# -*- coding: utf-8 -*-
#
# Copyright 2017 Mycroft AI Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#    http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
"""
    Parse functions for Italian (IT-IT)

    TODO: numbers greater than 999999
    TODO: it_number_parse
    TODO: it_pruning

"""

from datetime import datetime
from dateutil.relativedelta import relativedelta
from mycroft.util.lang.parse_common import is_numeric, look_for_fractions, \
    extract_numbers_generic
from mycroft.util.lang.format_it import pronounce_number_it

# Undefined articles ["un", "una", "un'"] can not be supressed,
# in Italian, "un cavallo" means "a horse" or "one horse".
it_articles = ["il", "lo", "la", "i", "gli", "le"]

it_numbers = {
    "zero": 0,
    "un": 1,
    "uno": 1,
    "una": 1,
    "un'": 1,
    "due": 2,
    "tre": 3,
    "quattro": 4,
    "cinque": 5,
    "sei": 6,
    "sette": 7,
    "otto": 8,
    "nove": 9,
    "dieci": 10,
    "undici": 11,
    "dodici": 12,
    "tredici": 13,
    "quattordici": 14,
    "quindici": 15,
    "sedici": 16,
    "diciassette": 17,
    "diciotto": 18,
    "diciannove": 19,
    "venti": 20,
    "vent": 20,
    "trenta": 30,
    "trent": 30,
    "quaranta": 40,
    "quarant": 40,
    "cinquanta": 50,
    "cinquant": 50,
    "sessanta": 60,
    "sessant": 60,
    "settanta": 70,
    "settant": 70,
    "ottanta": 80,
    "ottant": 80,
    "novanta": 90,
    "novant": 90,
    "cento": 100,
    "duecento": 200,
    "trecento": 300,
    "quattrocento": 400,
    "cinquecento": 500,
    "seicento": 600,
    "settecento": 700,
    "ottocento": 800,
    "novecento": 900,
    "primo": 1,
    "secondo": 2,
    "mille": 1000,
    "mila": 1000
}

def isFractional_it(input_str):
    """
    This function takes the given text and checks if it is a fraction.
    E' la versione portoghese riadattata in italiano

    Args:
        text (str): the string to check if fractional
    Returns:
        (bool) or (float): False if not a fraction, otherwise the fraction

    TODO:  verificare la corretta gestione dei plurali
    """

    aFrac = ["mezz", "terz", "quart", "quint", "sest", "settim", "ottav",
             "non", "decim", "undicesim", "dodicesim", "tredicesim",
             "quattrodicesim", "quindicesim", "sedicesim",
             "diciasettesim", "diciottesim", "diciasettesim",
             "diciannovesim"]

    if input_str[:-1].lower() in aFrac:
        return 1.0 / (aFrac.index(input_str[:-1]) + 2)
    if input_str[:-1] == "ventesim":
        return 1.0 / 20
    if input_str[:-1] == "centesim":
        return 1.0 / 100
    if input_str[:-1] == "millesim":
        return 1.0 / 1000

    return False

def extractnumber_long_it(word):
    """
    Questa funzione converte un numero testuale lungo es.
    ventisette -> 27
    quarantuno -> 41
    nell'equivalente valore intero
     args:
         text (str): la stringa da normalizzare
    Ritorna:
         (int) : il valore del numero estratto usando tutta la parola
         Falso : se la parola non è un numero es."qualcuno"
    """
    result = False
    value = False

    for number in it_numbers.keys():  # ciclo unità
        if word.endswith(number):
            result = True
            value = it_numbers[number]
            word = word[0: len(word) - len(number)]
            break

    if result:  # tolte le unità, dovrebbe rimanere una stringa nota
        if word in it_numbers:
            value += it_numbers[word]
        else:
            value = False  # non è un numero es. qualcuno

    return value

def extractnumber_it(text):
    """
    Questa funzione prepara il testo dato per l'analisi rendendo
    numeri testuali come interi o frazioni.
    In italiano non è un modo abituale ma può essere interessante
    per Mycroft
    E' la versione portoghese riadattata in italiano
     args:
         text (str): la stringa da normalizzare
    Ritorna:
         (int) o (float): il valore del numero estratto

    """
    aWords = text.split()
    count = 0
    result = None
    while count < len(aWords):
        val = 0
        word = aWords[count]
        next_next_word = None
        if count + 1 < len(aWords):
            next_word = aWords[count + 1]
            if count + 2 < len(aWords):
                next_next_word = aWords[count + 2]
        else:
            next_word = None

        # is current word a number?
        if word in it_numbers:
            if word == "mila":
                val = it_numbers[word]
                val = result * val
                result = 0
            else:
                val = it_numbers[word]

        elif word.isdigit():  # doesn't work with decimals
            val = int(word)
        elif is_numeric(word):
            val = float(word)

        elif isFractional_it(word):
            if not result:
                result = 1
            result = result * isFractional_it(word)
            # "un terzo" is 1/3 but "il terzo" is 3
            if aWords[count - 1] == "il":
                result = 1.0 // isFractional_it(word)

            count += 1
            continue

        if not val:
            # look for fractions like "2/3"
            aPieces = word.split('/')
            # if (len(aPieces) == 2 and is_numeric(aPieces[0])
            #   and is_numeric(aPieces[1])):
            if look_for_fractions(aPieces):
                val = float(aPieces[0]) / float(aPieces[1])

        if not val:
            # cerca numero composto come ventuno ventitre centoventi"
            val = extractnumber_long_it(word)

        if val:
            if result is None:
                result = 0
            # handle fractions
            # if next_word != "avos":
            result += val
            # else:
            #    result = float(result) / float(val)

        if next_word is None:
            break

        # number word and fraction
        ands = ["e"]
        if next_word in ands:
            zeros = 0
            if result is None:
                count += 1
                continue
            newWords = aWords[count + 2:]
            newText = ""
            for word in newWords:
                newText += word + " "

            afterAndVal = extractnumber_it(newText[:-1])
            if afterAndVal:
                if result < afterAndVal or result < 20:
                    while afterAndVal > 1:
                        afterAndVal = afterAndVal / 10.0
                    for word in newWords:
                        if word == "zero" or word == "0":
                            zeros += 1
                        else:
                            break
                for _ in range(0, zeros):
                    afterAndVal = afterAndVal / 10.0
                result += afterAndVal
                break
        elif next_next_word is not None:
            if next_next_word in ands:
                newWords = aWords[count + 3:]
                newText = ""
                for word in newWords:
                    newText += word + " "
                afterAndVal = extractnumber_it(newText[:-1])
                if afterAndVal:
                    if result is None:
                        result = 0
                    result += afterAndVal
                    break

        decimals = ["punto", "virgola", ".", ","]
        if next_word in decimals:
            zeros = 0
            newWords = aWords[count + 2:]
            newText = ""
            for word in newWords:
                newText += word + " "
            for word in newWords:
                if word == "zero" or word == "0":
                    zeros += 1
                else:
                    break
            afterDotVal = str(extractnumber_it(newText[:-1]))
            afterDotVal = zeros * "0" + afterDotVal
            result = float(str(result) + "." + afterDotVal)
            break
        count += 1

    if result is None:
        return False

    # Return the $str with the number related words removed
    # (now empty strings, so strlen == 0)
    # aWords = [word for word in aWords if len(word) > 0]
    # text = ' '.join(aWords)
    if "." in str(result):
        integer, dec = str(result).split(".")
        # cast float to int
        if dec == "0":
            result = int(integer)

    return result

def normalize_it(text, remove_articles):
    """ IT string normalization """

    words = text.split()  # this also removed extra spaces
    # Contractions are not common in IT
    # Convert numbers into digits, e.g. "quarantadue" -> "42"
    normalized = ""
    i = 0

    while i < len(words):
        word = words[i]
        # remove articles
        # Italian requires the article to define the gender
        if remove_articles and word in it_articles:
            i += 1
            continue

        if word in it_numbers:
            word = str(it_numbers[word])

        val = extractnumber_long_it(word)

        if val:
            word = str(val)

        normalized += " " + word
        i += 1
    # indefinite articles in it-it can not be removed

    return normalized[1:]

def extract_datetime_it(string, currentDate, default_time):
    def clean_string(s):
        """
            cleans the input string of unneeded punctuation and capitalization
            among other things.
            Normalize italian plurals
        """
        symbols = [".", ",", ";", "?", "!", u"º", u"ª", u"°"]

        for word in symbols:
            s = s.replace(word, "")

        s = s.lower().replace(
            u"á",
            "a").replace(
            u"à",
            "a").replace(
            u"è",
            "e'").replace(
            u"é",
            "e'").replace(
            u"ì",
            "i").replace(
            u"ù",
            "u").replace(
            u"ò",
            "o").replace(
            "-",
            " ").replace(
            "_",
            "")

        noise_words = ["tra", "la", "del", "al", "il", "di",
                       "le", "per", "alle", "alla", "dai", "delle",
                       "a", "e'", "era", "questa", "questo", "e"]

        for word in noise_words:
            s = s.replace(" " + word + " ", " ")

        # normalizza plurali per semplificare analisi
        s = s.replace(
            "secondi",
            "secondo").replace(
            "minuti",
            "minuto").replace(
            "ore",
            "ora").replace(
            "giorni",
            "giorno").replace(
            "settimane",
            "settimana").replace(
            "mesi",
            "mese").replace(
            "anni",
            "anno").replace(
            "mattino",
            "mattina").replace(
            "prossima",
            "prossimo").replace(
            "questa",
            "questo").replace(
            "quarti",
            "quarto")

        wordList = s.split()
        # print(wordList)  # debug only

        return wordList

    def date_found():
        return found or \
               (
                       datestr != "" or timeStr != "" or
                       yearOffset != 0 or monthOffset != 0 or
                       dayOffset is True or hrOffset != 0 or
                       hrAbs or minOffset != 0 or
                       minAbs or secOffset != 0
               )

    if string == "" or not currentDate:
        return None

    found = False
    daySpecified = False
    dayOffset = False
    monthOffset = 0
    yearOffset = 0
    dateNow = currentDate
    today = dateNow.strftime("%w")
    currentYear = dateNow.strftime("%Y")
    fromFlag = False
    datestr = ""
    hasYear = False
    timeQualifier = ""

    timeQualifiersList = ['mattina', 'pomeriggio', 'sera']
    markers = ['alle', 'in', 'questo', 'per', 'di']
    days = ['lunedi', 'martedi', 'mercoledi',
            'giovedi', 'venerdi', 'sabato', 'domenica']
    months = ['gennaio', 'febbraio', 'marzo', 'aprile', 'maggio', 'giugno',
              'luglio', 'agosto', 'settembre', 'ottobre', 'novembre',
              'dicembre']
    monthsShort = ['gen', 'feb', 'mar', 'apr', 'mag', 'giu', 'lug', 'ago',
                   'set', 'ott', 'nov', 'dic']

    words = clean_string(string)

    for idx, word in enumerate(words):
        if word == "":
            continue
        wordPrevPrev = words[idx - 2] if idx > 1 else ""
        wordPrev = words[idx - 1] if idx > 0 else ""
        wordNext = words[idx + 1] if idx + 1 < len(words) else ""
        wordNextNext = words[idx + 2] if idx + 2 < len(words) else ""
        # wordNextNextNext = words[idx + 3] if idx + 3 < len(words) else ""
        # possono esistere casi dove servano tre parole di profondità ?
        start = idx
        used = 0
        # save timequalifier for later
        if word in timeQualifiersList:
            timeQualifier = word
            # parse today, tomorrow, day after tomorrow
        elif word == "oggi" and not fromFlag:
            dayOffset = 0
            used += 1
        elif word == "domani" and not fromFlag:
            dayOffset = 1
            used += 1
        elif word == "ieri" and not fromFlag:
            dayOffset -= 1
            used += 1
        elif word == "dopodomani" and not fromFlag:  # after tomorrow
            dayOffset += 2
            used += 1
        elif word == "dopo" and wordNext == "domani" and \
                not fromFlag:
            dayOffset += 1
            used += 2
        elif word == "giorno":
            if wordPrev[0].isdigit():
                dayOffset += int(wordPrev)
                start -= 1
                used = 2
                if wordNext == "dopo" and wordNextNext == "domani":
                    dayOffset += 1
                    used += 2
        elif word == "settimana" and not fromFlag:
            if wordPrev[0].isdigit():
                dayOffset += int(wordPrev) * 7
                start -= 1
                used = 2
            elif wordPrev == "prossimo":
                dayOffset = 7
                start -= 1
                used = 2
            elif wordPrev == "passato":
                dayOffset = -7
                start -= 1
                used = 2
                # parse 10 months, next month, last month
        elif word == "mese" and not fromFlag:
            if wordPrev[0].isdigit():
                monthOffset = int(wordPrev)
                start -= 1
                used = 2
            elif wordPrev == "prossimo":
                monthOffset = 1
                start -= 1
                used = 2
            elif wordPrev == "passato":
                monthOffset = -1
                start -= 1
                used = 2
                # parse 5 years, next year, last year
        elif word == "anno" and not fromFlag:
            if wordPrev[0].isdigit():
                yearOffset = int(wordPrev)
                start -= 1
                used = 2
            elif wordPrev == "prossimo":
                yearOffset = 1
                start -= 1
                used = 2
            elif wordPrev == "passato":
                yearOffset = -1
                start -= 1
                used = 2
                # parse Monday, Tuesday, etc., and next Monday,
                # last Tuesday, etc.
        elif word in days and not fromFlag:
            d = days.index(word)
            dayOffset = (d + 1) - int(today)
            used = 1
            if dayOffset < 0:
                dayOffset += 7
            if wordPrev == "prossimo":
                dayOffset += 7
                used += 1
                start -= 1
            elif wordPrev == "passato":
                dayOffset -= 7
                used += 1
                start -= 1
            if wordNext == "prossimo":
                # dayOffset += 7
                used += 1
            elif wordNext == "passato":
                # dayOffset -= 7
                used += 1
                # parse 15 of July, June 20th, Feb 18, 19 of February
        elif word in months or word in monthsShort and not fromFlag:
            try:
                m = months.index(word)
            except ValueError:
                m = monthsShort.index(word)
            used += 1
            datestr = months[m]
            if wordPrev and (wordPrev[0].isdigit()):
                datestr += " " + wordPrev
                start -= 1
                used += 1
                if wordNext and wordNext[0].isdigit():
                    datestr += " " + wordNext
                    used += 1
                    hasYear = True
                else:
                    hasYear = False

            elif wordNext and wordNext[0].isdigit():
                datestr += " " + wordNext
                used += 1
                if wordNextNext and wordNextNext[0].isdigit():
                    datestr += " " + wordNextNext
                    used += 1
                    hasYear = True
                else:
                    hasYear = False
        # parse 5 days from tomorrow, 10 weeks from next thursday,
        # 2 months from July
        validFollowups = days + months + monthsShort
        validFollowups.append("oggi")
        validFollowups.append("domani")
        validFollowups.append("prossimo")
        validFollowups.append("passato")
        validFollowups.append("ora")
        if (word == "da" or word == "dopo") and wordNext in validFollowups:
            used = 2
            fromFlag = True
            if wordNext == "domani":
                dayOffset += 1
            elif wordNext in days:
                d = days.index(wordNext)
                tmpOffset = (d + 1) - int(today)
                used = 2
                if tmpOffset < 0:
                    tmpOffset += 7
                dayOffset += tmpOffset
            elif wordNextNext and wordNextNext in days:
                d = days.index(wordNextNext)
                tmpOffset = (d + 1) - int(today)
                used = 3
                if wordNext == "prossimo":
                    tmpOffset += 7
                    used += 2  # era 1
                    start -= 1
                elif wordNext == "passato":
                    tmpOffset -= 7
                    used += 1
                    start -= 1
                dayOffset += tmpOffset
        if used > 0:
            if start - 1 > 0 and words[start - 1] == "questo":
                start -= 1
                used += 1

            for i in range(0, used):
                words[i + start] = ""

            if start - 1 >= 0 and words[start - 1] in markers:
                words[start - 1] = ""
            found = True
            daySpecified = True

    # parse time
    timeStr = ""
    hrOffset = 0
    minOffset = 0
    secOffset = 0
    hrAbs = None
    minAbs = None

    for idx, word in enumerate(words):
        if word == "":
            continue

        wordPrevPrev = words[idx - 2] if idx > 1 else ""
        wordPrev = words[idx - 1] if idx > 0 else ""
        wordNext = words[idx + 1] if idx + 1 < len(words) else ""
        wordNextNext = words[idx + 2] if idx + 2 < len(words) else ""
        # wordNextNextNext = words[idx + 3] if idx + 3 < len(words) else ""
        # TODO verfica se esistono casi dove serva profindita 3 x analisi
        # parse noon, midnight, morning, afternoon, evening
        used = 0
        if word == "mezzogiorno":
            hrAbs = 12
            used += 1
        elif word == "mezzanotte":
            hrAbs = 24
            used += 1
        if word == "mezzo" and wordNext == "giorno":  # if stt splits the word
            hrAbs = 12
            used += 2
        elif word == "mezza" and wordNext == "notte":  # if stt splits the word
            hrAbs = 24
            used += 2
        elif word == "mattina":
            if not hrAbs:
                hrAbs = 8
            used += 1
            if wordNext and wordNext[0].isdigit():  # mattina alle 5
                hrAbs = int(wordNext)
                used += 1
        elif word == "pomeriggio":
            if not hrAbs:
                hrAbs = 15
            used += 1
            if wordNext and wordNext[0].isdigit():  # pomeriggio alle 5
                hrAbs = int(wordNext)
                used += 1
                if (hrAbs or 0) < 12:
                    hrAbs = (hrAbs or 0) + 12
        elif word == "sera":
            if not hrAbs:
                hrAbs = 19
            used += 1
            if wordNext and wordNext[0].isdigit():  # sera alle 8
                hrAbs = int(wordNext)
                used += 1
                if (hrAbs or 0) < 12:
                    hrAbs = (hrAbs or 0) + 12

        # parse 5:00 am, 12:00 p.m., etc
        elif word[0].isdigit():
            isTime = True
            strHH = ""
            strMM = ""
            remainder = ""
            if ':' in word:
                # parse colons
                # "3:00 in the morning"
                stage = 0
                length = len(word)
                for i in range(length):
                    if stage == 0:
                        if word[i].isdigit():
                            strHH += word[i]

                        elif word[i] == ":":
                            stage = 1
                        else:
                            stage = 2
                            i -= 1
                    elif stage == 1:
                        if word[i].isdigit():
                            strMM += word[i]
                        else:
                            stage = 2
                            i -= 1
                    elif stage == 2:
                        remainder = word[i:].replace(".", "")
                        break

                if remainder == "":
                    nextWord = wordNext.replace(".", "")
                    if nextWord == "am" or nextWord == "pm":
                        remainder = nextWord
                        used += 1
                    elif nextWord == "sera":
                        remainder = "pm"
                        used += 1
                    elif wordNext == "mattina":
                        remainder = "am"
                        used += 1
                    elif wordNext == "pomeriggio":
                        remainder = "pm"
                        used += 1
                    elif wordNext == "notte":
                        remainder = "pm"
                        used += 1
                    elif wordNext == "di" and wordNextNext == "notte":
                        if strHH > 5:
                            remainder = "pm"
                        else:
                            remainder = "am"
                        used += 2
                    else:
                        if timeQualifier != "":
                            if strHH <= 12 and \
                                    (timeQualifier == "sera" or
                                     timeQualifier == "pomeriggio"):
                                strHH += 12

            else:
                # try to parse # s without colons
                # 5 hours, 10 minutes etc.
                length = len(word)
                strNum = ""
                remainder = ""
                for i in range(length):
                    if word[i].isdigit():
                        strNum += word[i]
                    else:
                        remainder += word[i]

                if remainder == "":
                    remainder = wordNext.replace(".", "").lstrip().rstrip()

                if (
                        remainder == "pm" or
                        wordNext == "pm" or
                        remainder == "p.m." or
                        wordNext == "p.m."):
                    strHH = strNum
                    remainder = "pm"
                    used = 1
                elif (
                        remainder == "am" or
                        wordNext == "am" or
                        remainder == "a.m." or
                        wordNext == "a.m."):
                    strHH = strNum
                    remainder = "am"
                    used = 1
                else:
                    if wordNext == "pm" or wordNext == "p.m.":
                        strHH = strNum
                        remainder = "pm"
                        used = 1
                    elif wordNext == "am" or wordNext == "a.m.":
                        strHH = strNum
                        remainder = "am"
                        used = 1
                    elif (
                            int(word) > 100 and
                            (
                                    wordPrev == "o" or
                                    wordPrev == "oh"
                            )):
                        # 0800 hours (pronounced oh-eight-hundred)
                        strHH = int(word) / 100
                        strMM = int(word) - strHH * 100
                        if wordNext == "ora":
                            used += 1

                    elif (
                            wordNext == "ora" and
                            word[0] != '0' and
                            (
                                    int(word) < 100 and
                                    int(word) > 2400
                            )):
                        # ignores military time
                        # "in 3 hours"
                        hrOffset = int(word)
                        used = 2
                        isTime = False
                        hrAbs = -1
                        minAbs = -1
                    elif wordNext == "mattina":
                        # " 11 del mattina"  -> del viene rimosso
                        hh = int(word)
                        used = 2
                        isTime = False
                        hrAbs = hh
                        minAbs = 00
                    elif wordNext == "pomeriggio":
                        # " 2 del pomeriggio"  -> del viene rimosso
                        hh = int(word)
                        if hh < 12:
                            hh += 12
                        used = 2
                        isTime = False
                        hrAbs = hh
                        minAbs = 00
                    elif wordNext == "sera":
                        # "alle 8 di sera"  -> alle viene rimosso
                        hh = int(word)
                        if hh < 12:
                            hh += 12
                        used = 2
                        isTime = False
                        hrAbs = hh
                        minAbs = 00
                    # parse half an hour : undici e mezza
                    elif wordNext and wordNext == "mezza":
                        hrAbs = int(word)
                        minAbs = 30
                        used = 2
                        isTime = False
                    # parse 1 quarter hour 3 quarters : dieci e tre quarti
                    elif word and wordNext and \
                            wordNext == "quarto" and word[0].isdigit():
                        minAbs = 15 * int(word)
                        used = 2
                        if minAbs > 45:  # elimina eventuali errori
                            minAbs = 0
                            used -= 2
                        isTime = False
                    elif wordNext == "minuto":
                        # "in 10 minutes"
                        minOffset = int(word)
                        used = 2
                        isTime = False
                        hrAbs = -1
                        minAbs = -1
                    elif wordNext == "secondo":
                        # in 5 seconds
                        secOffset = int(word)
                        used = 2
                        isTime = False
                        hrAbs = -1
                        minAbs = -1
                    elif int(word) > 100:
                        strHH = int(word) / 100
                        strMM = int(word) - strHH * 100
                        if wordNext == "ora":
                            used += 1
                    elif wordNext and wordNext[0].isdigit():
                        strHH = word
                        strMM = wordNext
                        used += 1
                        if wordNextNext == "ora":
                            used += 1
                    elif wordNext == "in" and wordNextNext == "punto":
                        strHH = word
                        strMM = 00
                        used += 2

                    else:
                        isTime = False

            strHH = int(strHH) if strHH else 0
            strMM = int(strMM) if strMM else 0
            strHH = strHH + 12 if remainder == "pm" and strHH < 12 else strHH
            strHH = strHH - 12 if remainder == "am" and strHH >= 12 else strHH
            if strHH > 24 or strMM > 59:
                isTime = False
                used = 0
            if isTime:
                hrAbs = strHH * 1
                minAbs = strMM * 1
                used += 1

            if (hrAbs or 0) <= 12 and (timeQualifier == "sera" or
                                       timeQualifier == "pomeriggio"):
                hrAbs = (hrAbs or 0) + 12

        if used > 0:
            # removed parsed words from the sentence
            for i in range(used):
                words[idx + i] = ""

            if wordPrev == "o" or wordPrev == "oh":
                words[words.index(wordPrev)] = ""

            if wordPrev == "presto":
                hrOffset = -1
                words[idx - 1] = ""
                idx -= 1
            elif wordPrev == "tardi":
                hrOffset = 1
                words[idx - 1] = ""
                idx -= 1
            if idx > 0 and wordPrev in markers:
                words[idx - 1] = ""
            if idx > 1 and wordPrevPrev in markers:
                words[idx - 2] = ""

            idx += used - 1
            found = True

    # check that we found a date
    if not date_found:
        return None

    if dayOffset is False:
        dayOffset = 0

    # perform date manipulation

    extractedDate = dateNow
    extractedDate = extractedDate.replace(microsecond=0,
                                          second=0,
                                          minute=0,
                                          hour=0)

    if datestr != "":
        en_months = ['january', 'february', 'march', 'april', 'may', 'june',
                     'july', 'august', 'september', 'october', 'november',
                     'december']
        en_monthsShort = ['jan', 'feb', 'mar', 'apr', 'may', 'june', 'july',
                          'aug',
                          'sept', 'oct', 'nov', 'dec']
        for idx, en_month in enumerate(en_months):
            datestr = datestr.replace(months[idx], en_month)
        for idx, en_month in enumerate(en_monthsShort):
            datestr = datestr.replace(monthsShort[idx], en_month)

        temp = datetime.strptime(datestr, "%B %d")
        if not hasYear:
            temp = temp.replace(year=extractedDate.year)
            if extractedDate < temp:
                extractedDate = extractedDate.replace(year=int(currentYear),
                                                      month=int(
                                                          temp.strftime(
                                                              "%m")),
                                                      day=int(temp.strftime(
                                                          "%d")))
            else:
                extractedDate = extractedDate.replace(
                    year=int(currentYear) + 1,
                    month=int(temp.strftime("%m")),
                    day=int(temp.strftime("%d")))
        else:
            extractedDate = extractedDate.replace(
                year=int(temp.strftime("%Y")),
                month=int(temp.strftime("%m")),
                day=int(temp.strftime("%d")))

    if timeStr != "":
        temp = datetime(timeStr)
        extractedDate = extractedDate.replace(hour=temp.strftime("%H"),
                                              minute=temp.strftime("%M"),
                                              second=temp.strftime("%S"))

    if yearOffset != 0:
        extractedDate = extractedDate + relativedelta(years=yearOffset)
    if monthOffset != 0:
        extractedDate = extractedDate + relativedelta(months=monthOffset)
    if dayOffset != 0:
        extractedDate = extractedDate + relativedelta(days=dayOffset)
    if not hrAbs and not minAbs and default_time:
        hrAbs = default_time.hour
        minAbs = default_time.minute
    if hrAbs != -1 and minAbs != -1:
        extractedDate = extractedDate + relativedelta(hours=hrAbs or 0,
                                                      minutes=minAbs or 0)
        if (hrAbs or minAbs) and datestr == "":
            if not daySpecified and dateNow > extractedDate:
                extractedDate = extractedDate + relativedelta(days=1)
    if hrOffset != 0:
        extractedDate = extractedDate + relativedelta(hours=hrOffset)
    if minOffset != 0:
        extractedDate = extractedDate + relativedelta(minutes=minOffset)
    if secOffset != 0:
        extractedDate = extractedDate + relativedelta(seconds=secOffset)
    for idx, word in enumerate(words):
        if words[idx] == "e" and words[idx - 1] == "" and \
                words[idx + 1] == "":
            words[idx] = ""

    resultStr = " ".join(words)
    resultStr = ' '.join(resultStr.split())
    return [extractedDate, resultStr]

def get_gender_it(word, raw_string=""):
    """
    Questa potrebbe non essere utile.
    In italiano per definire il genere è necessario
    analizzare l'articolo che la precede e non la lettera
    con cui finisce la parola, ma sono presenti funzioni per
    la rimozione degli articoli dalla frase per semplificarne
    l'analisi

    TODO:  verificare se utile
    """

    gender = False
    words = raw_string.split(" ")
    for idx, w in enumerate(words):
        if w == word and idx != 0:
            previous = words[idx - 1]
            gender = get_gender_it(previous)
            break

    if not gender:
        if word[-1] == "a" or word[-1] == "e":
            gender = "f"
        if word[-1] == "o" or word[-1] == "n" \
                or word[-1] == "l" or word[-1] == "i":
            gender = "m"

    return gender

def extract_numbers_it(text, short_scale=True, ordinals=False):
    """
        Takes in a string and extracts a list of numbers.

    Args:
        text (str): the string to extract a number from
        short_scale (bool): Use "short scale" or "long scale" for large
            numbers -- over a million.  The default is short scale, which
            is now common in most English speaking countries.
            See https://en.wikipedia.org/wiki/Names_of_large_numbers
        ordinals (bool): consider ordinal numbers, e.g. third=3 instead of 1/3
    Returns:
        list: list of extracted numbers as floats
    """
    return extract_numbers_generic(text, pronounce_number_it, extractnumber_it,
                                   short_scale=short_scale, ordinals=ordinals)


# Shocking1 - first experiments with the DS3502 DigiPot

import sys
import random
import pdb
import readchar
import time
from adafruit_motorkit import MotorKit
import board
import adafruit_ds3502
i2c = board.I2C()
ds3502 = adafruit_ds3502.DS3502(i2c)

emulation=0
max_drink_counter=6 # one bad drink in each group of six
bad = 0
drink_counter = 0
# not sure what I am doing wrong

mh1 = MotorKit()

# recommended for auto-disabling motors on shutdown!
def turnOffMotors():
    mh1.motor1.throttle = None
    mh1.motor2.throttle = None
    mh1.motor3.throttle = None
    mh1.motor4.throttle = None
    #mh2.motor1.throttle = None
    #mh2.motor2.throttle = None
    #mh2.motor3.throttle = None
    #mh2.motor4.throttle = None

#atexit.register(turnOffMotors)

m = [None]
m.append(mh1.motor1)
m.append(mh1.motor2)
m.append(mh1.motor3)
m.append(mh1.motor4)
#m.append(mh2.motor1)
#m.append(mh2.motor2)
#m.append(mh2.motor3)
#m.append(mh2.motor4)

try:
    import RPi.GPIO as GPIO # Import Raspberry Pi GPIO library

    GPIO.setwarnings(False) # Ignore warning for now
    #GPIO.setmode(GPIO.BOARD)
    GPIO.setmode(GPIO.BCM)
    #GPIO.setup(13, GPIO.IN)
    #GPIO.setup(19, GPIO.IN)

    # Set pins 10 and 12 to be an input pin and set initial value to be pulled low (off)
    #GPIO.setup(13, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
    GPIO.setup(13, GPIO.IN, pull_up_down=GPIO.PUD_UP)
    GPIO.setup(19, GPIO.IN, pull_up_down=GPIO.PUD_UP)

except:
    print('Raspberry pi not responding, continuing in emulation mode')
    emulation=1

def next_drink():
    """ increment the counter and if need be select the next bad shot"""
    global drink_counter
    global bad
    if bad == 0:
        bad = random.randrange(6)+1
    drink_counter += 1
    if drink_counter > max_drink_counter:
        drink_counter=1
        bad = random.randrange(6)+1

    return

def dispense(player):
    """ dispense for a player
    player 1 is pumps 1 and 3
    player 2 is pumps 5 and 7

    player 1 - Motor 1 forward good stuff
    player 1 - Motor 2 forward bad stuff
    player 2 - Motor 3 forward good stuff
    player 2 - Motor 4 forward bad stuff
    """

    global drink_counter
    global bad
    print("\nIn dispense player=",player)
    for i in range(player):
        # get drink number and bad number
        next_drink()
        print('\tdispense a drink player=%i drink_counter=%i bad=%i ' % (i,drink_counter, bad), end='')
        if drink_counter==bad:
            print('\tYou are not going into space today.')
            time.sleep(1)
            # serve the icky drink
            # reset drink_counter and bad. Or should I? One bad out of six shots
            drink_counter=0
            bad=0
        else:
            # serve a fine shot
            time.sleep(1)
            print('\tYou get to go to space. Congratulations')

    print('service complete\n')

# We don't know the state of the drink counter or of anything.
# you push the button and 1 or 2 shots are poured.
# 1 out of 6 shots should be bad. But there are edge cases one should
# keep in mind.

print("Starting loop. Press a button, or if you are not on a pi  the keys '1', '2', or 'Q'")
flag1=False
wiper1 = 0
#while True:
#    for i in range (12):
#        print(i*10)
#        ds3502.wiper = i*10
#        time.sleep(1)

while True: # Run forever
    # event loops don't need to run at system speed
    time.sleep(.01)
    t=time.time()
    if emulation == 1:
        key = readchar.readkey()
        if key.upper()=='Q':
            sys.exit(2)

        key=int(key)
        if key in (1,2):
            dispense(key)

    else:
        if GPIO.input(13) == GPIO.LOW:
            #dispense(1)
            if flag1==False:
                wiper1 += 10
                print('Was False now true.')
                print('Was False now true. wiper1: ', wiper1)
                ds3502.wiper = wiper1
                if wiper1 > 128:
                    wiper1 = 0
            flag1=True
        else:
            #GPIO.input(13) == GPIO.HIGH
            if flag1==True:
                print('Was True now false.')
                #ds3502.wiper = wiper1
            flag1 = False

        if GPIO.input(19) == GPIO.LOW:
            print('button 2 pushed')
            #dispense(2)


"""
    Un bus viaja a 30km/h en promedio, 90km
    recoger pasajeros demora 2 minutos por pasajero
    bajar pasajero demora 1 minuto

    Cuantos minutos demora el bus, dada una cantidad de pasajeros que se subieron
    y otra cantidad de pasajeros que se bajaron
"""

numero_abordados = float(input("Numero de pasajeros que abordan: "))
numero_desc = float(input("Numero de pasajeros que descienden: "))

def calcular_tiempo(numero_abordados, numero_desc):
    duracion_estimada_viaje = (90/30)*60
    minutos_demora = duracion_estimada_viaje+((numero_abordados*2))+((numero_desc))
    return minutos_demora

print(calcular_tiempo(numero_abordados, numero_desc))


def spiral_matrix(matrix):
    res = []
    if len(matrix) == 0:
        return res
    row = len(matrix)
    col = len(matrix[0])

    top, bottom, left, right = 0, row - 1, 0, col - 1

    while(top <= bottom and left <= right):
        # Top
        for idx in range(left, right + 1):
            res.append(matrix[top][idx])

        top += 1

        # Right
        for idx in range(top, bottom + 1):
            res.append(matrix[idx][right])

        right -= 1

        # Bottom
        if top < bottom or row == 2:
            for idx in reversed(range(left, right + 1)):
                res.append(matrix[bottom][idx])

            bottom -= 1

        # Left
        if left < right or col == 2:
            for idx in reversed(range(top, bottom + 1)):
                res.append(matrix[idx][left])

            left += 1
    return res

if __name__ == "__main__":
    matrix = [
        [1, 2, 3, 4, 5, 6],
        [7, 8, 9, 10, 11, 12]
    ]
    print(spiral_matrix(matrix))


"""Interfaces for Bayesian filtering and smoothing."""

from abc import ABC, abstractmethod
from typing import Dict, Optional, Tuple, Union

import numpy as np

from probnum import randvars, statespace
from probnum.filtsmooth.timeseriesposterior import TimeSeriesPosterior
from probnum.type import FloatArgType

class BayesFiltSmooth(ABC):
    """Bayesian filtering and smoothing."""

    def __init__(
        self,
        dynamics_model: statespace.Transition,
        measurement_model: statespace.Transition,
        initrv: randvars.RandomVariable,
    ):
        self.dynamics_model = dynamics_model
        self.measurement_model = measurement_model
        self.initrv = initrv

    @abstractmethod
    def filter_step(
        self,
        start: FloatArgType,
        stop: FloatArgType,
        current_rv: randvars.RandomVariable,
        data: np.ndarray,
        _linearise_predict_at: Optional[randvars.RandomVariable] = None,
        _linearise_update_at: Optional[randvars.RandomVariable] = None,
        _diffusion: Union[FloatArgType, np.ndarray] = 1.0,
    ) -> Tuple[randvars.RandomVariable, Dict]:
        """Filter step.

        For Gaussian filters, this means a prediction step followed by
        an update step.
        """
        errormsg = (
            "filter_step(...) is not implemented for "
            + "the Bayesian filter {}.".format(type(self).__name__)
        )
        raise NotImplementedError(errormsg)

    def smooth(
        self,
        filter_posterior: TimeSeriesPosterior,
        _previous_posterior: Optional[TimeSeriesPosterior] = None,
    ) -> TimeSeriesPosterior:
        """Smoothing."""
        errormsg = (
            "smoother_step(...) is not implemented for "
            + "the Bayesian smoother {}.".format(type(self).__name__)
        )
        raise NotImplementedError(errormsg)


# -- coding: utf-8 --
# @Time : 01/04/2020 07:43
# @Author : LZL
# @Email: z.luan@qmul.ac.uk
# @File : utils.py

import os
import torch
from torch import nn
import transforms3d.quaternions as txq
import numpy as np
import sys

from torchvision.datasets.folder import default_loader
from _collections import OrderedDict

def madirs(paths):
    '''根据paths的类型来创建文件夹'''
    if isinstance(paths, list) and not isinstance(paths, str):
        for path in paths:
            mkdir(path)
        else:
            mkdir(path)

def mkdir(path):
    '''检查文件夹是否存在，否则新建'''
    if not os.path.exists(path):
        os.makedirs(path)

def qlog(q):
    if all(q[1:] == 0):
        q = np.zeros(3)
    else:
        q = np.arccos(q[0]) * q[1:] / np.linalg.norm(q[1:])
    return q

def calc_vos_simple(poses):
    """
    calculate the VOs, from a list of consecutive poses
    :param poses: N x T x 7
    :return: N x (T-1) x 7
    """
    vos = []
    for p in poses:
        # unsqueeze(0)表示在第0维上增加1个维度，对数据维度进行扩充
        pvos = [p[i + 1].unsqueeze(0) - p[i].unsqueeze(0) for i in range(len(p) - 1)]
        vos.append(torch.cat(pvos, dim=0))  # 沿着dim连接pvos中的tensor, 所有的tensor必须有相同的size或为empty
    vos = torch.stack(vos, dim=0)  # stack增加新的维度进行堆叠

def prosess_poses(poses_in, mean_t, std_t, align_R, align_t, align_s):
    """
     processes the 1x12 raw pose from dataset by aligning and then normalizing
     :param poses_in: N x 12
     :param mean_t: 3
     :param std_t: 3
     :param align_R: 3 x 3
     :param align_t: 3
     :param align_s: 1
     :return: processed poses (translation + quaternion) N x 7
     """
    poses_out = np.zeros((len(poses_in), 6))
    poses_out[:, 0:3] = poses_in[:, [3, 7, 11]]

    # align
    for i in range(len(poses_out)):
        R = poses_in[i].reshape((3, 4))[:3, :3]
        q = txq.mat2quat(np.dot(align_R, R))
        q *= np.sign(q[0])  # 限制在半球上
        q = qlog(q)
        poses_out[i, 3:] = q
        t = poses_out[i, :3] - align_t
        poses_out[i, :3] = align_s * np.dot(align_R,
                                            t[:, np.newaxis]).squeeze()  # squeeze()从数组的形状中删除单维度条目，即把shape中为1的维度去掉

    # normalize translation
    poses_out[:, :3] -= mean_t
    poses_out[:, :3] /= std_t
    return poses_out

# 给定filename，通过default_loader()函数载入数据
def load_images(filename, loader=default_loader):
    try:
        img = loader(filename)  # 获取数据集
    except IOError as e:
        print('Could not loas image {:s}, IOError: {:s}'.format(filename, e))
        return None
    except:
        print('Could not load image {:s}, unexpected error'.format(filename))
        return None
    return img

def quaternion_angular_error(q1, q2):
    """
    angular error between two quaternions
    :param q1: (4, )
    :param q2: (4, )
    :return:
    """
    d = abs(np.dot(q1, q2))
    d = min(1.0, max(-1.0, d))
    theta = 2 * np.arccos(d) * 180 / np.pi
    return theta

def qexp(q):
    """
    Applies the exponential map to q
    :param q: (3,)
    :return: (4,)
    """
    n = np.linalg.norm(q)  # 数据初始化
    q = np.hstack((np.cos(n), np.sinc(n / np.pi) * q))  # The sinc function is sin(pi*x) / (pi*x).
    return q

def load_state_dict(model, state_dict):  # state_dict 是一个简单的python的字典对象,将每一层与它的对应参数建立映射关系.(如model的每一层的weights及偏置等等)
    """
     Loads a state dict when the model has some prefix before the parameter names
     :param model:
     :param state_dict:
     :return: loaded model
     """
    model_names = [n for n, _ in model.named_parameters()]
    state_names = [n for n in state_dict.keys()]

    # find prefix for the model and state dicts from the first param name
    if model_names[0].find(state_names[0]) >= 0:
        model_prefix = model_names[0].replace(state_names[0], '')  # 将state_names[0]替换为''
        state_prefix = None
    elif state_names[0].find(model_names[0]) >= 0:
        state_prefix = state_names[0].replace(model_names[0], '')
        model_prefix = None
    else:
        model_prefix = model_names[0].split('.')[0]
        state_prefix = state_names[0].split('.')[0]

    new_state_dict = OrderedDict()  # 对字典对象中元素进行排序
    for k, v in state_dict.items():
        if state_prefix is None:
            k = model_prefix + k
        else:
            k = k.replace(state_prefix, model_prefix)
        new_state_dict[k] = v

    model.load_state_dict(new_state_dict)  # 返回的是一个OrderDict，存储了网络结构的名字和对应的参数，下面看看源代码如何实现的

# 控制程序运行输出
class Logger(object):
    def __init__(self, filename="Default.log"):
        self.termimal = sys.stdout
        self.log = open(filename, "w")

    def delink(self):
        self.log.close()

    def writeTerminalOnly(self, message):
        self.termimal.write(message)

    def write(self, message):
        self.termimal.write(message)
        self.log.write(message)

    def flush(self):
        pass

# 模型损失函数模块
class AtLocCriterion(nn.Module):
    # 初始化
    def __init__(self, t_loss_fn=nn.L1Loss(), q_loss_fn=nn.L1Loss(), sax=0.0, saq=0.0, learn_beta=False):
        super(AtLocCriterion, self).__init__()  # nn.Module的子类函数必须在构造函数中执行父类的构造函数,等价与nn.Module.__init__()
        self.t_loss_fn = t_loss_fn
        self.q_loss_fn = q_loss_fn

        # 首先可以把Parameter函数理解为类型转换函数，将一个不可训练的类型Tensor转换成可以训练的类型parameter并将这个parameter
        # 绑定到这个module里面(net.parameter()中就有这个绑定的parameter，所以在参数优化的时候可以进行优化的)所以经过类型转换这个
        # self.sax变成了模型的一部分，成为了模型中根据训练可以改动的参数了
        # 使用这个函数的目的也是想让某些变量在学习的过程中不断的修改其值以达到最优化。
        self.sax = nn.Parameter(torch.Tensor([sax]), requires_grad=learn_beta)
        self.saq = nn.Parameter(torch.Tensor([saq]), requires_grad=learn_beta)

    def forward(self, pred, targ):
        loss = torch.exp(-self.sax) * self.t_loss_fn(pred[:, :3], targ[:, :3]) + self.sax + \
               torch.exp(-self.saq) * self.q_loss_fn(pred[:, 3:], targ[:, 3:]) + self.saq

        return loss

class AverageMeter(object):
    """Computes and stores the average and current value"""

    def __init__(self):
        self.reset()

    def reset(self):
        self.val = 0
        self.avg = 0
        self.sum = 0
        self.count = 0

    def updata(self, val, n=1):
        self.val = val
        self.sum += val * n
        self.count += n
        self.avg = self.sum / self.count


import numpy as np
import matplotlib.pyplot as plt
from keras.datasets import cifar10
from keras.models import Sequential
from keras.models import load_model

# 指定亂數種子
seed = 10
np.random.seed(seed)
# 載入資料集
(X_train, Y_train), (X_test, Y_test) = cifar10.load_data()
# 選一個測試的圖片
# i = np.random.randint(0, len(X_test))
i = 8
img = X_test[i]
# 將圖片轉換成 4D 張量
X_test_img = img.reshape(1, 32, 32, 3).astype("float32")
# 因為是固定範圍, 所以執行正規化, 從 0-255 至 0-1
X_test_img = X_test_img / 255
# 建立Keras的Sequential模型
model = Sequential()
model = load_model("cifar10.h5")
# 編譯模型
model.compile(loss="categorical_crossentropy", optimizer="adam",
              metrics=["accuracy"])
# 繪出圖表的預測結果
plt.figure()
plt.subplot(1,2,1)
plt.title("Example of Image:" + str(Y_test[i]))
plt.imshow(img, cmap="binary")
plt.axis("off")
# 預測結果的機率
print("Predicting ...")
probs = model.predict_proba(X_test_img, batch_size=1)
plt.subplot(1,2,2)
plt.title("Probabilities for Each Image Class")
plt.bar(np.arange(10), probs.reshape(10), align="center")
plt.xticks(np.arange(10),np.arange(10).astype(str))
plt.show()


from rest_framework import permissions

class UpdateOwnProfile(permissions.BasePermission):
    """Allows user to update own profile"""

    def has_object_permission(self, request, view, obj):
        """Method to overide for permission """
        if request.method in permissions.SAFE_METHOD:
            return True

        return obj.id == request.user.id


#!/usr/bin/env python

import os.path
import os
from configobj import ConfigObj
import numpy as np
from gfail.godt import godt2008
from mapio.geodict import GeoDict
from gfail.conf import correct_config_filepaths

homedir = os.path.dirname(os.path.abspath(__file__))  # where is this script?
datadir = os.path.abspath(os.path.join(homedir, 'data'))

shakefile = os.path.join(datadir, 'test_shakegrid.xml')
shakefileBounds = os.path.join(datadir, 'test_shakegrid_bounds.xml')
uncertfile = os.path.join(datadir, 'test_uncert.xml')
cofile = os.path.join(datadir, 'test_friction.bil')
slopefile = os.path.join(datadir, 'test_slope.bil')
vs30file = os.path.join(datadir, 'test_vs30.bil')
ctifile = os.path.join(datadir, 'test_cti.bil')
precipfolder = os.path.join(datadir, 'test_precip')

fakegeodict = GeoDict({'xmin': 0.5, 'xmax': 1.5,
                       'ymin': 0.5, 'ymax': 1.5,
                       'dx': 1., 'dy': 1.,
                       'ny': 2, 'nx': 2})

def test_godt2008():
    configfile = os.path.join(datadir, 'testconfig_godt.ini')
    config = ConfigObj(configfile)
    # Use divfactor of 1.
    config['godt_2008']['divfactor'] = 1
    bounds = {'xmin': -1.5, 'xmax': 3, 'ymin': -1.5, 'ymax': 3}
    # Test path correction (from conf.py)
    config = correct_config_filepaths(datadir, config)
    maplayers1 = godt2008(shakefile, config, displmodel='J_PGA',
                          uncertfile=uncertfile, bounds=bounds)
    maplayers2 = godt2008(shakefile, config, displmodel='J_PGA_M',
                          saveinputs=True)
    maplayers3 = godt2008(shakefile, config, displmodel='RS_PGA_M')
    maplayers4 = godt2008(shakefile, config, displmodel='RS_PGA_PGV',
                          uncertfile=uncertfile, saveinputs=True)
    maplayers5 = godt2008(shakefile, config)

    # Testing J_PGA with Uncertainty - Model Type 1
    np.testing.assert_allclose(maplayers1['model']['grid'].getData(),
                               np.array([[0., 0.1], [0.9, 0.]]), atol=0.01)
    np.testing.assert_allclose(maplayers1['modelmin']['grid'].getData(),
                               np.array([[0., 0.01], [0.9, 0.]]))
    np.testing.assert_allclose(maplayers1['modelmax']['grid'].getData(),
                               np.array([[0., 0.7], [0.99, 0.]]))

    # Testing J_PGA_M with Uncertainty - Model Type 2
    np.testing.assert_allclose(maplayers2['model']['grid'].getData(),
                               np.array([[0., 0.01], [0.9, 0.]]), atol=0.01)

    # Testing RS_PGA_M with Uncertainty - Model Type 3
    np.testing.assert_allclose(maplayers3['model']['grid'].getData(),
                               np.array([[0., 0.5], [0.99, 0.]]), atol=0.01)

    # Testing RS_PGA_PGV with Uncertainty - Model Type 4
    np.testing.assert_allclose(maplayers4['model']['grid'].getData(),
                               np.array([[0., 0.7], [0.99, 0.]]), atol=0.01)
    np.testing.assert_allclose(maplayers4['modelmin']['grid'].getData(),
                               np.array([[0., 0.1], [0.9, 0.]]))
    np.testing.assert_allclose(maplayers4['modelmax']['grid'].getData(),
                               np.array([[0., 0.99], [0.99, 0.]]))
    np.testing.assert_allclose(maplayers4['pgvmin']['grid'].getData(),
                               np.array([[32.53, 44.72], [23.24, 71.58]]),
                               atol=0.01)

    # Testing default model and no uncertainty
    np.testing.assert_allclose(maplayers5['model']['grid'].getData(),
                               np.array([[0., 0.01], [0.9, 0.]]), atol=0.01)

    # delete reference
    del config['godt_2008']['shortref']
    # reshape bounds
    bounds = {'xmin': 0.5, 'xmax': 1.5, 'ymin': 0.5, 'ymax': 1.5}
    # bad uncertfile
    uncertfile2 = os.path.join(datadir, 'test_uncert_error.xml')

    maplayers6 = godt2008(shakefile, config, bounds=bounds,
                          uncertfile=uncertfile2)

    # Testing with changed config
    np.testing.assert_allclose(maplayers6['model']['grid'].getData(),
                               np.array([[0., 0.01], [0.9, 0.]]), atol=0.01)

if __name__ == "__main__":
    test_godt2008()
    print('godt2008 tests passed')


# P-2.35 Write a set of Python classes that can simulate an Internet application in
# which one party, Alice, is periodically creating a set of packets that she
# wants to send to Bob. An Internet process is continually checking if Alice
# has any packets to send, and if so, it delivers them to Bob’s computer, and
# Bob is periodically checking if his computer has a packet from Alice, and,
# if so, he reads and deletes it.
from time import sleep
import socket
import sys
from random import randint
from unittest import TestCase

class Node:

    def __init__(self):
        self._socket = socket.socket(
            socket.AF_INET, socket.SOCK_STREAM
        )
        self.data = []

class Server(Node):

    def __init__(self):
        super(Server, self).__init__()
        self._port = randint(10000, 10100)
        self._socket.bind(('localhost', self._port))
        print('listen on {}'.format(self._port))
        self._socket.listen(1)

    def accept_connections(self):

        while True:
            connection, client_address = self._socket.accept()
            print('{}'.format(client_address))
            try:
                while True:
                    data = connection.recv(1024)
                    print('{}'.format(data))
            finally:
                connection.close()

class Client(Node):

    def generate_data(self):
        pass

    def send_data(self, msg, port):
        self._socket.connect(('localhost', port))

        try:

            self._socket.sendall(msg)
        finally:
            self._socket.close()

class TestNode(TestCase):

    def test_basic(self):
        alice = Client()
        alice.send_data(b'Teest', 10037)
        # a.send_packets('test')


# Merge Agricultural Land Class with the land dataset
# Pre-process ALC by dissolving on ALC grade and then unioning with itself with no gaps and 1m tolerance
# to remove sliver gaps
# ---------------------------------------------------
import time, arcpy
import os
import  MyFunctions

print(''.join(["## Started on : ", time.ctime()]))

arcpy.CheckOutExtension("Spatial")
arcpy.env.overwriteOutput = True  # Overwrites files

region = "Arc"
# region = "Oxon"
# Choice of method that has been used to generate the input files - this determines location and names of input files
method = "CROME_PHI"
# method = "HLU"

if region == "Oxon" and method == "HLU":
    folder = r"D:\cenv0389\Oxon_GIS\Oxon_county\Data"
    gdbs = [os.path.join(folder,"Merge_OSMM_HLU_CR_ALC.gdb")]
    base_map_name = "OSMM_HLU_CR"
    out_name = "OSMM_HLU_CR_ALC"
    ALC_data = r"D:\cenv0389\Oxon_GIS\Oxon_county\Data\Merge_OSMM_HLU_CR_ALC.gdb\ALC_Union"
elif method == "CROME_PHI":
    folder = r"D:\cenv0389\OxCamArc\NatCap_Arc_PaidData"
    arcpy.env.workspace = folder
    # base_map_name = "OSMM_CROME_PHI"
    base_map_name = "LERC"
    # out_name = "OSMM_CR_PHI_ALC"
    out_name = "LERC_ALC"
    if region == "Arc":
        gdbs = []
        gdbs = arcpy.ListWorkspaces("*", "FileGDB")
        # Or comment out previous line and use this format (one row per gdb) if repeating certain gdbs only
        #gdbs.append(os.path.join(folder, "AylesburyVale.gdb"))
        #gdbs.append(os.path.join(folder, "Chiltern.gdb"))
        ALC_data = r"D:\cenv0389\Oxon_GIS\OxCamArc\Data\Data.gdb\ALC_diss_union"
    elif region == "Oxon":
        gdbs = []
        LADs = ["Cherwell.gdb", "Oxford.gdb", "SouthOxfordshire.gdb", "ValeofWhiteHorse.gdb", "WestOxfordshire.gdb"]
        for LAD in LADs:
            gdbs.append(os.path.join(folder, LAD))
        ALC_data = os.path.join(folder, "ALC_Union.shp")

for gdb in gdbs:
    arcpy.env.workspace = gdb
    # Need to define base map here otherwise it keeps repeating the first gdb base map
    base_map = os.path.join(folder, gdb, base_map_name)

    numrows = arcpy.GetCount_management(base_map)
    print ("Processing " + gdb + ". " + base_map_name + " has " + str(numrows) + " rows.")

    print("    Selecting intensive agriculture polygons from land cover layer")
    arcpy.CopyFeatures_management(base_map_name, "noFarmland")
    arcpy.MakeFeatureLayer_management("noFarmland", "farmland_layer")
    expression = "(Interpreted_habitat LIKE 'Arable%' OR Interpreted_habitat = 'Agricultural land' "
    expression = expression + "OR Interpreted_habitat LIKE 'Improved%' OR Interpreted_habitat LIKE '%rchard%')"
    arcpy.SelectLayerByAttribute_management("farmland_layer", where_clause=expression)

    print("    Running Identity")
    out_file = os.path.join(folder, gdb, out_name)
    arcpy.Identity_analysis ("farmland_layer", ALC_data, out_file, "NO_FID")

    print("    Creating no_farmland layer")
    arcpy.DeleteFeatures_management("farmland_layer")

    print("    Appending")
    arcpy.Append_management("noFarmland", out_file, "NO_TEST")

    MyFunctions.check_and_repair((out_file))

exit()


from django.urls import path

from Murr_card.views import murrs_list, murr_detail, search, murr_update, murr_delete, murr_create

urlpatterns = [
    path('', murrs_list, name='murrs_list'),
    path('create/', murr_create, name='murr_create'),
    path('murr_detail/<int:pk>', murr_detail, name='murr_detail'),
    path('murr_detail/<int:pk>/update/', murr_update, name='murr_update'),
    path('murr_detail/<int:pk>/delete/', murr_delete, name='murr_delete'),
    path('search/', search, name='search'),

]


# Copyright 2014 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

from infra.libs.git2.util import CalledProcessError
from infra.libs.git2.util import INVALID

class Ref(object):
  """Represents a single ref in a git Repo.

  Allowed to hold anything which can resolve to a single commit e.g.:

  >>> r = Repo()
  >>> r['refs/heads/master'].commit
  # Commit which is the current value of master
  >>> r['refs/heads/master~1'].commit
  # Commit which is the current first parent of master
  >>> r[raw_git_hash].to(r[other_git_hash])
  # generator of all Commits from raw_git_hash to other_git_hash

  May also hold INVALID or point to a ref which does not exist yet.

  >>> r = Repo()
  >>> r[some.expression.which.returns.INVALID].to(other_ref)
  # generator of all commits reachable from other_ref
  >>> r[INVALID].update_to(Commit())
  # => AssertionError
  >>> r['/ref/which/does_not/exist_yet'].to(other_ref)
  # generator of all commits reachable from other_ref
  >>> r['/ref/which/does_not/exist_yet'].update_to(Commit())
  # works
  """
  def __init__(self, repo, ref_str):
    """
    @type repo: Repo
    @type ref_str: str
    """
    self._repo = repo
    self._ref = ref_str

  # Comparison & Representation
  def __eq__(self, other):
    return (self is other) or (
        isinstance(other, Ref) and (
            self.ref == other.ref and
            self.repo is other.repo
        )
    )

  def __ne__(self, other):
    return not (self == other)

  def __hash__(self):
    return hash((self._repo, self._ref))

  def __repr__(self):
    return 'Ref({_repo!r}, {_ref!r})'.format(**self.__dict__)

  # Accessors
  # pylint: disable=W0212
  repo = property(lambda self: self._repo)
  ref = property(lambda self: self._ref)

  # Properties
  @property
  def commit(self):
    """Get the Commit at the tip of this Ref."""
    if self._ref is INVALID:
      return INVALID
    try:
      return self._repo.get_commit(
        self._repo.run('rev-parse', self._ref).strip())
    except CalledProcessError:
      return INVALID

  # Methods
  def to(self, other, path=None, first_parent=False):
    """Generate Commit()'s which occur from `self..other`.

    If the current ref is INVAILD, list all of the commits reachable from
    other.

    Args:
      first_parent - only return commits following the first parent of
         merge commits.
      path - A string indicating a repo-root-relative path to filter commits on.
             Only Commits which change this path will be yielded. See help for
             `git rev-list self..other -- <path>`.
    """
    args = ['rev-list', '--reverse']
    if first_parent:
      args.append('--first-parent')
    if self.commit is INVALID:
      args.append(other.ref)
    else:
      args.append('%s..%s' % (self.ref, other.ref))
    if path:
      args.extend(['--', path])
    for hsh in self.repo.run(*args).splitlines():
      yield self.repo.get_commit(hsh)

  def update_to(self, commit):
    """Update the local copy of the ref to ``commit``."""
    assert self._ref is not INVALID, 'May not update Ref(INVALID)'
    self.repo.run('update-ref', self.ref, commit.hsh)

  def fast_forward(self, commit):
    """Fast forward the local copy of the ref to ``commit``.

    Allows fast forward from undefined to a value as well.
    """
    if self.commit is not INVALID:
      self.repo.run('merge-base', '--is-ancestor', self.commit.hsh, commit.hsh)
    self.update_to(commit)


#!/usr/bin/env python
import warnings

import unittest
import numpy as np
import pytraj as pt
from pytraj.base import *
from pytraj.utils import has_
from pytraj.testing import aa_eq
from pytraj import Trajectory, TrajectoryIterator
from pytraj.datasets import CpptrajDatasetList

class TestSimpleRMSD(unittest.TestCase):

    def setUp(self):
        self.traj = pt.iterload("./data/Tc5b.x", "./data/Tc5b.top")

    def test_fit_and_then_nofit(self):
        traj = pt.iterload("data/Tc5b.x", "data/Tc5b.top")
        t0 = traj[:]
        pt.superpose(t0, ref=traj[3], mask='@CA')
        rmsd_0 = pt.rmsd_nofit(traj, ref=traj[3], mask='@CB')
        rmsd_1 = pt.rmsd(traj, ref=traj[3], mask='@CB', nofit=True)
        aa_eq(rmsd_1, rmsd_0)

    def test_rmsd_with_mask(self):
        TRAJ = pt.iterload(filename="./data/Tc5b.x",
                           top="./data/Tc5b.top")
        cpptraj_rmsd = np.loadtxt(
            "./data/rmsd_to_firstFrame_CA_allres.Tc5b.dat",
            skiprows=1).transpose()[1]
        f0 = TRAJ[0]
        arr0 = np.zeros(TRAJ.n_frames)
        arr1 = np.zeros(TRAJ.n_frames)
        mask = "@CA"
        atm = AtomMask(mask)
        TRAJ.top.set_integer_mask(atm)

        for i, frame in enumerate(TRAJ):
            arr0[i] = frame.rmsd(f0, mask=mask, top=TRAJ.top)
            arr1[i] = frame.rmsd(f0, atommask=atm)

        arr2 = pt.rmsd(TRAJ, mask=mask, ref=f0)
        arr3 = pt.rmsd(TRAJ, mask=mask, ref=0)
        aa_eq(arr0, cpptraj_rmsd, decimal=3)
        aa_eq(arr1, cpptraj_rmsd, decimal=3)
        aa_eq(arr2, cpptraj_rmsd, decimal=3)
        aa_eq(arr3, cpptraj_rmsd, decimal=3)

    def testsuperpose_alias(self):
        '''testsuperpose_alias'''
        t0 = self.traj[:]
        t1 = self.traj[:]
        pt.transform(t0, ['superpose'])
        pt.transform(t1, ['rms'])
        aa_eq(t0.xyz, t1.xyz)

    def test_reference_with_different_topology_basic(self):
        traj1 = pt.iterload(filename="./data/Tc5b.x",
                           top="./data/Tc5b.top")
        traj2 = pt.iterload('data/tz2.nc', 'data/tz2.parm7')

        # re-establish ActionList
        dslist = CpptrajDatasetList()
        dslist.add('reference', name='myref')

        dslist[0].top = traj2.top
        dslist[0].add_frame(traj2[0])

        actlist = pt.ActionList(['rmsd @1-11 @CB ref myref'], top=traj1.top,
                                dslist=dslist)
        for frame in traj1:
            actlist.compute(frame)

        # raise if ref_mask is given but not mask
        self.assertRaises(ValueError, lambda:
                pt.rmsd(traj1, ref=3, ref_mask='@CB'))
        self.assertRaises(ValueError, lambda:
                pt.rmsd(traj1, ref=traj2[:1], ref_mask='@CB'))

        # assert to cpptraj
        tc5b_traj = traj1[:]
        tz2_traj = traj2[:1]

        cm = '''
        parm data/Tc5b.top [tc5b]
        trajin data/Tc5b.x [tc5b]
        parm data/tz2.parm7 [tz2]
        reference data/tz2.nc parm [tz2] 1 [myref]
        rms myrmsd ref [myref] @1-10 @11-20
        '''
        state = pt.load_cpptraj_state(cm)
        state.run()

        expected_rmsd = state.data[-1].values
        rmsd_data = pt.rmsd(tc5b_traj, mask='@1-10',
                            ref=tz2_traj,
                            ref_mask='@11-20')
        aa_eq(expected_rmsd, rmsd_data)

    @unittest.skipIf(not has_('mdtraj'), 'does not have mdtraj')
    def test_ComparetoMDtraj(self):
        import mdtraj as md
        traj = pt.load(filename="./data/Tc5b.x",
                       top="./data/Tc5b.top")
        m_top = md.load_prmtop("./data/Tc5b.top")
        m_traj = md.load_mdcrd("./data/Tc5b.x", m_top)
        m_traj.xyz = m_traj.xyz * 10  # convert `nm` to `Angstrom` unit

        arr0 = pt.rmsd(traj, ref=0)
        arr1 = pt.rmsd(traj, ref=0)
        arr2 = pt.rmsd(traj, )
        a_md0 = md.rmsd(m_traj, m_traj, 0)
        aa_eq(arr0, arr1)
        aa_eq(arr0, arr2)
        aa_eq(arr0, a_md0)

        arr0 = pt.rmsd(traj, ref=-1)
        arr1 = pt.rmsd(traj, ref=-1)
        a_md = md.rmsd(m_traj, m_traj, -1)
        aa_eq(arr0, arr1)
        aa_eq(arr0, a_md)

        mask = ":3-18@CA,C"
        atm = traj.top(mask)
        arr0 = pt.rmsd(traj, ref=-1, mask=mask)
        arr1 = pt.rmsd(traj, mask=atm.indices, ref=-1)
        arr2 = pt.rmsd(traj, mask=list(atm.indices), ref=-1)
        arr3 = pt.rmsd(traj, mask=tuple(atm.indices), ref=-1)
        a_md = md.rmsd(m_traj, m_traj, -1, atm.indices)
        aa_eq(arr0, a_md)
        aa_eq(arr1, a_md)
        aa_eq(arr2, a_md)
        aa_eq(arr3, a_md)

        fa = Trajectory(traj)
        arr0 = pt.rmsd(fa, ref=-1, mask=mask)
        arr1 = pt.rmsd(fa, mask=atm.indices, ref=-1)
        arr2 = pt.rmsd(fa, mask=list(atm.indices), ref=-1)
        arr3 = pt.rmsd(fa, mask=tuple(atm.indices), ref=-1)
        a_md = md.rmsd(m_traj, m_traj, -1, atm.indices)
        aa_eq(arr0, a_md)
        aa_eq(arr1, a_md)
        aa_eq(arr2, a_md)
        aa_eq(arr3, a_md)

        fa = Trajectory(traj)
        mask = "!@H="
        atm = fa.top(mask)
        arr0 = pt.rmsd(fa, ref=4, mask=mask)
        a_md = md.rmsd(m_traj, m_traj, 4, atm.indices)

        # exclude 0-th frame for ref
        aa_eq(arr0, a_md)

    def test_list_of_masks(self):
        traj = self.traj.copy()
        mask = ['@CA', '@CB', ':3-18@CA,C']
        arr = pt.rmsd(traj, mask=mask)
        for idx, m in enumerate(mask):
            aa_eq(arr[idx], pt.rmsd(traj, mask=m))
            aa_eq(arr[idx], pt.rmsd(traj, mask=traj.top.select(m)))

        mask = ['@CA', '@CB', ':3-18@CA,C', [0, 3, 5]]
        self.assertRaises(ValueError, lambda: pt.rmsd(traj, mask=mask))

        mask_2 = [[0, 3, 6], range(50)]
        aa_eq(pt.rmsd(traj, mask=mask_2)[0], pt.rmsd(traj, mask=mask_2[0]))
        aa_eq(pt.rmsd(traj, mask=mask_2)[1], pt.rmsd(traj, mask=mask_2[1]))

        ca = pt.select('@CA', traj.top)
        cb = pt.select('@CB', traj.top)
        aa_eq(pt.rmsd(traj, mask=ca), pt.rmsd(traj, mask=[ca, cb])[0])
        aa_eq(pt.rmsd(traj, mask=cb), pt.rmsd(traj, mask=[ca, cb])[1])

    def test_raise_savematrices_if_not_dataset(self):
        traj = self.traj.copy()
        self.assertRaises(
            ValueError,
            lambda: pt.rmsd(traj, mask='@CA savematrices', dtype='ndarray'))

    def test_not_update_coordinates(self):
        traj = self.traj[:]
        data = pt.rmsd(traj, ref=3, update_coordinate=False)

        # make sure coordinates are not updated
        aa_eq(traj.xyz, self.traj.xyz)

        # make sure give the same rmsd values
        aa_eq(pt.rmsd(traj, ref=3), data)

    def test_combine_nofit_mass_nomod(self):
        cm = '''
        parm data/tz2.parm7
        trajin data/tz2.nc
        rms @CA nofit mass nomod
        '''
        state = pt.load_cpptraj_state(cm)
        state.run()

        unmut_traj = pt.iterload('data/tz2.nc', 'data/tz2.parm7')
        mut_traj = unmut_traj[:]

        data = pt.rmsd(mut_traj, mask='@CA', mass=True, nofit=True, update_coordinate=False)
        aa_eq(data, state.data[-1])

class TestRMSDPerRes(unittest.TestCase):

    def test_noreference(self):
        from pytraj.datafiles import load_cpptraj_output, tz2_ortho_trajin
        traj = pt.iterload("./data/tz2.ortho.nc", "./data/tz2.ortho.parm7")
        cout = load_cpptraj_output(tz2_ortho_trajin + """
        rmsd first @CA perres range 2-7""")
        d = pt.rmsd_perres(traj,
                           ref=0,
                           mask='@CA',
                           resrange='2-7',
                           dtype='ndarray')
        aa_eq(cout[1:].values, d)

    def test_reference(self):
        traj = pt.iterload("./data/tz2.truncoct.nc", "data/tz2.truncoct.parm7")
        txt = '''
        reference data/tz2.truncoct.nc 2 2
        rmsd :2-11 refindex 0 perres perresout center.agr range 1 perrescenter
        '''

        state = pt.load_batch(traj, txt).run()
        # state.data has 3 datasets: ref, rmsd, rmsd perres

        # cpptraj use 2nd reference
        rmsd0 = pt.rmsd(traj, ref=1, mask=':2-11')
        rmsdperres = pt.rmsd_perres(traj,
                                    ref=1,
                                    mask=':2-11',
                                    perres_mask='*',
                                    resrange='1',
                                    perres_center=True)
        aa_eq(rmsd0, state.data[2])
        aa_eq(rmsdperres[1], state.data[3].values)

    def test_frame_indices(self):
        traj = pt.iterload("data/tz2.truncoct.nc", "data/tz2.truncoct.parm7")
        traj2 = pt.iterload("data/tz2.truncoct.nc",
                            "data/tz2.truncoct.parm7",
                            frame_slice=(2, 8))

        txt = '''
        reference ./data/tz2.truncoct.nc 2 2
        rmsd :2-11 refindex 0 perres perresout center.agr range 1 perrescenter
        '''

        state = pt.load_batch(traj2, txt)
        state.run()

        frame_indices = range(2, 8)
        rmsd0 = pt.rmsd(traj, ref=1, mask=':2-11', frame_indices=frame_indices)
        rmsdperres = pt.rmsd_perres(traj,
                                    ref=1,
                                    mask=':2-11',
                                    perres_mask='*',
                                    resrange='1',
                                    perres_center=True,
                                    frame_indices=frame_indices)
        aa_eq(rmsd0, state.data[2])
        aa_eq(rmsdperres[1], state.data[3].values)

class TestRMSDnofit(unittest.TestCase):

    def test_0(self):
        traj = pt.iterload("./data/tz2.ortho.nc", "./data/tz2.ortho.parm7")

        cout = pt.datafiles.load_cpptraj_output("""
        parm ./data/tz2.ortho.parm7
        trajin ./data/tz2.ortho.nc
        rms first nofit
        rms first mass
        """)
        aa_eq(pt.rmsd(traj, nofit=True), cout[1])
        aa_eq(pt.rmsd(traj, mass=True), cout[2])

class TestPairwiseRMSD(unittest.TestCase):

    def testTwoTrajTypes(self):
        '''test different metrics with different traj objects
        '''
        funclist = [pt.iterload, pt.load]
        txt = '''
        parm ./data/Tc5b.top
        trajin ./data/Tc5b.x
        rms2d @CA metric_holder rmsout tmp.out
        '''

        for func in funclist:
            traj = func("./data/Tc5b.x", "./data/Tc5b.top")
            for metric in ['rms', 'nofit', 'dme']:
                d0 = pt.pairwise_rmsd(traj(mask='@CA'), metric=metric)
                d1 = pt.pairwise_rmsd(traj, mask='@CA', metric=metric)
                d2 = pt.pairwise_rmsd(traj(), mask='@CA', metric=metric)

                txt0 = txt.replace('metric_holder', metric)
                state = pt.datafiles.load_cpptraj_output(txt0, dtype='state')
                d3 = state.datasetlist[-1].values

                aa_eq(d0, d1)
                aa_eq(d0, d2)
                aa_eq(d0, d3)

class TestActionListRMSD(unittest.TestCase):

    def test_actionlist(self):
        traj = pt.iterload("./data/Tc5b.x", "./data/Tc5b.top")
        standard_rmsd = pt.rmsd(traj, mask='@CA')

        def test_rmsd(input_traj):
            from pytraj.c_action.c_action import Action_Rmsd
            from pytraj.datasets import DatasetList
            dslist = DatasetList()
            act = Action_Rmsd()
            act.read_input('first @CA', top=input_traj.top, dslist=dslist)
            act.check_topology(input_traj.top)

            for frame in input_traj:
                act.compute(frame)
            return (dslist.values)

        def test_rmsd_actlist(input_traj):
            from pytraj.c_action.c_action import Action_Rmsd
            from pytraj import ActionList
            from pytraj.datasets import DatasetList

            alist = ActionList()
            dslist = DatasetList()
            act = Action_Rmsd()
            alist.add(act,
                      'first @CA',
                      top=input_traj.top,
                      dslist=dslist)

            for frame in input_traj:
                alist.compute(frame)
            return (dslist.values)

        rmsd0 = test_rmsd(traj)
        rmsd1 = test_rmsd(traj[:])
        rmsd2 = test_rmsd_actlist(traj)
        rmsd3 = test_rmsd_actlist(traj[:])
        t0 = traj[:]
        rmsd4 = test_rmsd_actlist(t0)
        aa_eq(standard_rmsd, rmsd0)
        aa_eq(standard_rmsd, rmsd1)
        aa_eq(standard_rmsd, rmsd2)
        aa_eq(standard_rmsd, rmsd3)
        aa_eq(standard_rmsd, rmsd4)

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


'''
Created on 2 abr. 2020

@author: Sidney

Listado de bandas de la bd

'''

from PyQt5 import QtCore, QtWidgets
from bd.operaciones import Listar_Bandas

class Ventana_Listar_Banda(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(647, 415)
        MainWindow.setStyleSheet("QHeaderView::section{background-color:black;}")
        #Almacenamos el listado de bandas en una tupla
        self.listado_bandas = Listar_Bandas()
        self.principal_widget = QtWidgets.QWidget(MainWindow)
        self.principal_widget.setObjectName("principal_widget")
        self.gph_background = QtWidgets.QGraphicsView(self.principal_widget)
        self.gph_background.setGeometry(QtCore.QRect(-10, -20, 671, 431))
        self.gph_background.setStyleSheet("background-image: url(\'images/ini_background.jpg\');background-repeat: no-repeat; background-position: center;")
        self.gph_background.setObjectName("gph_background")
        self.tbl_listado_artistas = QtWidgets.QTableWidget(self.principal_widget)
        self.tbl_listado_artistas.setGeometry(QtCore.QRect(10, 20, 481, 341))
        self.tbl_listado_artistas.setObjectName("tbl_listado_artistas")
        self.tbl_listado_artistas.setStyleSheet("background: rgb(0,0,0, 0.8);"
                                                "color:white;"
                                                "border: 2px solid black;\n"
                                                "border-radius:5px;")
        self.tbl_listado_artistas.setColumnCount(2)
        self.tbl_listado_artistas.setColumnWidth(0,250)
        self.tbl_listado_artistas.setColumnWidth(1,202)
        self.tbl_listado_artistas.setRowCount(len(self.listado_bandas))
        #Generamos tantas cabeceras para las filas como resultados tengamos.
        for i in range(0,len(self.listado_bandas)):
            item = QtWidgets.QTableWidgetItem()
            self.tbl_listado_artistas.setVerticalHeaderItem(i, item)
        #end for
        item = QtWidgets.QTableWidgetItem()
        self.tbl_listado_artistas.setHorizontalHeaderItem(0, item)
        item = QtWidgets.QTableWidgetItem()
        self.tbl_listado_artistas.setHorizontalHeaderItem(1, item)
        #Creamos dos bucles para crear las celdas en la tabla
        #El primer bucle genera la fila
        for i in range(0,len(self.listado_bandas)):
            #El segundo bucle se encarga de las columnas
            for j in range(2):
                item = QtWidgets.QTableWidgetItem()
                self.tbl_listado_artistas.setItem(i, j, item)
            #end for
        #end for
        self.btn_modificar_banda = QtWidgets.QPushButton(self.principal_widget)
        self.btn_modificar_banda.setGeometry(QtCore.QRect(0, 0, 0, 0))
        self.btn_eliminar_banda = QtWidgets.QPushButton(self.principal_widget)
        self.btn_eliminar_banda.setGeometry(QtCore.QRect(0, 0, 0, 0))
        MainWindow.setCentralWidget(self.principal_widget)
        self.actionIncluir_artista_banda = QtWidgets.QAction(MainWindow)
        self.actionIncluir_artista_banda.setObjectName("actionIncluir_artista_banda")
        self.actionIncluir_disco = QtWidgets.QAction(MainWindow)
        self.actionIncluir_disco.setObjectName("actionIncluir_disco")
        self.actionIncluir_genero = QtWidgets.QAction(MainWindow)
        self.actionIncluir_genero.setObjectName("actionIncluir_genero")
        self.actionListar_artistas_bandas = QtWidgets.QAction(MainWindow)
        self.actionListar_artistas_bandas.setObjectName("actionListar_artistas_bandas")
        self.actionListar_discos = QtWidgets.QAction(MainWindow)
        self.actionListar_discos.setObjectName("actionListar_discos")
        self.actionListar_generos = QtWidgets.QAction(MainWindow)
        self.actionListar_generos.setObjectName("actionListar_generos")

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    #end setupUi

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "Directorio musical"))
        item = self.tbl_listado_artistas.horizontalHeaderItem(0)
        item.setText(_translate("MainWindow", "Artista"))
        item = self.tbl_listado_artistas.horizontalHeaderItem(1)
        item.setText(_translate("MainWindow", "Nacionalidad"))
        __sortingEnabled = self.tbl_listado_artistas.isSortingEnabled()
        self.tbl_listado_artistas.setSortingEnabled(False)
        #Generamos las líneas necesarias en función de la longitud del listado
        i = 0
        for banda in self.listado_bandas:
            item = self.tbl_listado_artistas.verticalHeaderItem(i)
            item.setText(_translate("MainWindow", ""))
            for j in range(0,2):
                item = self.tbl_listado_artistas.item(i, j)
                item.setText(_translate("MainWindow", banda[j]))
            #end for
            i += 1
        #end for
        self.tbl_listado_artistas.setSortingEnabled(__sortingEnabled)
        self.actionIncluir_artista_banda.setText(_translate("MainWindow", "Incluir artista/banda"))
        self.actionIncluir_disco.setText(_translate("MainWindow", "Incluir disco"))
        self.actionIncluir_genero.setText(_translate("MainWindow", "Incluir género"))
        self.actionListar_artistas_bandas.setText(_translate("MainWindow", "Listar artistas/bandas"))
        self.actionListar_discos.setText(_translate("MainWindow", "Listar discos"))
        self.actionListar_generos.setText(_translate("MainWindow", "Listar géneros"))
    #end restranslateUi

    def modificar_eliminar(self):
        _translate = QtCore.QCoreApplication.translate
        self.btn_modificar_banda.setGeometry(QtCore.QRect(520, 290, 101, 31))
        self.btn_modificar_banda.setObjectName("btn_modificar_banda")
        self.btn_modificar_banda.setStyleSheet("border: 2px solid black;"
                                                "border-radius:5px;"
                                                "background: rgb(255,255,255);"
                                                "color:black;"
                                                "font: 13px")
        self.btn_eliminar_banda.setGeometry(QtCore.QRect(520, 330, 101, 31))
        self.btn_eliminar_banda.setObjectName("btn_eliminar_banda")
        self.btn_eliminar_banda.setStyleSheet("border: 2px solid black;"
                                            "border-radius:5px;"
                                            "background: rgb(255,255,255);"
                                            "color:black;"
                                            "font: 13px")
        self.btn_modificar_banda.setText(_translate("MainWindow", "Modificar"))
        self.btn_eliminar_banda.setText(_translate("MainWindow", "Eliminar"))
    #end modificar_eliminar
#end Ventana_Listar_Banda


# Copyright 2018 Dong-Hyun Lee, Kakao Brain.
# (Strongly inspired by original Google BERT code and Hugging Face's code)
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

""" Transformer Model Classes & Config Class """
import pdb
import math
import json
from typing import NamedTuple
import random

import numpy as np
import torch
import torch.nn as nn
import torch.nn.functional as F

from utils.utils import split_last, merge_last, mixup_op

class Config(NamedTuple):
    "Configuration for BERT model"
    vocab_size: int = None # Size of Vocabulary
    dim: int = 768 # Dimension of Hidden Layer in Transformer Encoder
    n_layers: int = 12 # Numher of Hidden Layers
    n_heads: int = 12 # Numher of Heads in Multi-Headed Attention Layers
    dim_ff: int = 768*4 # Dimension of Intermediate Layers in Positionwise Feedforward Net
    #activ_fn: str = "gelu" # Non-linear Activation Function Type in Hidden Layers
    p_drop_hidden: float = 0.1 # Probability of Dropout of various Hidden Layers
    p_drop_attn: float = 0.1 # Probability of Dropout of Attention Layers
    max_len: int = 512 # Maximum Length for Positional Embeddings
    n_segments: int = 2 # Number of Sentence Segments

    @classmethod
    def from_json(cls, file):
        return cls(**json.load(open(file, "r")))

def gelu(x):
    "Implementation of the gelu activation function by Hugging Face"
    return x * 0.5 * (1.0 + torch.erf(x / math.sqrt(2.0)))

class LayerNorm(nn.Module):
    "A layernorm module in the TF style (epsilon inside the square root)."
    def __init__(self, cfg, variance_epsilon=1e-12):
        super().__init__()
        self.gamma = nn.Parameter(torch.ones(cfg.dim)) # (preload)
        self.beta  = nn.Parameter(torch.zeros(cfg.dim)) # (preload)
        self.variance_epsilon = variance_epsilon

    def forward(self, x):
        u = x.mean(-1, keepdim=True)
        s = (x - u).pow(2).mean(-1, keepdim=True)
        x = (x - u) / torch.sqrt(s + self.variance_epsilon)
        return self.gamma * x + self.beta

class Embeddings(nn.Module):
    "The embedding module from word, position and token_type embeddings."
    def __init__(self, cfg):
        super().__init__()
        self.tok_embed = nn.Embedding(cfg.vocab_size, cfg.dim) # (preload)
        self.pos_embed = nn.Embedding(cfg.max_len, cfg.dim) # (preload)
        self.seg_embed = nn.Embedding(cfg.n_segments, cfg.dim) # (preload)

        self.norm = LayerNorm(cfg) # (preload)
        self.drop = nn.Dropout(cfg.p_drop_hidden)

    def forward(
        self, x, seg, mixup, shuffle_idx, l, clone_ids, mixup_layer, simple_pad, no_grad_clone
        ):
        seq_len = x.size(1)
        pos = torch.arange(seq_len, dtype=torch.long, device=x.device)
        pos = pos.unsqueeze(0).expand_as(x) # (S,) -> (1, S) -> (B, S)  이렇게 외부에서 생성되는 값

        token_e = self.tok_embed(x)
        pos_e = self.pos_embed(pos)
        seg_e = self.seg_embed(seg)

        if mixup and 'word' in mixup:
            if simple_pad:
                if mixup_layer == 0:
                    token_e = mixup_op(token_e, l, shuffle_idx)
            else:
                if no_grad_clone:
                    with torch.no_grad():
                        c_token_e = self.tok_embed(clone_ids)
                else:
                    c_token_e = self.tok_embed(clone_ids)

                if mixup_layer == 0:
                    embeds_a, embeds_b = token_e, c_token_e[shuffle_idx]
                    token_e = l * embeds_a + (1-l) * embeds_b
                else:
                    e = token_e + pos_e + seg_e
                    ec = c_token_e + pos_e + seg_e

                    h = self.drop(self.norm(e))

                    if no_grad_clone:
                        with torch.no_grad():
                            hc = self.drop(self.norm(ec))
                    else:
                        hc = self.drop(self.norm(ec))

                    return h, hc

        e = token_e + pos_e + seg_e
        return self.drop(self.norm(e)), None

class MultiHeadedSelfAttention(nn.Module):
    """ Multi-Headed Dot Product Attention """
    def __init__(self, cfg):
        super().__init__()
        self.proj_q = nn.Linear(cfg.dim, cfg.dim) #(preload)
        self.proj_k = nn.Linear(cfg.dim, cfg.dim) #(preload)
        self.proj_v = nn.Linear(cfg.dim, cfg.dim) #(preload)
        self.drop = nn.Dropout(cfg.p_drop_attn)
        self.scores = None # for visualization
        self.n_heads = cfg.n_heads

    def forward(self, x, mask):
        """
        x, q(query), k(key), v(value) : (B(batch_size), S(seq_len), D(dim))
        mask : (B(batch_size) x S(seq_len))
        * split D(dim) into (H(n_heads), W(width of head)) ; D = H * W
        """
        # (B, S, D) -proj-> (B, S, D) -split-> (B, S, H, W) -trans-> (B, H, S, W)
        q, k, v = self.proj_q(x), self.proj_k(x), self.proj_v(x)
        q, k, v = (split_last(x, (self.n_heads, -1)).transpose(1, 2)
                   for x in [q, k, v])
        # (B, H, S, W) @ (B, H, W, S) -> (B, H, S, S) -softmax-> (B, H, S, S)
        scores = q @ k.transpose(-2, -1) / np.sqrt(k.size(-1))
        if mask is not None:
            mask = mask[:, None, None, :].float()
            scores -= 10000.0 * (1.0 - mask)
        scores = self.drop(F.softmax(scores, dim=-1))
        # (B, H, S, S) @ (B, H, S, W) -> (B, H, S, W) -trans-> (B, S, H, W)
        h = (scores @ v).transpose(1, 2).contiguous()
        # -merge-> (B, S, D)
        h = merge_last(h, 2)
        self.scores = scores
        return h

class PositionWiseFeedForward(nn.Module):
    """ FeedForward Neural Networks for each position """
    def __init__(self, cfg):
        super().__init__()
        self.fc1 = nn.Linear(cfg.dim, cfg.dim_ff) #(preload)
        self.fc2 = nn.Linear(cfg.dim_ff, cfg.dim) #(preload)
        #self.activ = lambda x: activ_fn(cfg.activ_fn, x)

    def forward(self, x):
        # (B, S, D) -> (B, S, D_ff) -> (B, S, D)
        return self.fc2(gelu(self.fc1(x)))

class Block(nn.Module):
    """ Transformer Block """
    def __init__(self, cfg):
        super().__init__()
        self.attn = MultiHeadedSelfAttention(cfg)
        self.proj = nn.Linear(cfg.dim, cfg.dim) # (preload)
        self.norm1 = LayerNorm(cfg) #(preload)
        self.pwff = PositionWiseFeedForward(cfg) #(preload)
        self.norm2 = LayerNorm(cfg) #(preload)
        self.drop = nn.Dropout(cfg.p_drop_hidden)

    def forward(self, x, mask):
        h = self.attn(x, mask)
        h = self.norm1(x + self.drop(self.proj(h)))
        h = self.norm2(h + self.drop(self.pwff(h)))
        return h

class Transformer(nn.Module):
    """ Transformer with Self-Attentive Blocks"""
    def __init__(self, cfg):
        super().__init__()
        self.embed = Embeddings(cfg)
        self.blocks = nn.ModuleList([Block(cfg) for _ in range(cfg.n_layers)])   # h 번 반복

    def forward(
            self,
            x=None, seg=None, mask=None,
            clone_ids=None, mixup=None, shuffle_idx=None, l=1,
            mixup_layer=-1, simple_pad=False, no_grad_clone=False
        ):
        h, hc = self.embed(
            x, seg, mixup, shuffle_idx, l, clone_ids, mixup_layer, simple_pad, no_grad_clone
        )

        layer = 1
        for block in self.blocks:
            h = block(h, mask)

            if hc is not None:
                if no_grad_clone:
                    with torch.no_grad():
                        hc = block(hc, mask)
                else:
                    hc = block(hc, mask)

            if mixup_layer == layer and (mixup == 'word' or mixup == 'word_cls'):
                if hc is not None:
                    h_a, h_b = h, hc[shuffle_idx]
                    h = l * h_a + (1-l) * h_b
                    hc = None
                else:
                    h = mixup_op(h, l, shuffle_idx)

            layer += 1
        return h

class Classifier(nn.Module):
    """ Classifier with Transformer """
    def __init__(self, cfg, n_labels):
        super().__init__()
        self.transformer = Transformer(cfg)
        self.fc = nn.Linear(cfg.dim, cfg.dim)
        self.activ = nn.Tanh()
        self.drop = nn.Dropout(cfg.p_drop_hidden)
        self.classifier = nn.Linear(cfg.dim, n_labels)
        self.layers = cfg.n_layers

    def forward(
            self,
            input_ids=None,
            segment_ids=None,
            input_mask=None,
            output_h=False,
            input_h=None,
            mixup=None,
            shuffle_idx=None,
            clone_ids=None,
            l=1,
            manifold_mixup=None,
            simple_pad=False,
            no_grad_clone=False
        ):
        if input_h is None:

            if mixup == 'word':
                mixup_layer = random.randint(0, self.layers) if manifold_mixup else 0
            elif mixup == 'word_cls':
                mixup_layer = random.randint(0, self.layers+1) if manifold_mixup else 0
            elif mixup == 'cls':
                mixup_layer = self.layers + 1
            elif mixup == 'word_cls_only':
                mixup_layer = random.choice([0, self.layers + 1])
            else:
                mixup_layer = -1

            h = self.transformer(
                x=input_ids, seg=segment_ids, mask=input_mask,
                clone_ids=clone_ids, mixup=mixup, shuffle_idx=shuffle_idx, l=l,
                mixup_layer = mixup_layer, simple_pad=simple_pad, no_grad_clone=no_grad_clone
            )

            # only use the first h in the sequence
            # h shape = [16, 128, 768]
            # h[h:, 0] = [16, 768]

            pooled_h = self.activ(self.fc(h[:, 0]))

            # pooled_h = [16, 768]

            if mixup_layer == self.layers+1:
                pooled_h = mixup_op(pooled_h, l, shuffle_idx)

            if output_h:
                return pooled_h
        else:
            pooled_h = input_h
        logits = self.classifier(self.drop(pooled_h))
        return logits


import numpy as np
import torch
import matplotlib.pyplot as plt
import argparse
from utils import objectview
import pandas as pd
from uci import get_data

parser = argparse.ArgumentParser()
parser.add_argument('--uci_data', type=str, default='housing')
parser.add_argument('--log_dir', type=str, default='y0')
load_args = parser.parse_args()

load_path = './Data/uci/'+load_args.uci_data+'/'+load_args.log_dir+'/'

import joblib
result = joblib.load(load_path+'result.pkl')
result = objectview(result)
args = result.args
for key in args.__dict__.keys():
    print(key,': ',args.__dict__[key])

from plot_utils import plot_result
plot_result(result, load_path)

df_X = pd.read_csv('./Data/uci/'+ args.uci_data +"/"+ args.uci_data +'.csv')
df_y = pd.read_csv('./Data/uci/'+ args.uci_data +"/"+ args.uci_data +'_target.csv', header=None)
data = get_data(df_X, df_y, args.train_edge, args.train_y, args.seed)

from gnn_model import GNNStack
model = GNNStack(data.num_node_features, args.node_dim,
                        args.edge_dim, args.edge_mode,
                        args.model_types, args.dropout)
model.load_state_dict(torch.load(load_path+'model.pt'))
model.eval()

from prediction_model import MLPNet
predict_model = MLPNet([args.node_dim], 1,
                        hidden_layer_sizes=args.predict_hiddens,
                        dropout=args.dropout)
predict_model.load_state_dict(torch.load(load_path+'predict_model.pt'))
predict_model.eval()

x = data.x.clone().detach()
y = data.y.clone().detach()
train_edge_index = data.train_edge_index.clone().detach()
train_edge_attr = data.train_edge_attr.clone().detach()

x_embd = model(x, train_edge_attr, train_edge_index).detach()
pred = predict_model(x_embd)[:data.y.shape[0],0]
pred_test = pred[data.test_y_mask].detach()
label_test = y[data.test_y_mask].detach()

import matplotlib.pyplot as plt
plt.figure()
plt.subplot(2,1,1)
plt.plot(pred_test[::10],label='pred')
plt.plot(label_test[::10],label='true')
plt.legend()
plt.subplot(2,1,2)
for i in range(20):
    plt.plot(x_embd[i,:],label=str(i))
plt.legend()
plt.savefig(load_path+'check_embedding.png')


a= int(input("enter the no :"))
sum=0
while(a!=0):
	b=a%10
	fact=1
	while b!=0:
		fact=fact*b
		b=b-1
	sum=sum+fact
	a=a//10
print(sum)


import DarkHexUtilities

columnLetters = "abcdefghjklmnopqrstuvwxyz"

class DarkHexHumanPlayer(object):
    """
    Human interface for dark hex
    """
    def __init__(self, colour, rows, columns):
        self.colour = colour
        self.rows = rows
        self.columns = columns

    def genmove(self, board, unknownPieces, time, status):
        print(status)
        print(time, "Time Remaining")
        DarkHexUtilities.prettyBoard(board, self.rows, self.columns)
        move = input("Move? (x#)")
        return int(move[1:]) - 1, columnLetters.find(move[0].lower())