import requests
import time
import lxml.html
import logging

from bs4 import BeautifulSoup as bs

from secret import AUTF_DATA

logger = logging.getLogger(__name__)
logging.basicConfig(
        level=logging.INFO,
        format='%(asctime)s %(levelname)s: %(module)s: %(message)s',
        handlers=[
            logging.FileHandler("bot.log"),
            logging.StreamHandler()
        ],
    )

# Чтобы вк считал нас немобильным устройством
HEADERS = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36'}

class FParser:
    def __init__(self, setts):
        self.AGE_DIFF = 5 # Разница в большую сторону с минимальным возрастом
        self.STORE_LIMIT = 16 # Лимит хранения старых id для каждой ссылки поиска
        self.TOPIC_LIMIT = 20 # Максимальное количество топиков в одной странице(ограничение от ВК)
        self.TEXT_LIMIT = 200 # Максимальное кол-во символов от поста, выводящиеся ботом

        if setts['old_links'] == {}:
            self.__old_links = {link: [] for link in setts['links']}
        else:
            self.__old_links = setts['old_links']

        # Учтение настроек, переданые от бота
        self.__setts = dict()
        self.__setts['key_words'] = setts['key_words']
        self.__setts['links'] = setts['links']
        self.__setts['ages'] = self.__genetate_ages(setts['age'])

    def __genetate_ages(self, age):
        """
        Cоздание списка возрастов [мин.,...,мин.+5]
        """
        min_age = int(age)
        ages = []
        for age in range(min_age, min_age + self.AGE_DIFF):
            ages.append(str(age))
        return ages

    def do_parse(self):
        """
        Список найденых сообщений и статистика, которые будут возвращены боту
        """
        to_bot = {
            'messages': [],
            'total': 0,
            'aim': 0,
            'old_links': {}
        }

        for root_link in self.__setts['links']:
            # Имитация запроса
            request = requests.get(root_link, headers=HEADERS)
            soup = bs(request.content, "html.parser")

            # Если ошибка доступа, то скорее всего для страницы нужно авторизоваться
            if ('Ошибка доступа' in soup.text):
                try:
                    session = self.__autf(AUTF_DATA)
                except:
                    logger.warning("Ошибка авторизации по адресу: " + root_link)
                    break

                if (session == "ErrorAuth"):
                    logger.warning("Ошибка авторизации по адресу: " + root_link)
                    break
                else:
                    request = session.get(root_link)
                    soup = bs(request.content, "html5lib")

            # Если это записи на стене группы
            if 'wall' in root_link:
                # Берём самые новые посты в количестве лимита
                with open('tt.html', 'w', encoding='utf-8') as f:
                    f.write(soup.prettify())
                posts = soup.find_all('div', attrs={'class': 'wall_text'})[:self.STORE_LIMIT]

                # Если мы уже храним максимальное количество постов, то новые посты должны поступать
                # в обратном порядке, это поможет сохранить их последовательность от самых новых до старых
                if (len(self.__old_links[root_link]) == self.STORE_LIMIT):
                    posts = posts[::-1]

                # Проход по каждому посту от самого нового до лимита хранения
                for post in posts:
                    # Генерируем ппрямую ссылку на пост из его уникального id
                    link = post.find('div', attrs={'class':'wall_post_cont _wall_post_cont'})['id'][3:]
                    full_link = 'https://vk.com/wall' + link

                    # Если старая ссылка, сразу пропускаем
                    if link in self.__old_links[root_link]:
                        continue

                    post_text = ""
                    try:
                        # Открываем пост полность в новой вкладке и анализируем полный текст
                        request = requests.get(full_link, headers=HEADERS)
                        full_post = bs(request.content, "lxml")
                        with open('full.html', 'w', encoding='utf-8') as f:
                            f.write(full_post.prettify())
                        post_text = full_post.find('div', attrs={'class': 'wall_post_text'}).text
                    except:
                        logger.warning("Cбой при открытии " + full_link)
                        # Скорее всего пост не содержит текста и может являться анкетой вовсе,
                        # но всё равно сохраняем его в старые ссылки, чтобы не пытаться
                        # открыть его при каждой итерации.
                        self.__old_links[root_link].append(link)
                        continue
                    else:
                        self.__analize(to_bot, post_text, link, full_link, root_link)
            elif 'topic' in root_link: # Если это записи в топике группы
                try:
                    topic_wall = soup.find('div', attrs={'id': 'content'})
                    topics = topic_wall.find_all('div', attrs={'class': 'bp_post clear_fix'})
                except:
                    logger.warning("Cбой при доступе к топику: " + root_link)
                    continue
                else:
                    # Проход по последним записям в количесве ЛИМИТА либо по всем, если их меньше
                    nlist = (topics if len(topics) < self.STORE_LIMIT else topics[-self.STORE_LIMIT:])
                    for topic in nlist:
                        topic_text = topic.find('div', attrs={'class': 'bp_text'}).text
                        link = topic.find('a', attrs={'class': 'bp_date'})['href']
                        full_link = 'https://vk.com' + link

                        # Если старая ссылка, сразу пропускаем
                        if link in self.__old_links[root_link]:
                            continue

                        self.__analize(to_bot, topic_text, link, full_link, root_link)
            else:
                pass
            to_bot['old_links'] = self.__old_links
        return to_bot

    def __analize(self, to_bot, text, link, full_link, root_link):
        """
        Анализ наличия ключевых слов и формировани ответа для бота
        """
        if link not in self.__old_links[root_link]:
            # Если пришла новая ссылка, то: если её ячейка уже заполнилась,
            # тогда добавляем её в начало, сдвинув все остальные вправо, при этом,
            # удалится наиболее старая запись
            if (len(self.__old_links[root_link]) == self.STORE_LIMIT):
                self.__old_links[root_link] = self.__push_queue(link, self.__old_links[root_link])
            else:
                self.__old_links[root_link].append(link)
            to_bot['total'] += 1
        else:
            return # Пропуск старой ссылки, которая просматривалась
        if (
            any((age in text) for age in self.__setts['ages']) and
            any((key.lower() in text.lower()) for key in self.__setts['key_words'])
        ):
            logger.info("Ссылка подходит: " + full_link)
            to_bot['messages'].append(
                text[:self.TEXT_LIMIT] + "...\n\n" + "ссылка: " + full_link
            )
            to_bot['aim'] = to_bot['aim'] + 1
        else:
            logger.info("Ссылка НЕ подходит: " + full_link)

    def __autf(self, autf_data):
        """
        Метод для авторизации, если предполагается поиск в закрытом сообществе
        """
        login_url = 'https://vk.com/login'

        session = requests.session()
        data = session.get(login_url)
        html = lxml.html.fromstring(data.content)

        form = html.forms[0]
        form.fields['email'] = autf_data['login']
        form.fields['pass'] = autf_data['pass']

        response = session.post(form.action, data=form.form_values())

        if ('onLoginDone' in response.text):
            return session
        else:
            logger.error("ErrorAuth")
            return "ErrorAuth"

    def __push_queue(self, el, array):
        return [el] + array[:-1]


from math import radians, copysign, pi, sin, cos, atan2, degrees, acos, asin, sqrt, atan
from numpy import array, cross, dot, linalg
import numpy.polynomial.polynomial as npp

k = 0.01720209895  # Gaussian gravitational constant
mu = 1

def get_data_points(path, number):
    """Takes in the following parang_mometers:
    1. a text file path, path
    2. a number specifying the number of observations wanted, number

    Every line in the file contains the following information for one
    observation night:
    1. UT date/time at middle of observation (Julian Days)
    2. RA (hh:mm:ss.ss), DEC (dd:mm:ss.s), and
    3. Sun vector from JPL Horizons (AU, equatorial cartesian, J2000, apparent states)

    Example:
        2457927.76426 17:27:15.08 -24:44:53.0 -3.092452663004570E-02 9.321463833793008E-01 4.040478235741391E-01"""

    # open the file, read all lines and save every line to a list
    file = open(path, "r")
    observation_data = file.read().splitlines()
    file.close()

    # get the total observations in the file
    total_observations = len(observation_data)

    # return all observations if all them are wanted
    if number == total_observations:
        return observation_data
    # display if the user want more observations than is available
    elif number >= total_observations:
        print("There are only", number, "observations.")
        number = int(input(""))

    # Otherwise, make the user choose the ones they want.
    # list that will holds observation the user chooses
    observations_chosen = []
    # in case the user chooses observations out of order, the indices are
    # saved first and then sorted to get them in the correct order
    indices = []
    print("There are more than", number, "observations available. Which would you like to use?")
    print("Enter the number next to the observation you want to use to select it.")

    # display the possible observations
    for i in range(1, total_observations+1):
        print( str(i) + ".", observation_data[i-1] )

    # while the user has not chosen three observations...
    count = 0
    while count != number:
        index = get_valid_number(0, total_observations, indices, "Observation Number: ")
        indices.append(index)
        count += 1

    for index in sorted(indices):
        observations_chosen.append( observation_data[index-1] )
    return observations_chosen

def decimalToSexagesimal(degrees, hour = False):
    """"Takes in decimal degrees and returns tuple holding the sexagesimal
    version. If you want the output in hours, the function takes in a second
    boolean argument that can be set to True. """

    hours, minutes, seconds = degrees, 0, 0
    if hour:
        hours /= 15
    minutes = (hours - int(hours))*60
    hours = int(hours)

    seconds = (minutes - int(minutes))*60
    minutes = int(minutes)

    return hours, minutes, seconds

def sexagesimalToDecimal(degrees, minutes, seconds, radians = False, normalize = False):
    """Converts sexagesimal value to degrees. Takes in a fourth boolean value that specifies
    if the output is to be returned in radians, and fifth boolean value that specifies to
    normalize the angle"""

    # handle a negative angle
    n_degrees = degrees
    n_minutes = copysign(minutes, degrees)
    n_seconds = copysign(seconds, degrees)

    # perform angle conversion
    n_minutes += n_seconds/60
    n_degrees += n_minutes/60

    # return result
    if normalize:
        n_degrees %= 360
    if radians:
        return n_degrees*pi/180
    else:
        return n_degrees

def convert_data_line_to_numbers(string):
    """"Reads data line and returns the following numbers in a dictionary:
    1. UT time in Julian Days
    2. Right ascension in radians
    3. Declination in radians
    4. numpy array holding Sun vector components"""

    # separate values in the string
    values = string.split()

    # get UT time
    time = float( values[0] )

    # get RA in sexagesimal hour form and convert to radians
    sexagesimal_RA = [float(a) for a in values[1].split(":")]
    # convert decimal hour into decimal degree by multiplying
    # by 15
    RA = sexagesimalToDecimal( *sexagesimal_RA, True)*15

    # get DEC in sexagesimal form and convert to radians
    sexagesimal_DEC = [float(a) for a in values[2].split(":")]
    DEC = sexagesimalToDecimal( *sexagesimal_DEC, True )

    # Get Sun Vector and convert to numpy array
    sun_vector = array( [float(a) for a in values[3:]] )

    return {"time":time, "RA":RA, "DEC":DEC, "sun vector":sun_vector}

def calculate_taus(k, time1, time2, time3):
    """Takes in a k-value, three Julian day values and returns the tau
    intervals as a dictionary"""

    tau3 = k * ( time3 - time2 )
    tau1 = k * ( time1 - time2 )
    tau = tau3 - tau1

    return {"tau":tau, "tau1":tau1, "tau3":tau3}

def calculate_rhohat(RA, DEC):
    """Takes in RA and DEC values in radians and returns a numpy array
    holding the components of the rhohat vector"""

    x_comp = cos(RA) * cos(DEC)
    y_comp = sin(RA) * cos(DEC)
    z_comp = sin(DEC)

    return array([x_comp, y_comp, z_comp])

def calculate_Ds(sun_vectors, rhohats):
    """Takes in two dictionaries:
    1. sun vectors
    2. rhohats

    Returns dictionary holding D values needed to calculate ranges"""

    D0 = dot(rhohats[1], cross( rhohats[2], rhohats[3] ))
    Ds = {"D0":D0}
    for j in "123":
        Ds["D1" + j] = dot( cross( sun_vectors[int(j)], rhohats[2] ), rhohats[3] )
        Ds["D2" + j] = dot( cross( rhohats[1], sun_vectors[int(j)] ), rhohats[3] )
        Ds["D3" + j] = dot( rhohats[1],  cross( rhohats[2], sun_vectors[int(j)] ) )

    return Ds

def getMag(vector):
    """Takes in a list that holds the components of a vector
    and returns the magnitude of the vector"""

    # check if the parameter given is already a scalar
    if type(vector).__name__ == "float64":
        return vector

    return (vector[0]**2 + vector[1]**2 + vector[2]**2)**0.5

def SEL(taus, Sun2, rhohat2, Ds):
    """Scalar equation of Lagrange function.
    Takes in the following parang_mometers:
    1. a dictionary holding all tau values
    2. sun vector of second observation
    3. rhohat of second observation
    4. a dictionary holding D0, D21, D22, and D23 in that order.

    Returns an r2 and its corresponding rho value chosen by the user
    if there is more than 1 positive, real root"""

    possible_rhos = []

    A1 = taus["tau3"]/taus["tau"]
    B1 = (A1 / 6) * (taus["tau"]**2 - taus["tau3"]**2)
    A3 = -taus["tau1"]/taus["tau"]
    B3 = (A3 / 6) * (taus["tau"]**2 - taus["tau1"]**2)

    A = (A1 * Ds["D21"] - Ds["D22"] + A3*Ds["D23"]) / -Ds["D0"]
    B = (B1 * Ds["D21"] + B3*Ds["D23"]) / -Ds["D0"]

    E = -2 * (dot(rhohat2, Sun2))
    F = getMag(Sun2)**2

    # coefficients of 8th degree polynomial
    a = -(A**2 + A*E + F)
    b = -(2*A*B + B*E)
    c = -B**2

    # find the roots and then filter out the real positive numbers
    possible_roots = [ x.real for x in npp.polyroots([c, 0, 0, b, 0, 0, a, 0, 1]) if x.imag == 0 and x.real > 0]

    # keep track of corresponding rho values with a list
    for root in possible_roots:
        possible_rhos.append( A + B / root**3 )

    # filter out roots with positive rhos
    roots = []
    rhos = []
    for index in range(len(possible_roots)):
        # if rho value is positive, add it and its root value to their
        # corresponding lists
        if possible_rhos[index] >= 0:
            roots.append( possible_roots[index] )
            rhos.append( possible_rhos[index] )

    index = 0
    # check if there are more than one possible roots
    if len(roots) > 1:
        print("There are more than one possible r2 values. Which would you like to use?")
        print("Enter the number on the left of the root to select it.")

        # display possible roots
        for index in range(len(possible_roots)):
            print(str(index + 1) + ".", possible_roots[index])

        index = get_valid_number(1, len(possible_roots), [], "Root number: ") - 1
    return roots[index], rhos[index]

def fDeltaE(x, semi_major_a, r2, r2dot, n, tau):
    """Takes in the following values:
    1. an initial guess, x
    2. semi major axis, semi_major_a
    3. position vector of second observation, r2
    4. velocity vector of second observation, r2dot
    5. coefficient n
    6. Gaussian interval, tau
    Returns f(initial guess)"""

    second_term = -(1 - getMag(r2)/semi_major_a) * sin(x)
    third_term = ( dot(r2, r2dot) / (n * semi_major_a**2) ) * ( 1 - cos(x) )
    fourth_term = -n * tau

    return x + second_term + third_term + fourth_term

def fDeltaEPrime(x, semi_major_a, r2, r2dot, n, tau):
    """Takes in the following values:
    1. an initial guess, x
    2. semi major axis, semi_major_a
    3. position vector of second observation, r2
    4. velocity vector of second observation, r2dot
    5. coefficient n
    6. Gaussian time interval, tau
    Returns f'(initial guess)"""

    second_term = -(1 - getMag(r2)/semi_major_a) * cos(x)
    third_term = ( dot(r2, r2dot) / (n * semi_major_a**2) ) * sin(x)

    return 1 + second_term + third_term

def newtons_method(f, fPrime, initial_numb, tol, args=[]):
    """Takes in a function f, its derivative fPrime, an initial guess (AKA x0), a
    tolerance value (AKA convergence value), and arguments that f and fPrime need"""
    # initial guesses
    root = initial_numb
    rootP = root - f(initial_numb, *args) / fPrime(initial_numb, *args)

    # while the tolerance has not been met...
    while abs(root - rootP) > tol:
        root = rootP
        rootP = root - f(root, *args) / fPrime(root, *args)

    return rootP

def fg(tau, r2, r2dot, flag = "f"):
    """Takes in the following values:
    1. Gaussian time interval, tau
    2. position vector, r2
    3. velocity vector, r2dot
    4. indicator of 2nd, 3rd, or 4th order or functions, flag
    Returns the values of f and g"""

    mu = 1
    r2_mag = getMag(r2)
    u = mu / r2_mag**3

    # f and g series to the second order
    if flag == "2":
        f_series = [
            1,
            - 0.5 * u * tau**2,
        ]
        g_series = [
            tau,
            -1/6 * u * tau**3
        ]
        return sum(f_series), sum(g_series)

    # numbers needed for the third and fourth order of f and g series
    r2dot_2 = -mu * r2 / r2_mag**3
    r2dot_3 = (-mu / r2_mag**5) * ( r2_mag**2 * r2 - 3 * dot(r2, r2dot) * r2)
    z = dot(r2, r2dot) / r2_mag**2
    q = dot( r2dot, r2dot ) / r2_mag**2 - u

    # f and g functions
    if flag == "f":
        # calculate the semi major axis and n with current r2 and r2dot values
        semi_major_a = get_semi_major_a(r2dot, getMag(r2))
        n = sqrt(1 / semi_major_a**3)

        # estimate the change in E using Newton's method
        deltaE = newtons_method(fDeltaE, fDeltaEPrime, n*tau, 1E-12, [semi_major_a, r2, r2dot, n, tau])

        # f and g function definitions
        f = 1 - (semi_major_a/getMag(r2)) * ( 1 - cos(deltaE) )
        g = tau + (1/n) * (sin(deltaE) - deltaE)

        return f, g
    # 3rd order of f and g series
    elif flag == "3":
        f_series = [
            1,
            - 0.5 * u * tau**2,
            0.5 * u * z * tau**3
        ]

        g_series = [
            tau,
            -1/6 * u * tau**3
        ]
        return sum(f_series), sum(g_series)

    # fourth order of f and g series
    elif flag == "4":
        f_series = [
            1,
            - 0.5 * u * tau**2,
            0.5 * u * z * tau**3,
           1/24 * ( 3*u*q - 15 * u * z**2 + u**2) * tau**4
        ]

        g_series = [
            tau,
            -1/6 * u * tau**3,
            1/4 * u * z * tau**4
        ]
        return sum(f_series), sum(g_series)
    # displays if flag given was incorrect
    else:
        print("invalid flag value given")

def calculate_scalar_ranges(taus, r2, r2dot, Ds, flag):
    """Takes in the following:
    1. dictionary holding tau values, taus
    2. numpy array representing the position vector for the 2nd observation,
       r2
    3. dictionary holding all D coefficients, Ds
    4. flag to pass on to the fg function

    The f and g series are then calculated according to the flag parameter
    to then find c1 and c3. c1 and c3 are then used to calculate the scalar ranges.
    Returns a dictionary holding the scalar ranges"""

    f1, g1 = fg(taus["tau1"], r2, r2dot, flag)
    f3, g3 = fg(taus["tau3"], r2, r2dot, flag)

    cs = {
    "c1": g3 / ( f1*g3 - g1*f3 ),
    "c2": -1,
    "c3": -g1 / ( f1*g3 - g1*f3 )
    }

    scalar_ranges = {}
    for index in "123":
        numerator = cs["c1"]*Ds["D" + index + "1"] + cs["c2"]*Ds["D" + index + "2"] + cs["c3"]*Ds["D" + index + "3"]
        scalar_ranges[int(index)] = numerator / ( cs["c"+index]*Ds["D0"] )

    return scalar_ranges

def calculate_r2dot(taus, r1, r2, r3, r2dot, flag):
    """Takes in the following parameters:
    1. dictionary holding tau values, taus
    2. all position vectors, r1, r2, and r3
    3. velocity vector of second observation, r2dot
    4. flag that's passed on to the fg function.
     Does the following:
        1. calculates f and g according to the flag
        2. calculates c1 and c3
        3. finds d1 and d3 in the equation r2dot = d1*r1 + d3*r3,
        4. returns r2dot"""

    f1, g1 = fg(taus["tau1"], r2, r2dot, flag)
    f3, g3 = fg(taus["tau3"], r2, r2dot, flag)

    d1 = -f3 / ( f1*g3 - f3*g1 )
    d3 = f1 / ( f1*g3 - f3*g1 )

    return d1*r1 + d3*r3

def get_angular_momentum(r2, r2dot):
    # find angular momentum by finding the cross product
    # of r2 and r2dot
    return cross(r2, r2dot)

def get_perihelion(ang_mom, r2_dot, r2, r2_mag):
    return -cross(ang_mom, r2_dot) - r2/r2_mag

def get_eccentricity(perihelion_vector):
    return getMag(perihelion_vector)

def get_semi_major_a(r2_dot, r2_mag):
    return 1/( (2/r2_mag) - dot(r2_dot,r2_dot))

def get_inclination(ang_mom):
    return atan( (ang_mom[0]**2 + ang_mom[1]**2)**0.5 / ang_mom[2] )

def get_ascending_node(ang_mom, ang_mom_mag, inclination):
    cos_of_AN =  -ang_mom[1] / (ang_mom_mag * sin(inclination))
    sin_of_AN = ang_mom[0] / (ang_mom_mag * sin(inclination))
    ascending_node = atan2( sin_of_AN, cos_of_AN )
    if ascending_node < 0:
        ascending_node += 2*pi
    return ascending_node

def get_arg_of_perihelion(r2, r2_mag, inclination, eccentricity, semi_major_a, ascending_node, ang_mom_mag, r2dot):
    sin_of_U = r2[2] / (r2_mag * sin(inclination))
    cos_of_U = ( r2[0]*cos(ascending_node) + r2[1]*sin(ascending_node) ) / r2_mag
    U = atan2( sin_of_U, cos_of_U )

    cos_of_mu = (1/eccentricity)*( (semi_major_a * (1 - eccentricity**2))/r2_mag -1)
    sin_of_mu = semi_major_a*(1 - eccentricity**2) / (eccentricity*ang_mom_mag) * ( dot(r2, r2dot) / r2_mag)
    mu = atan2( sin_of_mu, cos_of_mu )

    if U-mu < 0:
        return U - mu + 2*pi
    return U - mu

def getMeanAnomaly(eccentricity, r2_mag, semi_major_a):
    eccen_anom =  (1/eccentricity) * (1 - r2_mag/semi_major_a)
    eccen_anom = acos(eccen_anom)
    eccen_anom = atan2(sin(eccen_anom), cos(eccen_anom))
    mean_anom = eccen_anom - eccentricity*sin(eccen_anom)
    return mean_anom

def calculate_percent_diff(expected, calculated):
    return (expected-calculated)/expected*100

def display_results(eccentricity, semi_major_a, inclination, ascending_node, arg_of_perihelion, mean_anom):
    elements = ["eccentricity", "semi-major axis", "inclination", "ascending node", "argument of perihelion", "mean anomaly"]
    expectedVals = [3.442331151611204E-01, 1.056800057440451E+00, radians(2.515524946767665E+01),
                    radians(2.362379850093818E+02), radians(2.555046043539150E+02), radians(1.404194630208429E+02)]
    calculatedVals = [eccentricity, semi_major_a, inclination, ascending_node, arg_of_perihelion, mean_anom]
    for elem in range(6):
        print("*"*60)
        print(elements[elem])
        print("expected value:", expectedVals[elem])
        print("calculated value:", calculatedVals[elem] )
        print("percent difference:", calculate_percent_diff(expectedVals[elem], calculatedVals[elem]))

def get_orbital_elements(r2, r2_dot):
    """Given the position and velocity vectors, the following occurs:
    1. The magnitudes and unit vectors or the position and velocity
       velocity vectors are calculated.
    2. The angular momentum is determined.
    3. orbital elements are determined in the following order:
        eccentricity, semi-major axis, inclination, ascending node,
        argument of perihelion, and mean anomaly"""

    # position vector data
    r2_mag = getMag(r2)
    radius_unitV = r2/r2_mag

    # velocity vector data
    velocity_mag = getMag(r2_dot)
    velocity_unitV = r2_dot/velocity_mag

    # angular momentum data
    ang_mom = get_angular_momentum(r2, r2_dot)
    ang_mom_mag = getMag(ang_mom)

    perihelion_vector = get_perihelion(ang_mom, r2_dot, r2, r2_mag)

    # 6 orbital elements
    eccentricity = get_eccentricity(perihelion_vector)

    semi_major_a = get_semi_major_a(r2_dot, r2_mag)

    inclination = get_inclination(ang_mom)

    ascending_node = get_ascending_node(ang_mom, ang_mom_mag, inclination)

    arg_of_perihelion = get_arg_of_perihelion(r2, r2_mag, inclination, eccentricity, \
        semi_major_a, ascending_node, ang_mom_mag, r2_dot)

    meanAnomaly = getMeanAnomaly(eccentricity, r2_mag, semi_major_a)

    # display_results(eccentricity, semi_major_a, inclination, ascending_node, arg_of_perihelion, meanAnomaly)
    return eccentricity, semi_major_a, inclination, ascending_node, arg_of_perihelion, meanAnomaly

def calculate_new_taus(k, times, scalar_ranges, c):
    """Takes in the following:
    1. k, Gaussian gravitational constant
    2. list holding Julian days, in order
    3. dictionary holding scalar ranges
    4. speed of light in AU per mean solar day
    Adjusts for the time it takes light to travel, and returns a dictionary"""

    ctime1 = times[0] - scalar_ranges[1]/c
    ctime2 = times[1] - scalar_ranges[2]/c
    ctime3 = times[2] - scalar_ranges[3]/c

    return calculate_taus(k, ctime1, ctime2, ctime3)

def equatorialToEcliptic(obliquity, vector):
    obliquity_matrix = array([
		[1,              0,               0],
		[0, cos(obliquity), -sin(obliquity)],
		[0, sin(obliquity),  cos(obliquity)]
    ])
    return dot(linalg.inv(obliquity_matrix), vector)

def get_valid_number(Min, Max, already_chosen, prompt_message,
range_error_message = "That is not an option. Try again.",
invalid_input_message = "You entered invalid input. Try again."):
    """Takes in the following parameters:
    1. An inclusive range described by its maximum and minimum values, Min and Max
    2. Message to prompt the user to enter

    Optional Parameters:
    3. A message to show when the number entered is not in the range described by Min and Max
    4. A message to show when the user enter invalid input, such as a letter

    The function then checks if the number given is withing the range, an actual number,
    and if it has not already been chosen.
    Returns valid number"""

    while True:
        try:
            number = int(input(prompt_message))
            if number >= Min and number <= Max:
                return number
            if number in already_chosen:
                print("This number has already been chosen. Try again.")
            else:
                print(range_error_message)
                continue
        except:
            print(invalid_input_message)

def ephemeris_generator_1(r2, r2dot, t, obliquity, sun_vector):
    time_of_perihelion = 2457852.08061

    # calculate orbital elements
    eccentricity, semi_major_a, inclination, ascending_node, arg_of_perihelion, init_mean_anom = get_orbital_elements(r2, r2dot)

    # calculate mean anomaly at ephemeris generation time
    mean_anom = calculate_mean_anom(t, time_of_perihelion, semi_major_a)

    # find eccentric anomaly
    # passed on init_mean_anom because there is no change in mean anomaly
    eccen_anom = newtons_method(f, f_prime, mean_anom, 1E-12, [eccentricity, 0])

    position_vector = getCartesianCoords(semi_major_a, eccen_anom, eccentricity)

    position_vector = spinVector(ascending_node, inclination, arg_of_perihelion, position_vector)

    position_vector = ecliptic_to_equatorial(obliquity, position_vector)

    range_vector = position_vector + sun_vector
    rhohat = range_vector / getMag(range_vector)

    RA, DEC = getRAandDEC(rhohat)

    return RA, DEC

def ephemeris_generator_2(components, t, obliquity, sun_vector):
    time_of_perihelion = 2457852.08061

    # calculate orbital elements
    eccentricity, semi_major_a, inclination, \
        ascending_node, arg_of_perihelion, init_mean_anom = get_orbital_elements(components[:3], components[3:])

    # calculate mean anomaly at ephemeris generation time
    mean_anom = calculate_mean_anom(JDays, time_of_perihelion, semi_major_a)

    # find eccentric anomaly
    eccen_anom = newtons_method(f, f_prime, mean_anom, 1E-12, [eccentricity, 0])

    position_vector = getCartesianCoords(semi_major_a, eccen_anom, eccentricity)

    position_vector = spinVector(ascending_node, inclination, arg_of_perihelion, position_vector)

    position_vector = ecliptic_to_equatorial(obliquity, position_vector)

    range_vector = position_vector + sun_vector
    rhohat = range_vector / getMag(range_vector)

    RA, DEC = getRAandDEC(rhohat)

    return RA, DEC

def getRAandDEC(rhohat):
    DEC = asin(rhohat[2])
    RA = atan2( rhohat[1] / cos(DEC), rhohat[0] / cos(DEC) )

    if RA < 0:
        RA += 2*pi

    return RA, DEC

def calculate_mean_anom(JDays, time_of_perihelion, semi_major_a, mean_anom = 0):
    n = k*sqrt(1 / semi_major_a**3)
    return n * (JDays - time_of_perihelion)

def f(x, eccen, mean_anom):
    return x - eccen * sin(x) - mean_anom

def f_prime(x, eccen, mean_anom):
    return 1 - eccen * cos(x)

def getCartesianCoords(semi_major_a, eccen_anom, eccen):
    """Takes in semi-major axis, eccentric anomaly, and eccentricity
       and returns the Cartesian coordinates of the position vector"""
    x = semi_major_a * cos(eccen_anom) - semi_major_a * eccen
    y = semi_major_a * sqrt(1 - eccen**2) * sin(eccen_anom)
    z = 0
    arr = array([x, y, z])
    return arr

def spinVector(ascending_node, inclination, perihelion, vector):
    ascending_node_matrix = array([
        [cos(ascending_node), -sin(ascending_node), 0],
        [sin(ascending_node),  cos(ascending_node), 0],
        [                  0,                    0, 1]
    ])

    inclination_matrix = array([
        [1,                0,                 0],
        [0, cos(inclination), -sin(inclination)],
        [0, sin(inclination),  cos(inclination)]
    ])

    perihelion_matrix = array([
		[cos(perihelion), -sin(perihelion), 0],
        [sin(perihelion),  cos(perihelion), 0],
        [              0,                0, 1]
    ])
    newVector = dot( perihelion_matrix, vector )
    newVector = dot( inclination_matrix, newVector)
    newVector = dot(ascending_node_matrix, newVector)
    return newVector

def ecliptic_to_equatorial(obliquity, vector):
    obliquity_matrix = array([
		[1,              0,               0],
		[0, cos(obliquity), -sin(obliquity)],
		[0, sin(obliquity),  cos(obliquity)]
    ])
    return dot(obliquity_matrix, vector)

def calculate_partial_derivatives(RA, DEC, delta, r2, r2dot, t, obliquity, sun_vector, file):
    """Calculates all partial derivatives for an observation"""
    components = [*r2, *r2dot]
    names = [
        "x",
        "y",
        "z",
        "xdot",
        "ydot",
        "zdot"
    ]

    pds_RA = {}
    pds_DEC = {}
    for i in range(6):
        file.write('PARTIAL DERIVATIVES FOR ' + names[i] + "\n")

        components[i] = components[i] * (1+delta)
        file.write(names[i] + " plus " + str(components[i]) + "\n")

        var_plus_RA, var_plus_DEC = ephemeris_generator_2( components, t, obliquity, sun_vector )
        file.write("RA-Plus " + str(var_plus_RA) + "\n")
        file.write("DEC-Plus " + str(var_plus_DEC) + "\n")

        components[i] = components[i] / (1+delta) # back to normal

        components[i] = components[i] * (1-delta)
        file.write(names[i] + " minus " + str(components[i]) + "\n")

        var_minus_RA, var_minus_DEC = ephemeris_generator_2( components, t, obliquity, sun_vector )
        file.write("RA-Minus " + str(var_minus_RA) + "\n")
        file.write("DEC-Minus " + str(var_minus_DEC) + "\n")

        components[i] = components[i] / (1-delta) # back to normal

        # find partial derivative for the current variable
        pd_RA = (var_plus_RA - var_minus_RA) / (delta * 2 * components[i])
        file.write("Partial derivative RA" + str(pd_RA) + "\n")

        pd_DEC = (var_plus_DEC - var_minus_DEC) / (delta * 2 * components[i])
        file.write("Partial derivative DEC" + str(pd_DEC) + "\n")

        pds_RA[ names[i] ] = pd_RA
        pds_DEC[ names[i] ] = pd_DEC

        file.write("*"*60 + "\n")
    return pds_RA, pds_DEC

def write_dict(file, Dict, dict_name, dline = True):
    """Function that takes in dictionary and file name and prints
    all values in the dictionary on separate lines in the file"""
    file.write(dict_name + "\n")
    for key, value in Dict.items():
        file.write(str(key) + ": ")
        file.write(str(value) + "\n")
    if dline:
        file.write("*"*60 + "\n")

def civil_date_to_julian_day(Y, M, D, UT):
    JDay = (367*Y)
    JDay -= int( (7 * ( Y + int( (M+9) /12 )))/4)
    JDay += int(275 * M /9)
    JDay += D
    JDay += 1721013.5
    JDay += (UT/24)
    return JDay


import streamlit as st
import pickle
import numpy as np

pickle_in=open("model.pkl","rb")
model=pickle.load(pickle_in)
def predict(house_age,distance_to_nearest_metro,no_of_nearby_stores):
    List=[house_age,distance_to_nearest_metro,no_of_nearby_stores]
    array=np.array(List,np.float64)
    prediction=model.predict([array])
    return prediction
def main():
    st.title("HOUSE_PRICE-PREDICTION")

    template = """

 HOUSE PRICE-PREDICTION

      """
    st.markdown(template,unsafe_allow_html=True)

    house_age=st.text_input("Houseage","enter your house age")
    distance_to_nearest_metro=st.text_input("Distance to nearest metro","enter your nearest metro distance")
    no_of_nearby_stores=st.text_input("No of nearby stores","enter no.of nearby stores")
    result=" "
    if st.button("predict"):
        result=(predict(house_age,distance_to_nearest_metro,no_of_nearby_stores))
    st.success("the house predicted value is {}".format(result))

if __name__=="__main__":
    main()


'''
功能：
读取MNIST数据集并转换为numpy向量，每个numpy向量的元素代表一个图片向量或一个标签值
引用数据集链接：
http://yann.lecun.com/exdb/mnist/
引用代码链接：
https://blog.csdn.net/eleclike/article/details/79968574
'''

import numpy as np
import os

IMAGE_ROW = 28
IMAGE_COL = 28
IMAGE_SIZE = 28*28

def readHead(filename):
	dimension = []
	with open(filename,'rb') as pf:
		#获取magic number
		data = pf.read(4)#读出第1个4字节
		magic_num = int.from_bytes(data,byteorder='big')#bytes数据大尾端模式转换为int型

		#获取dimension的长度，由magic number的最后一个字节确定
		dimension_cnt = magic_num & 0xff

		#获取dimension数据，
		#dimension[0]表示图片的个数,如果是3维数据,dimension[1][2]分别表示其行/列数值
		for i in range(dimension_cnt):
			data = pf.read(4)
			dms = int.from_bytes(data,byteorder='big')
			dimension.append(dms)
	#print(dimension)
	return dimension

def getHeadLength(dimension):
	return 4*len(dimension)+4

def readImage(filename,head_len,offset):
	image = np.zeros((IMAGE_ROW,IMAGE_COL),dtype=np.uint8)#创建一个28x28的array，数据类型为uint8

	with open(filename,'rb') as pf:
		#magic_num的长度为4，dimension_cnt单个长度为4,前面的number个长度为28*28*offset
		pf.seek(head_len+IMAGE_SIZE*offset)

		for row in range(IMAGE_ROW):#处理28行数据，
			for col in range(IMAGE_COL):#处理28列数据
				data = pf.read(1)#单个字节读出数据
				pix = int.from_bytes(data,byteorder='big')#由byte转换为int类型，
				#简单滤波，如果该位置的数值大于指定值，则表示该像素为1.因为array已经初始化为0了，如果小于该指定值，不需要变化
				if pix >10:image[row][col] = 1
		#print(image)

	return image

def readLabel(filename,head_len,offset):
	label = None

	with open(filename,'rb') as pf:
		#pf 指向label的第number个数据,magic_num的长度为4，dimension_cnt单个长度为4
		pf.seek(head_len+offset)
		data = pf.read(1)
		label = int.from_bytes(data,byteorder='big')#由byte转换为int类型，
	return label

def getSampleCount(dimension):
	return dimension[0]

def readImageVector(filename,head_len,offset,amount):
	image_mat=np.zeros((amount,IMAGE_SIZE),dtype=np.uint8)

	with open(filename,'rb') as pf:
		#magic_num的长度为4，dimension_cnt单个长度为4,前面的number个长度为28*28*offset
		pf.seek(head_len+IMAGE_SIZE*offset)

		for ind in range(amount):
			image = np.zeros((1,IMAGE_SIZE),dtype=np.uint8)#创建一个1，28x28的array，数据类型为uint8
			for row in range(IMAGE_SIZE):#处理28行数据，
				data = pf.read(1)#单个读出数据
				pix = int.from_bytes(data,byteorder='big')#由byte转换为int类型，
				#简单滤波，如果该位置的数值大于指定值，则表示该像素为1.因为array已经初始化为0了，如果小于该指定值，不需要变化
				if pix >10:image[0][row] = 1
			image_mat[ind,:]=image
			print('readImageVector：当前进度%0.2f%%'%(ind*100.0/amount),end='\r')
		print()
		#print(image)

	return image_mat

def readLabelVector(filename,head_len,offset,amount):
	label_list=[]

	with open(filename,'rb') as pf:
		#pf 指向label的第number个数据,magic_num的长度为4，dimension_cnt单个长度为4
		pf.seek(head_len+offset)

		for ind in range(amount):
			data = pf.read(1)
			label = int.from_bytes(data,byteorder='big')#由byte转换为int类型，
			label_list.append(label)
			print('readLabelVector：当前进度%0.2f%%'%(ind*100.0/amount),end='\r')
		print()

	return label_list

def readImageLabelVector(image_file,label_file,offset,amount):

	image_dim = readHead(image_file)
	label_dim = readHead(label_file)

	#判断样本中的image和label是否一致
	image_amount = getSampleCount(image_dim)
	label_amount = getSampleCount(label_dim)
	if image_amount != label_amount:
		print('Error:训练集image和label数量不相等')
		return None

	if offset+amount > image_amount:
		print('Error:请求的数据超出样本数量')
		return None

	#获取样本image和label的头文件长度
	image_head_len = getHeadLength(image_dim)
	label_head_len = getHeadLength(label_dim)

	#得到image和label的向量
	image_mat = readImageVector(image_file,image_head_len,offset,amount)
	label_list = readLabelVector(label_file,label_head_len,offset,amount)

	return image_mat,label_list


'''
Post-processing script that computes user lifetime. Reads a stream of user/page
interactions and outputs times of first and last edit.
'''

import sys
from argparse import ArgumentParser, FileType
import numpy as np

def main(args):
    lt = {}
    for line in iter(args.input.readline, ''):
        time, user, page = map(float,line.strip().split())
        try:
            start, stop, edits = lt[user]
            lt[user] = (start, time, edits+1)
        except KeyError:
            lt[user] = (time, -1, 1)
    if len(lt) > 0:
        data = np.asarray(lt.values())
        # filter out users with less edits than min_edits
        data = data[data[:,2] >= args.min_edits]
        if args.lifetime or args.log_lifetime:
            data = np.diff(data[:,:2], axis=1)
            if args.log_lifetime:
                data = np.log(data)
        np.save(args.output_file, data)
    else:
        np.save(args.output_file, [])
    return lt

def make_parser():
    parser = ArgumentParser(fromfile_prefix_chars='@', description=__doc__)
    parser.add_argument('output_file', type=FileType('w'), help='output file '\
            '(- for standard output)', metavar='output')
    parser.add_argument('-i', '--input', type=FileType('r'), default='-',
            help='read data from %(metavar)s (default: standard input).')
    parser.add_argument('-l','--lifetime', action='store_true',
            help='output user lifetime')
    parser.add_argument('-L','--log-lifetime', action='store_true',
            help='output user log-lifetime')
    parser.add_argument('-m', '--min-edits', type=int, default=2, metavar='NUM',
            help='filter out users with less edits than num (default 2)')
    return parser

def check_arguments(args):
    if args.min_edits < 0:
        raise ValueError('invalid value for min_edits (-m/--min-edits)')

if __name__ == '__main__':
    parser = make_parser()
    ns = parser.parse_args()
    check_arguments(ns)
    main(ns)


import time
import csv
from marabou_encoding import marabouEncoding
import numpy as np
import random
import argparse

# Information for noting the results in csv format
veri_info = [
    "Specification",
    "Network file",
    "Epsilon",
    "Delta",
    "Time taken",
    "Upper bound",
    "Lower bound",
    "SAT",
]
veri_dict = {i: None for i in veri_info}

def write_csv_header(csvfile):
    with open(csvfile, mode="w") as file:
        writer = csv.DictWriter(file, fieldnames=veri_info)
        writer.writeheader()

def write_line_csv(csvfile):
    with open(csvfile, mode="a") as file:
        writer = csv.DictWriter(file, fieldnames=veri_info)
        writer.writerow(veri_dict)

Timeout = 3600

def main():

    parser = argparse.ArgumentParser(description="verification")
    parser.add_argument(
        "--network",
        type=int,
        default=1,
        help="input batch size for training (default: 100)",
    )
    args = parser.parse_args()

    mean_digit = []
    with open(
        "../../TrainingData/mnist/eight_mean_pixel.txt", "r"
    ) as f:  # mean digit for eight now
        mean_digit = f.readlines()
        mean_digit = [float(i.strip("\n")) for i in mean_digit]

    # lower_bound = 0.2
    # upper_bound = 0.2
    # prop1 = ["checking-digit", 8]
    # prop2 = ["checking-confidence", 0.01, 10]
    # prop3 = ["checking-equivalence", 0.1]
    # prop4 = ["checking-fairness", 0.01, 8]
    # prop5 = ["checking-robustness", 0.01]
    # prop6 = ["checking-digit-safe-radius", lower_bound, upper_bound, mean_digit, "digit"]
    # prop7 = ["checking-autoencoder-safe-radius", lower_bound, upper_bound, mean_digit, "autoenc", 0.05]

    prop1 = ["checking-digit"]
    prop2 = ["checking-confidence"]
    prop3 = ["checking-equivalence"]
    prop4 = ["checking-digit-confidence"]
    prop5 = ["check-confidence-random-sampling"]
    prop6 = ["checking-confidence-counterexample"]
    prop = prop6
    mara = marabouEncoding()
    # network_file = "../../networks/mnist/mnist_digit_fc.onnx"  # mnist_digit_fc.onnx / mnist_confidence_fc / mnist_eq_fc / mnist_safe_region_fc / mnist_autoenc_safe_region_fc / mnist_adv_fc / mnist_fair_fc

    print("------Checking properties of DNN, specification: " + prop[0] + "-------")
    print("------Checking properties of DNN Using Marabou-------")

    # write csv header
    # csvfile = "../../validate/mnist/" + prop[0] + ".csv"

    # digit experiment
    if prop[0] == "checking-digit":
        for digit in range(10):
            # if digit == 2:
            #     continue

            csvfile = (
                "../../validate/mnist/mnist-"
                + prop[0]
                + "-exp"
                + str(args.network)
                + "-sign"
                + str(digit)
                + ".csv"
            )
            write_csv_header(csvfile)

            network_file = (
                "../../networks/mnist/mnist_digit"
                + str(digit)
                + "_exp"
                + str(args.network)
                + ".onnx"
            )
            prop.append(digit)

            veri_dict.update(
                {
                    "Specification": prop[0],
                    "Network file": network_file,
                }
            )

            # Verification procedure
            log_time = time.time()
            result = mara.checkProperties(
                prop=prop,
                networkFile=network_file,
            )

            sat = True if result == "sat" else False

            mara_time = time.time() - log_time
            print("mara time: " + str(mara_time))
            veri_dict.update(
                {
                    "Time taken": mara_time,
                    "SAT": sat,
                }
            )

            write_line_csv(csvfile)

    # confidence experiment
    # setting epsilon and delta
    elif prop[0] == "checking-confidence":

        csvfile = (
            "../../validate/mnist/mnist-"
            + prop[0]
            + "-exp"
            + str(args.network)
            + ".csv"
        )
        write_csv_header(csvfile)

        for epsilon in np.linspace(0.05, 0.14, 10):
            for delta in range(1, 21, 1):

                network_file = (
                    "../../networks/mnist/mnist_confidence_exp"
                    + str(args.network)
                    + ".onnx"
                )
                prop.append(epsilon)
                prop.append(delta)
                veri_dict.update(
                    {
                        "Specification": prop[0],
                        "Network file": network_file,
                        "Epsilon": epsilon,
                        "Delta": delta,
                    }
                )

                # Verification procedure
                log_time = time.time()
                result = mara.checkProperties(
                    prop=prop,
                    networkFile=network_file,
                )

                sat = True if result == "sat" else False

                mara_time = time.time() - log_time
                print("mara time: " + str(mara_time))
                veri_dict.update(
                    {
                        "Time taken": mara_time,
                        "SAT": sat,
                    }
                )

                write_line_csv(csvfile)

    # equivalence experiment
    # setting epsilon
    elif prop[0] == "checking-equivalence":

        csvfile = (
            "../../validate/mnist/mnist-"
            + prop[0]
            + "-exp"
            + str(args.network)
            + ".csv"
        )
        write_csv_header(csvfile)

        for epsilon in np.linspace(0.06, 0.14, 10):

            network_file = (
                "../../networks/mnist/mnist_eq_exp" + str(args.network) + ".onnx"
            )
            prop.append(epsilon)
            veri_dict.update(
                {
                    "Specification": prop[0],
                    "Network file": network_file,
                    "Epsilon": epsilon,
                }
            )

            # Verification procedure
            log_time = time.time()
            result = mara.checkProperties(
                prop=prop,
                networkFile=network_file,
            )

            print(result)
            sat = True if result == "sat" else False

            mara_time = time.time() - log_time
            print("mara time: " + str(mara_time))
            veri_dict.update(
                {
                    "Time taken": mara_time,
                    "SAT": sat,
                }
            )

            write_line_csv(csvfile)

    elif prop[0] == "checking-confidence-counterexample":

        for delta in range(1):

            network_file = (
                "../../networks/mnist/mnist_confidence_exp"
                + str(args.network)
                + ".onnx"
            )
            prop.append(delta)
            veri_dict.update(
                {
                    "Specification": prop[0],
                    "Network file": network_file,
                    "Delta": delta,
                }
            )

            # Verification procedure
            log_time = time.time()
            counterExample = mara.checkProperties(
                prop=prop,
                networkFile=network_file,
            )
            mara_time = time.time() - log_time
            print("mara time: " + str(mara_time))
            veri_dict.update(
                {
                    "Time taken": mara_time,
                }
            )

    # worst-case confidence experiment
    elif prop[0] == "checking-digit-confidence":
        epsilon = 0.02
        acc = 0.01
        for digit in range(9, 10):
            upper_bound = 10
            lower_bound = 0
            network_file = (
                "../../networks/mnist/mnist_" + str(digit) + "_10_digit_fc.onnx"
            )
            veri_dict.update(
                {
                    "Specification": prop[0],
                    "Network file": network_file,
                }
            )
            prop.append(digit)
            time_for_one_digit = time.time()

            while upper_bound - lower_bound > acc:
                mid = (upper_bound + lower_bound) / 2
                prop.append(mid)

                # Verification procedure
                log_time = time.time()
                result = mara.checkProperties(
                    prop=prop,
                    networkFile=network_file,
                )
                mara_time = time.time() - log_time
                print("mara time: " + str(mara_time))

                sat = True if result == "sat" else False

                veri_dict.update(
                    {
                        "Time taken": mara_time,
                        "Delta": mid,
                        "Upper bound": upper_bound,
                        "Lower bound": lower_bound,
                        "SAT": sat,
                    }
                )

                if result == "sat":
                    upper_bound = mid + epsilon
                else:
                    lower_bound = mid - epsilon
                write_line_csv(csvfile)

                prop.pop()
                if time.time() - time_for_one_digit > Timeout:
                    break
            prop.pop()
            break

    # random sampling
    elif prop[0] == "check-confidence-random-sampling":
        upper_bound = 10
        lower_bound = 0
        for digit in range(9, 10):
            time_for_one_digit = time.time()
            digit_upper = upper_bound
            digit_lower = lower_bound

            network_file = (
                "../../networks/mnist/mnist_" + str(digit) + "_10_digit_fc.onnx"
            )
            veri_dict.update(
                {
                    "Specification": prop[0],
                    "Network file": network_file,
                }
            )
            prop.append(digit)

            while True:
                curr_point = random.uniform(lower_bound, upper_bound)
                prop.append(curr_point)

                log_time = time.time()
                result = mara.checkProperties(
                    prop=prop,
                    networkFile=network_file,
                )
                mara_time = time.time() - log_time

                if (
                    result == "sat"
                    and curr_point < digit_upper
                    and curr_point > digit_lower
                ):
                    digit_upper = curr_point
                elif (
                    result == "unsat"
                    and curr_point > digit_lower
                    and curr_point < digit_upper
                ):
                    digit_lower = curr_point

                sat = True if result == "sat" else False

                veri_dict.update(
                    {
                        "Time taken": mara_time,
                        "Delta": curr_point,
                        "Upper bound": digit_upper,
                        "Lower bound": digit_lower,
                        "SAT": sat,
                    }
                )
                write_line_csv(csvfile)

                prop.pop()
                if time.time() - time_for_one_digit > Timeout:
                    break
            prop.pop()
            break

if __name__ == "__main__":
    main()


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

from __future__ import print_function
import sys
from copy import deepcopy
from interval import interval
from .interval_utils import width
from .contractor import Contractor
from .contractor_hull import HC4
from .contractor_newton import NewtonUni
from .contractor_box import BC3

def extract_stack(b_list):
    return b_list.pop()

def extract_queue(b_list):
    return b_list.popleft()

def extract_sorted(b_lise):
    pass

def select_bb(eps, box, vs, context):
    if 'last' not in context:
        context['last'] = 0
    else:
        context['last'] += 1
        context['last'] %= len(vs)

    if 'sp' not in context:
        context['sp'] = context['last']
    elif context['sp'] == context['last']:
        del context['sp']
        return None

    vn = vs[context['last']]
    if width(box[vn]) <= eps:
        return select_bb(eps, box, vs, context)
    else:
        del context['sp']
        return vn

def select_largest(eps, box, vs, context):
    pass

class Solver:
    '''Branch-and-prune solver.
    '''

    def __init__(self, vs, dag, cs,
            eps=1e-12,
            ext_fun=extract_stack, sel_fun=select_bb):
        self.__vs = vs
        self.__dag = dag
        self.__cs = cs
        self.__eps = eps
        self.__extract = ext_fun
        self.__select_var = sel_fun

    def __contract(self, box):
        for c in self.__cs:
            if c[0] != 'Switch':
                for i in range(len(self.__vs)):
                    bc = BC3(self.__dag, c, self.__vs[i], i)
                    bc.contract(box)

        #print('after BC3:')
        #print(box)
        #print()

        if box.is_empty():
            return

        #for c in self.__cs:
        #    hc = HC4(self.__dag, c)
        #    hc.contract(box)

        #print('after HC4:')
        #print(box)
        #print()

    def __split(self, v, box):
        i = box[v]
        b1 = box
        b1[v] = interval[i[0].inf, i.midpoint]
        b2 = deepcopy(box)
        b2[v] = interval[i.midpoint, i[0].sup]
        return b1, b2

    def __append(self, b_list, elem):
        b_list.append(elem)

    def solve(self, box):

        solutions = []
        undecided = [(box,{})]

        while (len(undecided) > 0):
            box,ctx = self.__extract(undecided)

            self.__contract(box)

            # ask and contract
            for c in self.__cs:
                if c[0] == 'Switch':
                    b_tmp = deepcopy(box)

                    #print('Switch contract')
                    #print(b_tmp)

                    res = Contractor.UNKNOWN
                    for i in range(len(self.__vs)):
                        bc = BC3(self.__dag, c[2], self.__vs[i], i)
                        res = bc.contract(b_tmp)
                        if not res is Contractor.UNKNOWN:
                            break
                    if res is Contractor.PROVED:
                        for i in range(len(self.__vs)):
                            bc = BC3(self.__dag, ('=',c[1],c[3]), self.__vs[i], i)
                            bc.contract(box)
                    elif res is Contractor.NO_SOL:
                        for i in range(len(self.__vs)):
                            bc = BC3(self.__dag, ('=',c[1],c[4]), self.__vs[i], i)
                            bc.contract(box)

            v = self.__select_var(self.__eps, box, self.__vs, ctx)

            if (v is None):
                if (not box.is_empty()):
                    solutions.append(box)
            else:
                b1,b2 = self.__split(v, box)
                self.__append(undecided, (b1,ctx))
                self.__append(undecided, (b2,deepcopy(ctx)))

        return solutions


import numpy as np
import matplotlib.pyplot as plt
import matplotlib.cm as cm
import IPython
import IPython
import os
cwd = os.getcwd()
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'
from sklearn.preprocessing import LabelEncoder
from sklearn.preprocessing import OneHotEncoder
import tensorflow as tf
from sklearn.utils import shuffle
from tensorflow.contrib.learn.python.learn.datasets.mnist import read_data_sets
from sklearn.model_selection import train_test_split
from tensorflow.contrib.layers import flatten
import pickle

def low_rank_k(u, s, vh, num):
	# function for low rank approximation

	u = u[:,:num]
	vh = vh[:num,:]
	s = s[:num]
	s = np.diag(s)
	low_rank1 = np.dot(u, s)
	low_rank2 = vh
	return low_rank1, low_rank2

def decimal_str(x: float, decimals: int = 10) -> str:
	return format(x, f".{decimals}f").lstrip().rstrip('0')

def get_compression_accuracy(x, y, conv1_w, conv1_b, conv2_w ,conv2_b, fc1_w, fc1_b, fc2_w, fc2_b, fc3_w, fc3_b):
	conv1 = tf.nn.conv2d(x,conv1_w, strides = [1,1,1,1], padding = 'VALID') + conv1_b
	# TODO: Activation.
	conv1 = tf.nn.relu(conv1)
	# Pooling Layer. Input = 28x28x1. Output = 14x14x6.
	pool_1 = tf.nn.max_pool(conv1, ksize = [1,2,2,1], strides = [1,2,2,1], padding = 'VALID')
	# TODO: Layer 2: Convolutional. Output = 10x10x16.
	conv2 = tf.nn.conv2d(pool_1, conv2_w, strides = [1,1,1,1], padding = 'VALID') + conv2_b
	# TODO: Activation.
	conv2 = tf.nn.relu(conv2)# TODO: Pooling. Input = 10x10x16. Output = 5x5x16.
	pool_2 = tf.nn.max_pool(conv2, ksize = [1,2,2,1], strides = [1,2,2,1], padding = 'VALID')
	# TODO: Flatten. Input = 5x5x16. Output = 400.
	fc1 = flatten(pool_2)
	# TODO: Layer 3: Fully Connected. Input = 400. Output = 120.
	fc1 = tf.matmul(fc1,fc1_w) + fc1_b
	# TODO: Activation.
	fc1 = tf.nn.relu(fc1)
	# TODO: Layer 4: Fully Connected. Input = 120. Output = 84.
	fc2 = tf.matmul(fc1, fc2_w) + fc2_b
	# TODO: Activation.
	fc2 = tf.nn.relu(fc2)
	# TODO: Layer 5: Fully Connected. Input = 84. Output = 10.
	#IPython.embed()
	logits = tf.matmul(tf.cast(fc2, tf.float32), fc3_w) + fc3_b

	correct_prediction = tf.equal(tf.argmax(logits,1), tf.argmax(y,1))
	accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))# Evaluate function
	sess = tf.Session()
	return sess.run(accuracy)

def fine_tune(N, eps, epochs, rank1, rank2):

	x = tf.placeholder(tf.float32, shape=[None,32,32,1])
	y_ = tf.placeholder(tf.int32, (None))

	conv1_w = np.loadtxt('data/conv1_w', delimiter=',').reshape([5,5,1,6])
	conv1_b = np.loadtxt('data/conv1_b',  delimiter=',')
	conv2_w = np.loadtxt('data/conv2_w', delimiter=',').reshape([5,5,6,16])
	conv2_b = np.loadtxt('data/conv2_b', delimiter=',')
	fc1_w = np.loadtxt('data/fc1_w', delimiter=',')
	fc1_b = np.loadtxt('data/fc1_b', delimiter=',')
	fc2_w = np.loadtxt('data/fc2_w', delimiter=',')
	fc2_b = np.loadtxt('data/fc2_b', delimiter=',')
	fc3_w = np.loadtxt('data/fc3_w', dtype = np.float32, delimiter=',')
	fc3_b = np.loadtxt('data/fc3_b', dtype = np.float32, delimiter=',')
	Y_in = np.loadtxt('data/Y_in', delimiter=',')
	Y_out = np.loadtxt('data/Y_out', delimiter=',')
	train_x = np.loadtxt('data/train_x', delimiter=',').reshape([33600, 32, 32, 1])
	test_x = np.loadtxt('data/test_x', delimiter=',').reshape([8400, 32, 32, 1])
	train_y = np.loadtxt('data/train_labels', delimiter=',')
	test_y = np.loadtxt('data/test_labels', delimiter=',')

	# tf Graph input
	x = tf.placeholder(tf.float32, shape=[None,32,32,1])
	y_ = tf.placeholder(tf.int32, (None))
	## =================================================================
	## =================================================================
	# laod notes for compression

	file_name_1 = 'Lenet_layer1_Constr_Low_Rank_N_' + str(N) + '_Eps_' + str(decimal_str(eps)).replace('.', '')
	file_name_2 = 'Lenet_2nd_layer_Constr_Low_Rank_N_' + str(N) + '_Eps_' + str(decimal_str(eps)).replace('.', '')
	# load first layer
	weight_lr1 = np.loadtxt('data/'+ file_name_1 + '.txt', delimiter=',')
	weight_lr2 = np.loadtxt('data/'+ file_name_2 + '.txt', delimiter=',')

	u, s, vh = np.linalg.svd(weight_lr1, full_matrices = False)
	W_lr_to_tune_1_1, W_lr_to_tune_1_2 = low_rank_k(u, s, vh, rank1)

	u, s, vh = np.linalg.svd(weight_lr2, full_matrices = False)
	W_lr_to_tune_2_1, W_lr_to_tune_2_2 = low_rank_k(u, s, vh, rank2)
	# Initialize the variables (i.e. assign their default value)
	## Initiliaze Layer Weights
	# Store layers weight & bias
	weights = {
		'h1_1': tf.Variable(W_lr_to_tune_1_1, dtype=tf.float32),
		'h1_2': tf.Variable(W_lr_to_tune_1_2, dtype=tf.float32),
		'h2_1': tf.Variable(W_lr_to_tune_2_1, dtype=tf.float32),
		'h2_2': tf.Variable(W_lr_to_tune_2_2, dtype=tf.float32)
	}
	## =================================================================
	## =================================================================
	## Create model
	def neural_net(x, conv1_w, conv1_b, conv2_w ,conv2_b, fc1_w, fc1_b, fc2_w, fc2_b, fc3_w, fc3_b):
		# Network architecture with only middle layer being a variable now
		# layer_1 = tf.nn.relu(tf.add(tf.matmul(x, Win), Bin))
		# layer_2 = tf.nn.relu(tf.add(tf.matmul(layer_1, tf.matmul(weights['h2_1'], weights['h2_2'])), Btest)) # I am using trained bias without fine tuning it
		# out_layer = tf.matmul(layer_2, Wout) + Bout
		conv1 = tf.nn.conv2d(x,conv1_w, strides = [1,1,1,1], padding = 'VALID') + conv1_b
		# TODO: Activation.
		conv1 = tf.nn.relu(conv1)
		# Pooling Layer. Input = 28x28x1. Output = 14x14x6.
		pool_1 = tf.nn.max_pool(conv1, ksize = [1,2,2,1], strides = [1,2,2,1], padding = 'VALID')
		# TODO: Layer 2: Convolutional. Output = 10x10x16.
		conv2 = tf.nn.conv2d(pool_1, conv2_w, strides = [1,1,1,1], padding = 'VALID') + conv2_b
		# TODO: Activation.
		conv2 = tf.nn.relu(conv2)# TODO: Pooling. Input = 10x10x16. Output = 5x5x16.
		pool_2 = tf.nn.max_pool(conv2, ksize = [1,2,2,1], strides = [1,2,2,1], padding = 'VALID')
		# TODO: Flatten. Input = 5x5x16. Output = 400.
		fc1 = flatten(pool_2)
		# TODO: Layer 3: Fully Connected. Input = 400. Output = 120.
		fc1 = tf.matmul(fc1, tf.matmul(weights['h1_1'], weights['h1_2'])) + fc1_b
		# TODO: Activation.
		fc1 = tf.nn.relu(fc1)
		# TODO: Layer 4: Fully Connected. Input = 120. Output = 84.
		fc2 = tf.matmul(fc1, tf.matmul(weights['h2_1'], weights['h2_2'])) + fc2_b
		# TODO: Activation.
		fc2 = tf.nn.relu(fc2)
		logits = tf.matmul(fc2, fc3_w) + fc3_b
		return logits

	# learning_rate = 0.001
	## Construct model
	logits = neural_net(x, conv1_w, conv1_b, conv2_w ,conv2_b, fc1_w, fc1_b, fc2_w, fc2_b, fc3_w, fc3_b)

	#Invoke LeNet function by passing features
	#logits,   conv1_w, conv1_b, conv2_w, conv2_b, fc1_w, fc1_b, fc2_w, fc2_b, fc3_w, fc3_b, fc1, fc2 = LeNet_5(x)#Softmax with cost function implementation
	cross_entropy = tf.nn.softmax_cross_entropy_with_logits_v2(labels = y_, logits = logits)
	loss_operation = tf.reduce_mean(cross_entropy)
	optimizer = tf.train.AdamOptimizer(learning_rate = 0.001)
	training_operation = optimizer.minimize(loss_operation)

	correct_prediction = tf.equal(tf.argmax(logits,1), tf.argmax(y_,1))
	accuracy_operation = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))# Evaluate function

	#To initialise session and run
	BATCH_SIZE = 128
	np.random.seed(3)
	#N = 200
	m, _, _, _ = train_x.shape
	ind = np.random.choice(m, N, replace=False)
	X_train = train_x[ind,:,:,:]
	y_train = train_y[ind, :]

	with tf.Session() as sess:
		sess.run(tf.global_variables_initializer())
		num_examples = len(X_train)

		print("Training... with dataset - ", num_examples)
		print()
		for i in range(epochs):
			X_train, y_train = shuffle(X_train, y_train)
			for offset in range(0, num_examples, BATCH_SIZE):
				end = offset + BATCH_SIZE
				batch_x, batch_y = X_train[offset:end], y_train[offset:end]
				sess.run(training_operation, feed_dict={x: batch_x, y_: batch_y})

		num_examples = len(test_x)
		total_accuracy = 0

		#sess = tf.get_default_session()
		for offset in range(0, num_examples, BATCH_SIZE):
			batch_x, batch_y = test_x[offset:offset+BATCH_SIZE], test_y[offset:offset+BATCH_SIZE]
			#IPython.embed()
			accuracy = sess.run(accuracy_operation, feed_dict={x: batch_x, y_: batch_y})
			total_accuracy += (accuracy * len(batch_x))

		acc_test_ft = total_accuracy / num_examples
			#validation_accuracy = evaluate(X_validation, y_validation)
			# print("EPOCH {} ...".format(i+1))
			# train_accuracy = evaluate(X_train, y_train)
			# print("Train Accuracy = {:.3f}".format(train_accuracy))
			# #print()
			# test_accuracy = evaluate(test_x, test_y)
			# print("Test Accuracy = {:.3f}".format(test_accuracy))
	# this should generate the same data samples used for constrained low rank
	#np.random.seed(3)
	#N = 200
	# m, _, _, _ = train_x.shape
	# ind = np.random.choice(m, N, replace=False)
	# test_x_N = test_x[ind,]
	# test_y_N = test_y[ind,]
	#IPython.embed()

	return acc_test_ft

res_dict = {}
# for epochs in [1, 2, 5]:
# 	print("Epoch {}".format(epochs))
for N in [200, 400, 800]:
	print("N {}".format(N))
	notes_filename_1 = 'Lenet_layer1_Constr_low_rank_N_' + str(N) + '_notes_python'
	notes_1 = np.loadtxt('data/' + notes_filename_1 + '.txt', delimiter=',')
	n_notes_1, _ = notes_1.shape
	epsilon_1 = notes_1[:, 0]
	ranks_1 = notes_1[:, 1]

	notes_filename_2 = 'Lenet_Constr_low_rank_N_' + str(N) + '_notes_python'
	notes_2 = np.loadtxt('data/' + notes_filename_2 + '.txt', delimiter=',')
	n_notes_2, _ = notes_2.shape
	epsilon_2 = notes_2[:, 0]
	ranks_2 = notes_2[:, 1]
	cnt = 0
	for eps in epsilon_1:

		# start fine tuning
		acc = fine_tune(N, eps, 0, int(ranks_1[cnt]), int(ranks_2[cnt]))
		cnt += 1
		res_dict[(N,  eps)] = acc

f = open("data/MNIST_FT_dict_no_epochs.pkl","wb")
pickle.dump(res_dict,f)
f.close()

IPython.embed()


"""some pylint test utilities
"""
from glob import glob
from os.path import join, abspath, dirname, basename, exists
from cStringIO import StringIO

from pylint.interfaces import IReporter
from pylint.reporters import BaseReporter

PREFIX = abspath(dirname(__file__))

def fix_path():
    import sys
    sys.path.insert(0, PREFIX)

import sys
MSGPREFIXES = ['2.%s_'%i for i in range(5, 2, -1) if i <= sys.version_info[1]]
MSGPREFIXES.append('')

def get_tests_info(prefix=None, suffix=None, inputdir='input', msgdir='messages'):
    pattern = '*'
    if prefix:
        pattern = prefix + pattern
    if suffix:
        pattern = pattern + suffix
    result = []
    for file in glob(join(PREFIX, inputdir, pattern)):
        infile = basename(file)
        for msgprefix in MSGPREFIXES:
            outfile = join(PREFIX, msgdir, msgprefix + infile.replace(suffix, '.txt'))
            if exists(outfile):
                break
        result.append((infile, outfile))
    return result

TITLE_UNDERLINES = ['', '=', '-', '.']

class TestReporter(BaseReporter):
    """ store plain text messages
    """

    __implements____ = IReporter

    def __init__(self):
        self.message_ids = {}
        self.reset()

    def reset(self):
        self.out = StringIO()
        self.messages = []

    def add_message(self, msg_id, location, msg):
        """manage message of different type and in the context of path """
        fpath, module, object, line = location
        self.message_ids[msg_id] = 1
        if object:
            object = ':%s' % object
        sigle = msg_id[0]
        self.messages.append('%s:%3s%s: %s' % (sigle, line, object, msg))

    def finalize(self):
        self.messages.sort()
        for msg in self.messages:
            print >>self.out, msg
        result = self.out.getvalue()
        self.reset()
        return result

    def display_results(self, layout):
        """ignore layouts"""

# # # # #  pyreverse unittest utilities  # # # # # #

import unittest
import os
import sys
from os.path import join

from logilab.astng import MANAGER

def _astng_wrapper(func, modname):
    return func(modname)

def _sorted_file(path):
    lines = [line.strip() for line in open(path).readlines()
             if (line.find('squeleton generated by ') == -1 and
                 not line.startswith('__revision__ = "$Id:'))]
    lines = [line for line in lines if line]
    lines.sort()
    return '\n'.join(lines)

def get_project(module, name=None):
    """return a astng project representation
    """
    manager = MANAGER
    # flush cache
    manager._modules_by_name = {}
    return manager.project_from_files([module], _astng_wrapper,
                                      project_name=name)

DEFAULTS = {'all_ancestors': None, 'show_associated': None,
            'module_names': None,
            'output_format': 'dot', 'diadefs_file': None, 'quiet': 0,
            'show_ancestors': None, 'classes': (), 'all_associated': None,
            'mode': 'PUB_ONLY', 'show_builtin': False, 'only_classnames': False}

class Config(object):
    """config object for tests"""
    def __init__(self):
        for attr, value in DEFAULTS.items():
            setattr(self, attr, value)

class FileTC(unittest.TestCase):
    """base test case for testing file output"""

    generated_files = ()

    def setUp(self):
        self.expected_files = [join('data', file)
                               for file in self.generated_files]

    def tearDown(self):
        for fname in self.generated_files:
            try:
                os.remove(fname)
            except:
                continue

    def _test_same_file(self, index):
        generated_file = self.generated_files[index]
        expected_file = self.expected_files[index]
        generated = _sorted_file(generated_file)
        expected = _sorted_file(expected_file)

        from difflib import unified_diff
        files = "\n *** expected : %s, generated : %s \n"  % (
            expected_file, generated_file)
        self.assertEqual(expected, generated, '%s%s' % (
            files, '\n'.join(line for line in unified_diff(
            expected.splitlines(), generated.splitlines() ))) )
        os.remove(generated_file)

def build_file_case(filetc):
    for i in range(len(filetc.generated_files)):
        setattr(filetc, 'test_same_file_%s' %i,
                lambda self, index=i: self._test_same_file(index))


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

from py3oauth2 import message
from py3oauth2.errors import (
    AccessDenied,
    ErrorException,
    InvalidRequest,
    UnauthorizedClient,
)
from py3oauth2.interfaces import IClient

__all__ = [
    'AuthorizationResponse',
    'AuthorizationRequest',
    'AccessTokenRequest'
]

class AuthorizationResponse(message.Response):
    code = message.Parameter(str, required=True)
    state = message.Parameter(str, required=message.is_state_required)

class AuthorizationRequest(message.Request):
    response = AuthorizationResponse

    response_type = message.Parameter(str, required=True,
                                      default='code', editable=False)
    client_id = message.Parameter(str, required=True)
    redirect_uri = message.Parameter(str)
    scope = message.Parameter(str)
    state = message.Parameter(str, recommended=True)

    def answer(self, provider, owner):
        client = provider.store.get_client(self.client_id)
        if not isinstance(client, IClient):
            raise UnauthorizedClient(self)

        redirect_uri = self.redirect_uri or client.get_redirect_uri()
        if not redirect_uri:
            raise InvalidRequest(self)
        elif not provider.validate_redirect_uri(client, redirect_uri):
            raise UnauthorizedClient(self)

        if not owner:
            raise AccessDenied(self, redirect_uri)

        try:
            code = provider.store.issue_authorization_code(
                client, owner, provider.normalize_scope(self.scope))
        except ErrorException as why:
            why.request = self
            raise

        response = self.response(self, redirect_uri)
        response.update({
            'code': code.get_code(),
            'state': self.state,
        })
        return response

class AccessTokenRequest(message.Request):
    response = message.AccessTokenResponse

    grant_type = message.Parameter(str, required=True,
                                   default='authorization_code',
                                   editable=False)
    code = message.Parameter(str, required=True)
    redirect_uri = message.Parameter(str)
    client_id = message.Parameter(str, required=True)

    def answer(self, provider, owner):
        authcode = provider.store.get_authorization_code(self.code)
        if authcode is None or not authcode.is_active():
            # NOTES: If an authorization code is used more than once,
            # the authorization server MUST deny the request and SHOULD
            # revoke (when possible) all tokens previously issued
            # based on that authorization code.
            raise AccessDenied(self)

        authcode.deactivate()

        client = provider.store.get_client(self.client_id)
        if not isinstance(client, IClient)\
                or not provider.authorize_client(client)\
                or client != authcode.get_client():
            raise UnauthorizedClient(self)

        try:
            token = provider.store.issue_access_token(authcode.get_client(),
                                                      authcode.get_owner(),
                                                      authcode.get_scope())
        except ErrorException as why:
            why.request = self
            raise

        response = self.response(self)
        response.update({
            'access_token': token.get_token(),
            'token_type': token.get_type(),
            'expires_in': token.get_expires_in(),
            'refresh_token': token.get_refresh_token(),
            'scope': ' '.join(token.get_scope()),
        })
        return response


import numpy as np
from tensorflow.keras.models import Sequential, Model
from tensorflow.keras.layers import Dense, SimpleRNN, LSTM, GRU, Input

#1. data
x = np.array([[1,2,3],[2,3,4],[3,4,5],[4,5,6],
            [5,6,7],[6,7,8],[7,8,9],[8,9,10],
            [9,10,11],[10,11,12],
            [20,30,40],[30,40,50],[40,50,60]])
y = np.array([4,5,6,7,8,9,10,11,12,13,50,60,70])

print(x.shape, y.shape) # (13, 3) (13,)

x = x.reshape(13, 3, 1) # (bacth_size, timesteps, feature)
x = x.reshape(x.shape[0], x.shape[1], 1)

#2. model
'''model = Sequential()
model.add(SimpleRNN(units=10, activation='relu', input_shape=(3,1)))
# model.add(GRU(units=32, activation='relu', input_shape=(3,1))) # units = output, 행무시이기때문에 (3,1)
model.add(Dense(32, activation='relu'))
model.add(Dense(16, activation='relu'))
model.add(Dense(8, activation='relu'))
model.add(Dense(4, activation='relu'))
model.add(Dense(2, activation='relu'))
model.add(Dense(1))'''

input = Input(shape=(3,1))
dense = LSTM(units=32, activation='relu')(input)
dense1 = Dense(16)(dense)
dense2 = Dense(8)(dense1)
dense3 = Dense(4)(dense2)
dense4 = Dense(2)(dense3)
output = Dense(1)(dense4)

model = Model(inputs=input, outputs=output)

model.summary()

#3. compile, fit
model.compile(loss='mse', optimizer='adam')
model.fit(x, y, epochs=100, batch_size=1)

#4. evaluate, predict
x_input = np.array([5,6,7]).reshape(1,3,1)
y_pred = model.predict(x_input)
print(y_pred)

'''
함수형 : [[7.8914647]]
'''


from tkinter import *
import time
import linecache
import tkinter as tk
import numbers
from time import strftime
from tkinter import filedialog

def valid_data():
    global Empty_flag
    global Warning_label
    global number_flag
    global number_label
    global Label_flag

    try:
        (float(R1.get()) and float(R2.get()) and float(VCC.get()))
        print(" a number")
        if(number_flag==True):
            number_label.destroy()
            #number_flag=False
        number_flag=False
    except ValueError:
        print("not a number")
        number_flag=True
        number_label = Label(text="Input Invalid:",fg="RED",font=('Helvetica',11))
        number_label.place(x=60,y=100)

def validation():
    global Empty_flag
    global Warning_label
    global Warning_flag
    global number_flag
    global number_label
    global Label_flag

    R1Value=R1.get()
    R2Value=R2.get()
    VCCValue=VCC.get()

    if (len(R1Value)==0 or len(R2Value)==0 or len(VCCValue)==0):
        print("Empty")
        Empty_flag=True
        Warning_label = Label(text="Please enter all the Values:",fg="RED",font=('Helvetica',11))
        Warning_label.place(x=60,y=100)
        Warning_flag=True

    elif(Empty_flag):
        Warning_label.destroy()
        Empty_flag=False
    else:
        Empty_flag=False
        Warning_flag=False
        if(Warning_flag):
            Warning_label.destroy()

    if(Label_flag):
         label.destroy()
         Label_flag=False

def clear():
    global Label_flag
    global number_flag

    R1.delete(0,END)
    R2.delete(0,END)
    VCC.delete(0,END)
    if(Label_flag):
        label.destroy()
        Label_flag=False
    if(number_flag):
        number_label.destroy()
        number_flag=False
    if(Warning_flag):
        Warning_label.destroy()

def save_info():
    global Label_flag
    global label
    global Empty_flag
    global Warning_label
    global Warning_flag
    global number_flag

    file = open("Values.txt","w")
    file.truncate(0)
    #file = open(r"F:\USERS\PRAKASH\PROJECTS\data"+timestr,"w")
    R1Value=R1.get()
    R2Value=R2.get()
    VCCValue=VCC.get()

    file.write(R1.get())
    file.write("\n")
    file.write(R2.get())
    file.write("\n")
    file.write(VCC.get())
    file.write("\n")
    file.close()
    validation()
    if(Warning_flag==False):
        valid_data()

    #valid_data()
    if((Empty_flag==False) and (number_flag==False) and (Warning_flag==False)):
        with open('Values.txt', 'r') as byte_reader:

            R1_value=float(byte_reader.readline()[0:7])
            print(R1_value)

            R2_value=float(byte_reader.readline()[0:7])
            print(R2_value)

            VCC_value=float(byte_reader.readline()[0:5])
            print(VCC_value)

            Vout=(VCC_value*R2_value)/(R1_value+R2_value)
            print(str(Vout)+ " Volts")
            if(Label_flag):
               label.destroy()

            if(Empty_flag==True):
                Warning_label.destroy()

            label = Label(app,text=" Vout is:"+ str(Vout)+" Volts",fg="GREEN", font=('Helvetica',15))
            label.place(x=50,y=400)
            Label_flag=True

app = Tk()

app.geometry("500x500")

app.title("APOLLO COMPUTING LABORATORIES")

#app.iconbitmap("acl.ico")

heading = Label(text="VOLTAGE DIVIDER NETWORK",font=('Helvetica',15,"bold"),fg="black",bg="cyan",width="500",height="0")
heading.pack()
timestr = time.strftime("%d.%m.%Y-%H.%M.%S")
"""
image = PhotoImage(file = "al.ico")
image_button = tk.Button(app,image=image)
image_button.place(x=0,y=0)
"""

global Label_flag
global label
global Empty_flag
global Warning_label
global number_flag
global Warning_flag

Warning_flag=False
number_flag=False
Label_flag=False
Empty_flag=False

R1 = Label(text="Enter R1 in Ohms only :",font=('Helvetica',11,"bold"))
R1.place(x=15,y=150)
R1 = Entry(textvariable=R1,width="10")
R1.place(x=200,y=150)

R2 = Label(text="Enter R2 in Ohms only :",font=('Helvetica',11,"bold"))
R2.place(x=15,y=210)
R2 = Entry(textvariable=R2,width="10")
R2.place(x=200,y=210)

VCC = Label(text="Enter VCC in Volts only :",font=('Helvetica',11,"bold"))
VCC.place(x=15,y=270)
VCC = Entry(textvariable=VCC,width="5")
VCC.place(x=200,y=270)

Note = Label(text="NOTE:",font=('Helvetica',12,"bold"))
Note.place(x=10,y=70)
Message = Label(text="Resistor values Limited to 1MEGA OHM Only :",fg="black",font=('Helvetica',12,"bold"))
Message.place(x=62,y=70)

button = Button(app,text="CALCULATE",font=('Helvetica',11,"bold"),command=save_info,width="30",height="2",bg="grey")
button.place(x=15,y=350)
clear = Button(app,text="CLEAR",font=('Helvetica',11,"bold"),command=clear,width="30",height="2",bg="grey")
clear.place(x=15,y=450)

mainloop()


import requests
import datetime
import pandas as pd

def get_winrate(address):
    """Gets the winrate of a scholar using the battlelog API"""

    try:
        response = requests.get(
            "https://game-api.axie.technology/battlelog/" + address
        ).json()

        df = pd.DataFrame(response[0]["items"])
        df = df[["winner", "created_at", "first_client_id", "second_client_id"]]

        total_wins_data = get_wins(df, address)

        # Get todays data
        today = datetime.datetime.today()
        yesterday = (datetime.datetime.today() - datetime.timedelta(days=1)).strftime(
            "%Y-%m-%d %H:%M"
        )
        today_df = df[
            (df["created_at"] > yesterday)
            & (df["created_at"] <= today.strftime("%Y-%m-%d %H:%M"))
        ]

        daily_wins_data = get_wins(today_df, address)

        # Save this in a dict that will be returned
        wins_data = {
            "Date": today.strftime("%Y-%m-%d"),
            "Weekly winrate": [total_wins_data["Winrate"]],
            "Weekly games": total_wins_data["Games_played"],
            "Daily winrate": daily_wins_data["Winrate"],
            "Daily games": daily_wins_data["Games_played"],
        }

    except Exception as e:
        print("Error with getting winrate")

        wins_data = {
            "Date": today.strftime("%Y-%m-%d"),
            "Weekly winrate": "ERROR",
            "Weekly games": "ERROR",
            "Daily winrate": "ERROR",
            "Daily games": "ERROR",
        }

    wins_df = pd.DataFrame(wins_data).set_index("Date")
    return wins_df

def get_wins(df, address):
    """Simple function to get wins"""

    wins = 0
    for index, row in df.iterrows():
        if row["first_client_id"] == address:
            if row["winner"] == 0:
                wins += 1
        else:
            if row["winner"] == 1:
                wins += 1

    return_dict = {
        "Games_played": len(df),
        "Winrate": "Unknown"
        if len(df) == 0
        else str(round(wins / len(df) * 100, 2)) + "%",
    }
    return return_dict


import torch
import torch.nn as nn
import torch.nn.functional as F
from model.HSI.SpeT import SpeTL
from model.MSI.SpaT import SpaTL
from timm.models.layers import trunc_normal_
from model.HSI.band_embed import BandEmbed
from model.MSI.patch_embed import PatchEmbed

def conv3x3(in_channels, out_channels, stride=1):
    return nn.Conv2d(in_channels, out_channels, kernel_size=3,
                     stride=stride, padding=1, bias=True)

class ResBlock(nn.Module):
    def __init__(self, in_channels, out_channels, stride=1):
        super(ResBlock, self).__init__()
        self.conv1 = conv3x3(in_channels=in_channels, out_channels=out_channels, stride=stride)
        self.relu = nn.ReLU(inplace=True)
        self.conv2 = conv3x3(in_channels=out_channels, out_channels=out_channels)

    def forward(self, x):
        x1 = x
        out = self.conv1(x1)
        out = self.relu(out)
        out = self.conv2(out)
        out = out + x
        return out

class Net(nn.Module):
    def __init__(self, args):
        super(Net, self).__init__()
        self.args = args
        # shallow feature extraction
        self.shallow1 = nn.Conv2d(args.hsi_channel + args.msi_channel, args.n_feats, 3, 1, 1)
        self.shallow2 = nn.Conv2d(args.hsi_channel + args.msi_channel, args.n_feats, 3, 1, 1)

        self.RB1 = nn.ModuleList()
        self.RB2 = nn.ModuleList()
        for i in range(self.args.hsi_res_blocks):
            self.RB1.append(ResBlock(self.args.n_feats, self.args.n_feats))
        for i in range(self.args.msi_res_blocks):
            self.RB2.append(ResBlock(self.args.n_feats, self.args.n_feats))
        self.conv_tail1 = conv3x3(self.args.n_feats, self.args.hsi_channel)
        self.conv_tail2 = conv3x3(self.args.n_feats, self.args.hsi_channel)

        # band_embedding_1
        self.band_embedding_1 = BandEmbed(args.hsi_channel, args.hsi_embed_dim)

        self.spectral_layers_1 = SpeTL(dim=args.hsi_embed_dim, heads=args.hsi_heads, num_layers=args.hsi_num_layers)
        self.norm_1 = nn.LayerNorm(args.hsi_embed_dim)
        self.band_unembed_1 = nn.Conv2d(args.hsi_embed_dim, args.hsi_channel, 1, 1)
        self.conv_1 = nn.Conv2d(args.hsi_channel, args.hsi_channel, 3, 1, 1)

        # band_embedding_2
        self.band_embedding_2 = BandEmbed(args.hsi_channel, args.hsi_embed_dim // 2)

        self.spectral_layers_2 = SpeTL(dim=args.hsi_embed_dim // 2, heads=args.hsi_heads, num_layers=args.hsi_num_layers)
        self.norm_2 = nn.LayerNorm(args.hsi_embed_dim // 2)
        self.band_unembed_2 = nn.Conv2d(args.hsi_embed_dim // 2, args.hsi_channel, 1, 1)
        self.conv_2 = nn.Conv2d(args.hsi_channel, args.hsi_channel, 3, 1, 1)

        # band_embedding_3
        self.band_embedding_3 = BandEmbed(args.hsi_channel, args.hsi_embed_dim * 2)

        self.spectral_layers_3 = SpeTL(dim=args.hsi_embed_dim * 2, heads=args.hsi_heads,num_layers=args.hsi_num_layers)
        self.norm_3 = nn.LayerNorm(args.hsi_embed_dim * 2)
        self.band_unembed_3 = nn.Conv2d(args.hsi_embed_dim * 2, args.hsi_channel, 1, 1)
        self.conv_3 = nn.Conv2d(args.hsi_channel, args.hsi_channel, 3, 1, 1)

        # patch_embedding_16
        self.patch_embedding_16 = PatchEmbed(args.hsi_channel, args.msi_embed_dim, args.patch_size)
        self.spatial_layers_16 = SpaTL(embed_dim=args.msi_embed_dim, heads=args.msi_heads, num_layers=args.msi_num_layers)
        self.norm_16 = nn.LayerNorm(args.msi_embed_dim)
        # patch_unembed
        self.patch_unembed_16 = nn.ConvTranspose2d(args.msi_embed_dim, args.hsi_channel, kernel_size=args.patch_size, stride=args.patch_size)
        self.conv_16 = nn.Conv2d(args.hsi_channel, args.hsi_channel, 3, 1, 1, bias=False)

        # patch_embedding_8
        self.patch_embedding_8 = PatchEmbed(args.hsi_channel, args.msi_embed_dim, args.patch_size // 2)
        self.spatial_layers_8 = SpaTL(embed_dim=args.msi_embed_dim, heads=args.msi_heads, num_layers=args.msi_num_layers)
        self.norm_8 = nn.LayerNorm(args.msi_embed_dim)
        # patch_unembed
        self.patch_unembed_8 = nn.ConvTranspose2d(args.msi_embed_dim, args.hsi_channel, kernel_size=args.patch_size // 2, stride=args.patch_size // 2)
        self.conv_8 = nn.Conv2d(args.hsi_channel, args.hsi_channel, 3, 1, 1, bias=False)

        # patch_embedding_32
        self.patch_embedding_32 = PatchEmbed(args.hsi_channel, args.msi_embed_dim, args.patch_size * 2)
        self.spatial_layers_32 = SpaTL(embed_dim=args.msi_embed_dim, heads=args.msi_heads, num_layers=args.msi_num_layers)
        self.norm_32 = nn.LayerNorm(args.msi_embed_dim)
        # patch_unembed
        self.patch_unembed_32 = nn.ConvTranspose2d(args.msi_embed_dim, args.hsi_channel, kernel_size=args.patch_size * 2, stride=args.patch_size * 2)
        self.conv_32 = nn.Conv2d(args.hsi_channel, args.hsi_channel, 3, 1, 1, bias=False)

        #upsample
        self.upsample = nn.Sequential(
            nn.Conv2d(args.hsi_channel, args.n_feats, 3, 1, 1),
            nn.GELU(),
            nn.Conv2d(args.n_feats, args.ratio*args.ratio*args.n_feats, 3, 1, 1),
            nn.PixelShuffle(args.ratio),
            nn.Conv2d(args.n_feats, args.hsi_channel, 3, 1, 1)
        )
        #reconstruction
        self.recon = nn.Sequential(
            nn.Conv2d(args.hsi_channel*2, args.n_feats, 3, 1, 1),
            nn.GELU(),
            nn.Conv2d(args.n_feats, args.hsi_channel, 3, 1, 1)
        )

        self.a = nn.Parameter(torch.FloatTensor(1), requires_grad=True).data.fill_(1).to(args.device)
        self.b = nn.Parameter(torch.FloatTensor(1), requires_grad=True).data.fill_(1).to(args.device)
        self.c = nn.Parameter(torch.FloatTensor(1), requires_grad=True).data.fill_(1).to(args.device)

        self.a1 = nn.Parameter(torch.FloatTensor(1), requires_grad=True).data.fill_(1).to(args.device)
        self.b1 = nn.Parameter(torch.FloatTensor(1), requires_grad=True).data.fill_(1).to(args.device)
        self.c1 = nn.Parameter(torch.FloatTensor(1), requires_grad=True).data.fill_(1).to(args.device)

        self.apply(self._init_weights)

    def _init_weights(self, m):
        if isinstance(m, nn.Linear):
            trunc_normal_(m.weight, std=.02)
            if isinstance(m, nn.Linear) and m.bias is not None:
                nn.init.constant_(m.bias, 0)
        elif isinstance(m, nn.Conv2d):
            # NOTE conv was left to pytorch default in my original init
            nn.init.xavier_normal_(m.weight)
            if m.bias is not None:
                nn.init.constant_(m.bias, 0)
        elif isinstance(m, nn.LayerNorm):
            nn.init.constant_(m.bias, 0)
            nn.init.constant_(m.weight, 1.0)

    def forward(self, y, z):
        #y: [B, C, h, w]   z :[B, c, H, W]
        #x_5: [B, C, H, W]
        y_up = F.interpolate(y, scale_factor=self.args.ratio, mode='bilinear')  #[B, C, H, W]
        z_down = F.interpolate(z, scale_factor=1 / self.args.ratio, mode='bilinear')  #[B, c, h, w]

        z_1 = self.shallow1(torch.cat((y, z_down), dim=1)) #[B, C, h, w]
        x_1 = self.shallow2(torch.cat((y_up, z), dim=1))  # [B, C, H, W]

        z1_res = z_1
        for i in range(self.args.hsi_res_blocks):
            z1_res = self.RB1[i](z1_res)
        z_1 = z_1 + z1_res
        z_1 = self.conv_tail1(z_1)

        x1_res = x_1
        for i in range(self.args.msi_res_blocks):
            x1_res = self.RB2[i](x1_res)
        x_1 = x_1 + x1_res
        x_1 = self.conv_tail2(x_1)

        embed_band_1 = self.band_embedding_1(z_1) #[B, C, h, w]
        _, C_1, h, w = embed_band_1.shape
        # position embedding
        pos_embed_hsi_1 = nn.Parameter(torch.zeros(1, C_1, h, w)).to(self.args.device)
        trunc_normal_(pos_embed_hsi_1, std=.02)
        embed_band_1 = embed_band_1 + pos_embed_hsi_1  # [B, C, h, w]

        fea_hsi_1 = self.spectral_layers_1(embed_band_1)  # [B, C, h, w]
        fea_hsi_1 = self.norm1(fea_hsi_1.permute(0, 2, 3, 1)).permute(0, 3, 1, 2) #[B, C, h, w]
        x_hsi_1 = self.band_unembed_1(fea_hsi_1) #[B, C, h, w]
        x_hsi_1 = self.conv1(x_hsi_1)  # [B, C, h, w]

        embed_band_2 = self.band_embedding_2(z_1)  # [B, C/2, h, w]
        _, C_2, _, _ = embed_band_2.shape
        # position embedding
        pos_embed_hsi_2 = nn.Parameter(torch.zeros(1, C_2, h, w)).to(self.args.device)
        trunc_normal_(pos_embed_hsi_2, std=.02)
        embed_band_2 = embed_band_2 + pos_embed_hsi_2  # [B, C/2, h, w]

        fea_hsi_2 = self.spectral_layers_2(embed_band_2)  # [B, C/2, h, w]
        fea_hsi_2 = self.norm2(fea_hsi_2.permute(0, 2, 3, 1)).permute(0, 3, 1, 2)  # [B, C/2, h, w]
        x_hsi_2 = self.band_unembed_2(fea_hsi_2)  # [B, C/2, h, w]
        x_hsi_2 = self.conv2(x_hsi_2)  # [B, C, h, w]

        embed_band_3 = self.band_embedding_3(z_1)  # [B, C*2, h, w]
        _, C_3, _, _ = embed_band_3.shape
        # position embedding
        pos_embed_hsi_3 = nn.Parameter(torch.zeros(1, C_3, h, w)).to(self.args.device)
        trunc_normal_(pos_embed_hsi_3, std=.02)
        embed_band_3 = embed_band_3 + pos_embed_hsi_3  # [B, C*2, h, w]

        fea_hsi_3 = self.spectral_layers_3(embed_band_3)  # [B, C*2, h, w]
        fea_hsi_3 = self.norm3(fea_hsi_3.permute(0, 2, 3, 1)).permute(0, 3, 1, 2)  # [B, C*2, h, w]
        x_hsi_3 = self.band_unembed_3(fea_hsi_3)  # [B, C*2, h, w]
        x_hsi_3 = self.conv3(x_hsi_3)  # [B, C, h, w]

        sum = self.a + self.b + self.c
        x_hsi = x_hsi_1 * (self.a / sum) + x_hsi_2 * (self.b / sum) + x_hsi_3 * (self.c / sum)  # [B, C, h, w]
        z_2 = z_1 + x_hsi    # [B, C, h, w]

        x_2 = self.upsample(z_2)   # [B, C, H, W]

        embed_patch_16 = self.patch_embedding(x_1)   # [B, d, H, W]
        _, d, n_h_16, n_w_16 = embed_patch_16.shape
        # position embedding
        pos_embed_msi_16 = nn.Parameter(torch.zeros(1, d, n_h_16, n_w_16)).to(self.args.device)
        trunc_normal_(pos_embed_msi_16, std=.02)
        embed_patch_16 = embed_patch_16 + pos_embed_msi_16  # [B, d, H, W]

        fea_msi_16 = self.spatial_layers_16(embed_patch_16) #[B, d, H, W]
        fea_msi_16 = self.norm_16(fea_msi_16.permute(0, 2, 3, 1)).permute(0, 3, 1, 2) #[B, d, H, W]
        x_msi_16 = self.patch_unembed(fea_msi_16) #[B, C, H, W]
        x_msi_16 = self.conv2(x_msi_16) #[B, C, H, W]

        embed_patch_8 = self.patch_embedding_8(x_1)  # [B, d, H*2, W*2]
        _, _, n_h_8, n_w_8 = embed_patch_8.shape
        # position embedding
        pos_embed_msi_8 = nn.Parameter(torch.zeros(1, d, n_h_8, n_w_8)).to(self.args.device)
        trunc_normal_(pos_embed_msi_8, std=.02)
        embed_patch_8 = embed_patch_8 + pos_embed_msi_8  # [B, d, H*2, W*2]

        fea_msi_8 = self.spatial_layers_8(embed_patch_8)  # [B, d, H*2, W*2]
        fea_msi_8 = self.norm4_8(fea_msi_8.permute(0, 2, 3, 1)).permute(0, 3, 1, 2)  # [B, d, H/patch, W/patch]
        x_msi_8 = self.patch_unembed_8(fea_msi_8)  # [B, C, H, W]
        x_msi_8 = self.conv2_8(x_msi_8)  # [B, C, H, W]

        embed_patch_32 = self.patch_embedding_32(x_1)  # [B, d, H/2, W/2]
        _, _, n_h_32, n_w_32 = embed_patch_32.shape
        # position embedding
        pos_embed_msi_32 = nn.Parameter(torch.zeros(1, d, n_h_32, n_w_32)).to(self.args.device)
        trunc_normal_(pos_embed_msi_32, std=.02)
        embed_patch_32 = embed_patch_32 + pos_embed_msi_32  # [B, d, H/2, W/2]

        fea_msi_32 = self.spatial_layers_32(embed_patch_32)  # [B, d, H/2, W/2]
        fea_msi_32 = self.norm4_32(fea_msi_32.permute(0, 2, 3, 1)).permute(0, 3, 1, 2)  # [B, d, H/2, W/2]
        x_msi_32 = self.patch_unembed_32(fea_msi_32)  # [B, C, H, W]
        x_msi_32 = self.conv2_32(x_msi_32)  # [B, C, H, W]

        sum1 = self.a1 + self.b1 + self.c1
        x_msi = x_msi_16 * (self.a1 / sum1) + x_msi_8 * (self.b1 / sum1) + x_msi_32 * (self.c1 / sum1)   # [B, C, H, W]

        x_3 = x_1 + x_msi   # [B, C, H, W]

        x_4 = torch.cat((x_2, x_3), dim=1)   # [B, C*2, H, W]

        x_5 = self.recon(x_4)   # [B, C, H, W]

        return x_5


# Uses python3
import numpy as np
import sys

def edit_distance(s, t):
    d = np.zeros([len(s) + 1, len(t) + 1], dtype = int)
    for i in range(d.shape[0]):
        d[i, 0] = i
    for j in range(d.shape[1]):
        d[0, j] = j
    for j in range(1, d.shape[1]):
        for i in range(1, d.shape[0]) :
            insertion = d[i, j -1] + 1
            deletion  = d[i - 1, j] + 1
            mismatch  = d[i - 1, j - 1] + 1
            match = d[i - 1, j - 1]
            # print(s[i - 1], t[j - 1])
            if s[i-1] != t[j - 1] :
                match  = sys.maxsize
            d[i, j] = min(insertion, deletion, mismatch, match)
    # print(d)
    #write your code here
    return d[len(s), len(t)]

if __name__ == "__main__":
    print(edit_distance(input(), input()))


import rubrik_cdm
import urllib3

urllib3.disable_warnings()

db_name = 'AdventureWorks2016'
date = '10-21-2019'
time = '3:00 PM'
sql_instance = 'MSSQLSERVER'
sql_host = 'em1-promowol-w1.rubrikdemo.com'
target_instance_name = sql_instance
target_hostname = sql_host
target_database_name = 'Demo_Export'
target_data_file_path = 'C:\\Program Files\\Microsoft SQL Server\\MSSQL13.MSSQLSERVER\\MSSQL\\DATA\\AdventureWorks2016_export'
target_log_file_path = 'C:\\Program Files\\Microsoft SQL Server\\MSSQL13.MSSQLSERVER\\MSSQL\\DATA\\AdventureWorks2016_export'
target_file_paths = [{'logicalName': 'AdventureWorks2016_Data',
                      'exportPath': 'C:\\Program Files\\Microsoft SQL Server\\MSSQL13.MSSQLSERVER\\MSSQL\\DATA\\AdventureWorks2016_export',
                      'newLogicalName': 'AdventureWorks2016_Data_export',
                      'newFilename': 'AdventureWorks2016_Data_export.mdf'},
                      {'logicalName': 'AdventureWorks2016_Log',
                      'exportPath': 'C:\\Program Files\\Microsoft SQL Server\\MSSQL13.MSSQLSERVER\\MSSQL\\DATA\\AdventureWorks2016_export',
                      'newLogicalName': 'AdventureWorks2016_Log_export',
                      'newFilename': 'AdventureWorks2016_Log_export.mdf'}]
rubrik = rubrik_cdm.Connect(enable_logging=True)

sql_export = rubrik.sql_db_export(db_name,
                                    date,
                                    time,
                                    sql_instance,
                                    sql_host,
                                    target_instance_name,
                                    target_hostname,
                                    target_database_name,
                                    target_data_file_path,
                                    target_log_file_path,
                                    target_file_paths)

print(sql_export)


#!/usr/bin/env python
import sys
from myparser import parser
from myerror import TPError

def main():
    input = get_input()

    try:
        result = parser.parse(input)
        maintype = resolve(result)
    except TPError as e:
        print(e.msg, file=sys.stderr)
        sys.exit(1)
    except Exception as e:
        raise e
        sys.exit(1)
    else:
        write_output(maintype)

def resolve(result):
    """Chequea y resuelve las dependencias internas en result"""
    deps = {}
    maintype = result[0]

    for typedef in result:
        if typedef.name in deps:
            raise TPError("Error: multiples declaraciones del tipo '%s'" % typedef.name)
        deps[typedef.name] = list(typedef.get_deps().keys())

    maybeloop = get_loop(deps, maintype.name, {})
    if maybeloop is not None:
        raise TPError(
            "Error: se encontró una referencia circular en la definición de '%s', mediante el tipo '%s'"
            % maybeloop
        )

    resolve_dict = {}

    for typedef in result[1:]:
        resolve_dict[typedef.name] = typedef.type

    maintype.resolve(resolve_dict)

    return maintype

def get_loop(graph, start, visited):
    """Verifica si graph tiene loops, empezando por start y habiendo visitado visited"""
    visited[start] = True

    if start not in graph:
        raise TPError("Error: el tipo '%s' no esta definido." % start)

    for next in graph[start]:
        if next in visited and visited[next]:
            return (start, next)

        maybeloop = get_loop(graph, next, visited.copy())
        if maybeloop is not None:
            return maybeloop

    return None

def get_input():
    """Obtiene el texto de entrada (stdin / 1er arg.)"""
    if len(sys.argv) > 1:
        with open(sys.argv[1], "r") as input:
            return input.read()
    else:
        return sys.stdin.read()

def write_output(maintype):
    """Escribe a la salida (stdout / 2do arg) un json generado del tipo"""
    json = maintype.generate_json()

    if len(sys.argv) > 2:
        with open(sys.argv[2], "w") as output:
            # limpiar el archivo
            output.write(json)
    else:
        sys.stdout.write(json)

if __name__ == "__main__":
    main()