import pymysql
import os

class Configuration:
    def __init__(self, nazwa_pliku, host, user, haslo, baza):
        self.nazwa_pliku = nazwa_pliku
        self.__create_config(host, user, haslo, baza)

    def __create_config(self, host, user, haslo, baza):

        if(not os.path.isfile('./' + self.nazwa_pliku + '.txt')):
            self.file = open(self.nazwa_pliku + ".txt", 'w')
            config_list = [host + "\n", user, "\n", haslo, "\n", baza, "\n"]
            self.file.writelines(config_list)
            self.file.close()

    def read_data(self):
        file = open(self.nazwa_pliku + '.txt', 'r')
        data = []
        for line in file.read().splitlines():
            data.append(line)
        dictionary = {}

        dictionary["host"]      = data[0]
        dictionary["user"]      = data[1]
        dictionary["password"]  = data[2]
        dictionary["baza"]      = data[3]

        return dictionary

class DBConect:
    def __init__(self, config):
        try:
            data = config.read_data()
            self.conn = pymysql.connect(data['host'], data['user'], data['password'], data['baza'], charset="utf8")
            self.entry()
            self.conn.close()

        except pymysql.MySQLError:
            print("Błędne dane połącznia")
    def entry(self):
        dec = input("Chcesz się zalogować czy utworzyć nowe konto? \nL - logowanie, \nN - nowy użytkownik, \nQ-wyjście").upper()
        if dec == "L":
            self.log()
        elif dec == "N":
            self.reg()
        elif dec == "Q":
            exit()
        else:
            print("Błędny wybór.")
            self.entry()

    def log(self):
        login = input('Podaj login')
        haslo = input('Podaj hasło')

        self.kursor = self.conn.cursor()
        self.kursor.execute("SELECT * FROM logowanie WHERE login=%s and haslo=%s", (login, haslo))
        results = self.kursor.fetchall()

        if len(results) == 1:
            print("Zalogowano poprawnie.")
            self.menu()
        else:
            print("Niepoprawny login lub hasło. Spróbuj ponownie.")
            self.log()

    def reg(self):
        login = input('Podaj login')
        self.kursor = self.conn.cursor()
        self.kursor.execute("SELECT login FROM logowanie WHERE login=%s", login)
        if self.kursor.rowcount != 0:
            print("Użytkownik", login, "już istnieje.")
            self.entry()
        else:
            haslo = input('Podaj hasło')
            self.kursor.execute("INSERT INTO logowanie (login, haslo) VALUES (%s, %s)", (login, haslo))
            print("Utworzono nowego użytkownika: ", login)
            self.conn.commit()
            self.log()

    def menu(self):
        while(True):
            dec = input("Wybierz opcję: \nP - pokaż, \nW - wprowadź, \nU - usuń, \nS - szybkie podsumowanie, \nQ - wyjście").upper()
            if dec == "P":
                self.select()
            elif (dec == "W"):
                self.insert()
            elif (dec == "U"):
                self.delete()
            elif(dec == "S"):
                self.summary()
            elif dec == "Q":
                exit()
            else:
                print("Błędny wybór.")

    def select(self):
        tabela = input("Pokaż: \nW - wydatki, \nP - przychody").upper()
        miesiac = int(input("Wpisz miesiąc:"))
        rok = int(input("Wpisz rok:"))
        widok = input("Pokaż widok: \nP - pełny, \nS - skrócony, \nSUM - tylko sumę").upper()

        if tabela == "W":
            if widok == "P":
                self.kursor.execute\
                ("SELECT * FROM wydatki WHERE month(data)=%s and year(data)=%s;", (miesiac, rok))
                result = self.kursor.fetchall()
                if self.kursor.rowcount == 0:
                    print("Brak danych do wyświetlenia.")
                else:
                    i = 1
                    for row in result:
                        print(" | %4s | | %10s | | %7.2f | | %20s | | %15s | | %5s | | %30s |" % (row[0], row[1], row[2], row[3], row[4], row[5], row[6]))
                        i = i + 1

            if widok == "S":
                self.kursor.execute\
                ("SELECT kategoria, round(sum(kwota),2) FROM wydatki WHERE month(data)=%s and year(data)=%s GROUP BY kategoria;", (miesiac, rok))
                result = self.kursor.fetchall()
                if self.kursor.rowcount == 0:
                    print("Brak danych do wyświetlenia.")
                else:
                    i = 1
                    for row in result:
                        print(" | %20s | | %10s |" % (row[0], row[1]))
                        i = i + 1

            if widok == "SUM":
                self.kursor.execute\
                ("SELECT round(sum(kwota),2) FROM wydatki WHERE month(data)=%s and year(data)=%s;", (miesiac, rok))
                result = self.kursor.fetchall()
                if self.kursor.rowcount == 0:
                    print("Brak danych do wyświetlenia.")
                else:
                    print("Wydatki w wybranym miesiącu: %7.2f zł" % result[0])

        if tabela == "P":
            if widok == "P":
                self.kursor.execute\
                ("SELECT * FROM przychody WHERE month(data)=%s and year(data)=%s;", (miesiac, rok))
                result = self.kursor.fetchall()
                if self.kursor.rowcount == 0:
                    print("Brak danych do wyświetlenia.")
                else:
                    i = 1
                    for row in result:
                        print("| %4s | | %10s | | %7.2f | | %15s | | %5s | | %30s |" % (row[0], row[1], row[2], row[3], row[4], row[5]))
                        i = i + 1

            if widok == "S":
                self.kursor.execute\
                ("SELECT kategoria, round(sum(kwota),2) FROM przychody WHERE month(data)=%s and year(data)=%s GROUP BY kategoria;",
                (miesiac, rok))
                result = self.kursor.fetchall()
                if self.kursor.rowcount == 0:
                    print("Brak danych do wyświetlenia.")
                else:
                    i = 1
                    for row in result:
                        print(" | %20s | | %10s |" % (row[0], row[1]))
                        i = i + 1

            if widok == "SUM":
                self.kursor.execute\
                ("SELECT round(sum(kwota),2) FROM przychody WHERE month(data)=%s and year(data)=%s;", (miesiac, rok))
                result = self.kursor.fetchall()
                if self.kursor.rowcount == 0:
                    print("Brak danych do wyświetlenia.")
                else:
                    print("Przychody w wybranym miesiącu: %7.2f zł" % result[0])
    def insert(self):
        tabela = input("Wprowadź: \nW - wydatki, \nP - przychody").upper()
        data = input("Wprowadź datę transakcji w formacje rrrr-mm-dd")
        kwota = input("Wprowadź kwotę")

        if tabela == "W":
            kategoria = input(
                "Wprowadź jedną z poniższych kategorii:\nŻywność, \nMieszkanie, \nPłatności, \nAuto i transport, \nZdrowie, \nHigiena, \nOdzież i obuwie, \nRozrywka, \nEdukacja, \nSpłata długów, \nInne").capitalize()
            opis = input("Wprowadź opis transkacji / miejsce zakupu")
        if tabela == "P":
            kategoria = input("Wprowadź jedną z poniższych kategorii:\nWynagrodzenie, \nPremia, \nInne").capitalize()

        kto = input("Wprowadź osobę przeprowadzającą transakcję")
        komentarz = input("Wprowadź komantarz")

        if tabela == "W":
            try:
                self.kursor.execute\
                ("INSERT INTO wydatki (data, kwota, kategoria, opis, kto, komentarz) VALUES (%s, %s, %s, %s, %s, %s)",\
                (data, kwota, kategoria, opis, kto, komentarz))
                self.conn.commit()
                print('Wprowadzono poprawnie.')
            except pymysql.MySQLError:
                print("Niepoprawne dane. Spróbuj ponownie.")
                self.insert()

        if tabela == "P":
            try:
                self.kursor.execute\
                ("INSERT INTO przychody (data, kwota, kategoria, kto, komentarz) VALUES (%s, %s, %s, %s, %s)",\
                (data, kwota, kategoria, kto, komentarz))
                self.conn.commit()
                print('Wprowadzono poprawnie.')
            except pymysql.MySQLError:
                print("Niepoprawne dane. Spróbuj ponownie.")
                self.insert()
    def delete(self):
        tabela = input("Usuń: \nW - wydatki, \nP - przychody").upper()
        ID = int(input("Wprowadź ID transakcji"))

        if tabela == "W":
            self.kursor.execute("DELETE FROM wydatki WHERE id=%s", ID)
            if self.kursor.rowcount == 0:
                print("Nie ma transakcji o takim ID.")
            else:
                dec = input("Czy na pewno usunąć? T/N").upper()
                if (dec == "T"):
                    self.conn.commit()
                    print("Usunięto poprawnie.")
                else:
                    self.conn.rollback()
                    print("Nie usunięto.")

        if tabela == "P":
            self.kursor.execute("DELETE FROM przychody WHERE id=%s", ID)
            if self.kursor.rowcount == 0:
                print("Nie ma transakcji o takim ID.")
            else:
                dec = input("Czy na pewno usunąć? T/N").upper()
                if (dec == "T"):
                    self.conn.commit()
                    print("Usunięto poprawnie.")
                else:
                    self.conn.rollback()
                    print("Nie usunięto.")

    def summary(self):
        self.kursor.execute\
        ("SELECT w.rok, w.miesiac, ifnull(p.suma_przychodow,0) AS przychody, ifnull(w.suma_wydatkow,0) AS wydatki, ((ifnull(p.suma_przychodow,0))-(ifnull(w.suma_wydatkow,0))) AS roznica FROM wydatki_mies AS w LEFT JOIN przychody_mies AS p ON w.rok = p.rok AND w.miesiac = p.miesiac GROUP BY w.rok, w.miesiac ORDER BY w.rok DESC, w.miesiac DESC;")
        result = self.kursor.fetchall()
        print(" | rok  | |miesiąc| | przychody | |  wydatki  | |  róźnica  | ")
        i = 1
        for row in result:
            print(" | %4s | | %5s | | %9.2f | | %9.2f | | %9.2f | " % (row[0], row[1], row[2], row[3], row[4]))
            i = i + 1


import socket
import sys
import time
from datetime import datetime, date
import hashlib
import numpy as np

class Block:
    def __init__(self, blocknumber, prev_hash, time_stamp, message):
        self.blocknumber = blocknumber
        self.message = message
        self.prev_hash = prev_hash
        self.time_stamp = time_stamp
        hash = str(blocknumber) + message + prev_hash + time_stamp
        self.block_hash = hashlib.sha256(hash.encode()).hexdigest()

blockchain = []
now = datetime.now()
now = now.strftime("%H:%M:%S")
today = date.today()
today =  today.strftime("%d/%m/%Y")
time_stamp = (today + " " +now)
genesis_block = Block(0, hashlib.sha256("Block-Chat".encode()).hexdigest(), time_stamp, "Secure Chat Application for Server is Live!")
blockchain.append(genesis_block)

s = socket.socket()
host = socket.gethostname()
print("Server will start on host:", host)
port = 9999
s.bind((host, port))
s.listen(3)
print('Waiting for connections')
conn, addr = s.accept()
print("Connected with", addr)
blocknumber = 1
prev_hash = genesis_block.block_hash
while 1:
    message = input("Server: ").encode()
    now = datetime.now()
    now = now.strftime("%H:%M:%S")        # Current time
    today = date.today()
    today =  today.strftime("%d/%m/%Y")   # Current date
    time_stamp = (today + " " +now)
    new_block = Block(blocknumber, prev_hash, time_stamp, message.decode("utf-8"))
    blocknumber+=1
    prev_hash = new_block.block_hash
    blockchain.append(new_block)
    blockchain_b = np.array(blockchain)
    blockchain_b.tobytes()
    conn.send(blockchain_b)
    conn.send(message)
    blockchain_b = conn.recv(20480000)
    blockchain = list(bytes(blockchain_b))
    incoming_msg = conn.recv(1024).decode()
    print("Client:", incoming_msg)


import math
import numpy as np
import networkx as nx
from collections import Counter
from sklearn.linear_model import HuberRegressor

class FeatureExtractor:

    def __init__(self, graph) -> None:
        self.G = graph

    """
    This method returns the depth of the graph.
    For the calculation we need to pass the networkx graph
    instance G and the root of the graph, G_root.
    See [1] for more information about this.
    """

    def calc_depth(self, G_root):
        depth = nx.eccentricity(self.G, v=G_root)
        return depth

    """
    This method defines the size [1] of the graph in question.
    This simply considers the total number of nodes in the given graph G.
    """

    def calc_size(self):
        return self.G.number_of_nodes()

    """
    Definition needs to be re-visited from [1]
    """

    def max_breadth(self, root, depth):

        metadata={}
        node2date = nx.get_node_attributes(self.G, 't_date')
        metadata['depth2breadth'] = {}
        done_nodes = []

        for dp in range(depth):
            current_dp = dp+1
            current_subgraph = nx.ego_graph(self.G, root, radius=current_dp)
            current_sb_nodes = current_subgraph.nodes()
            node2date = nx.get_node_attributes(current_subgraph, 't_date')
            node_dates = node2date.items()
            node_dates = [(n, d) for n, d in node_dates if n not in done_nodes]
            if len(node_dates) == 0:
                break
            current_depth_nodes = [n for n, d in node_dates]

            current_breadth = len(current_depth_nodes)
            metadata['depth2breadth'][current_dp] = current_breadth
            done_nodes = current_sb_nodes

        breadths = metadata['depth2breadth'].values()
        maxbreadth = 1 if len(breadths) == 0 else max(breadths)
        return maxbreadth

    """
    Structural Virality is the modified Wiener index defined in [4].
    It is adopted by several authors. Here, we are re-using the definition
    provided in [1]. Here, tthe graph G needs to be passed down, along with
    the size of the graph, calculated using calc_size method, defined above.
    """

    def calc_structural_viralty(self, size):
        if size == 1:
            return None  # virality is not defined for cascades of size 1,
        # Note: this is very time-consuming for larger cascades
        sv = nx.average_shortest_path_length(self.G)
        return sv

    """
    This method defines the number of strongly connected components [5, 6]
    in the given graph. This utilizes the method provided by networkx.
    """

    def no_of_strongly_connnected_components(self):
        return nx.number_strongly_connected_components(self.G)

    """
    This method provides the length of the largest strongly connected
    component [5, 6]. Using direct method provided by networkx package.
    """

    def size_of_largest_strongly_connected_component(self):
        generator_set = max(nx.strongly_connected_components(self.G), key=len)
        return len(generator_set)

    """
    This method defines the number of weakly connected components [5, 6]
    in the given graph. This utilizes the method provided by networkx.
    """

    def no_of_weakly_connnected_components(self):
        return nx.number_weakly_connected_components(self.G)

    """
    This method provides the length of the largest weakly connected
    component [5, 6]. Using direct method provided by networkx package.
    """

    def size_of_largest_weakly_connected_component(self):
        generator_set = max(nx.weakly_connected_components(self.G), key=len)
        return len(generator_set)

    """
    Compute the average clustering coefficient for the graph G.
    Utilizing method provided by networkx package.
    """

    def average_clustering_coefficient(self):
        return nx.average_clustering(self.G)

    """
    The main core is the core with the largest degree.
    A k-core is a maximal subgraph that contains nodes of degree k or more.
    main k core [5, 6] will be core with largest degree.
    """

    def main_k_core_number(self):
        return nx.k_core(self.G)

    def denity(self):
        return nx.density(self.G)

    """
    Calculates structural heterogeneity of a network. It starts by getting the
    degrees per node and then follows the calculation provided in [3].
    """

    def structural_heterogeneity(self, N):

        squared_sum = 0
        regular_sum = 0

        degree_values = dict(self.G.degree()).values()

        for item in degree_values:
            squared_sum += (item**2)
            regular_sum += item

        if N != 0 and regular_sum != 0:
            return (math.sqrt(squared_sum/N))/(regular_sum/N)
        else:
            return 0

    """
    Calculation of characteristic distance, defined in [3]. Calculating distance
    between all pairs of nodes and then plotting them against their probabilites,
    calculated as PMF. Then fitting a regression line using robust regression, Huber
    Regressor, we get the slope of the line, inverse of which is the characteristic
    distance. For more detail about the calculation, please visit [3].
    """

    def characteristic_distance(self):

        distances = []

        length = nx.all_pairs_shortest_path_length(self.G)
        pairs = dict(length)

        for n in pairs.keys():
            pair = pairs.get(n)
            for j in pair.keys():
                item = pair.get(j)
                distances.append(item)

        d6 = Pmf(distances)
        d6.normalize()
        temp_array = []

        for item in list(d6.values()):
            try:
                temp_array.append(math.log(item))
            except ValueError:
                return 0
        values = np.array(temp_array).reshape(-1, 1)
        lm = HuberRegressor()
        lm.fit(np.array(list(d6.keys())).reshape(-1, 1), values)
        a = -1 * (1/lm.coef_)
        return a[0]

    def layer_ratio(self, root_node):
        layer_1_ego_graph = nx.ego_graph(self.G, root_node, radius=1)
        layer_2_ego_graph = nx.ego_graph(self.G, root_node, radius=2)
        layer_1_nodes = layer_1_ego_graph.number_of_nodes()
        layer_2_nodes = layer_2_ego_graph.number_of_nodes()
        if layer_1_nodes != 0:
            layer_ratio = layer_2_nodes/layer_1_nodes
        else:
            layer_ratio = 0
        return layer_ratio

    def extract_features(self, root):

        depth = self.calc_depth(root)
        size = self.calc_size()
        max_breadth = self.max_breadth(root, depth)
        structural_virality = self.calc_structural_viralty(size)
        strongly_connected_comp = self.no_of_strongly_connnected_components()
        weakly_connected_comp = self.no_of_weakly_connnected_components()
        size_of_largest_weakly_connected_comp = self.size_of_largest_weakly_connected_component()
        avg_clustering_coeff = self.average_clustering_coefficient()
        # main_k_core_no = self.main_k_core_number()
        density = self.denity()
        structural_heterogeneity = self.structural_heterogeneity(size)
        characteristic_distance = self.characteristic_distance()
        layer_ratio = self.layer_ratio(root)

        return (depth, size, max_breadth, structural_virality,
        strongly_connected_comp, weakly_connected_comp,
        size_of_largest_weakly_connected_comp,
        avg_clustering_coeff,  density, layer_ratio,
        structural_heterogeneity, characteristic_distance)

class Pmf(Counter):
    """A Counter with probabilities."""

    def normalize(self):
        """Normalizes the PMF so the probabilities add to 1."""
        total = float(sum(self.values()))
        for key in self:
            self[key] /= total
            self[key] = round(self[key], 3)


#!/usr/bin/env python
# coding=utf-8
"""
文件名称：ImageWallImageNumTestCase.py
作者：ycy
版本：PPTPro
创建时间：2019/1/23 11:32
修改时间：
软件：PyCharm
"""
from script.windows.Operation import *
from script.windows.SystemDialog import SystemDiaglog
from script.windows.PPT3DTestCase.Action import Action
from script.windows.PPT3DSetting.SourcePath import SourcePath

reload(sys)
sys.setdefaultencoding('UTF-8')  # 将脚本编码格式转化未置顶的编码格式

class ImageWallImageNumTestCase(Action, Operation, SystemDiaglog):

    def test_main(self):
        '''图片墙默认图片数量'''
        self.OperationSetting()
        self.Init3DPPT()
        self.SetTag("图片墙默认图片数量", time.time())

        full_path = SourcePath.File_Image + '"BMP.bmp""GIF.gif""JPEG.jpeg""JPG.jpg""PNG.png"'
        self.OneClick("BtnInsert")
        self.OpenImageWall(full_path)

        tag = (self.__class__.__doc__ or u"测试") + "_" + self.__class__.__name__
        self.startScene(tag)

        self.WaitForElementText("TextImageCount", "5/20", 10, "图片墙图片数量异常")
        self.ListClick("ItemImageWallClose")
        self.WaitForElementText("TextImageCount", "4/20", 10, "图片墙图片数量异常")
        self.OneClick("BtnImageWallMore")
        self.OneClick("BtnAddImage")
        self.inputDlgClick("#32770", u"选择文件", [("ComboBoxEx32", 0), ("ComboBox", 0), ("Edit", 0)], full_path,
                           "Button")  # 输入路径点击打开
        self.WaitForElementText("TextImageCount", "9/20", 10, "图片墙图片数量异常")

        self.endScene(tag)
        time.sleep(1)
        self.EndTag()


from setuptools import setup, find_packages
import os

version = '1.3'

setup(name='collective.pfg.creditcardfields',
      version=version,
      description="PFG extension, to be able to use fields specific to credit cards",
      long_description=open("README.txt").read() + "\n" +
                       open(os.path.join("docs", "HISTORY.txt")).read(),
      # Get more strings from http://www.python.org/pypi?%3Aaction=list_classifiers
      classifiers=[
        "Programming Language :: Python",
        "Topic :: Software Development :: Libraries :: Python Modules",
        ],
      keywords='',
      author='Lucie Lejard',
      author_email='lucie@sixfeetup.com',
      url='http://sixfeetup.com',
      license='GPL',
      packages=find_packages(exclude=['ez_setup']),
      namespace_packages=['collective', 'collective.pfg'],
      include_package_data=True,
      zip_safe=False,
      install_requires=[
          'setuptools',
          'Products.Archetypes>=1.7.7',
          # -*- Extra requirements: -*-
      ],
      entry_points="""
      # -*- Entry points: -*-
      """,
      )


#coding:utf-8
import os
import time
import threading
import logging

from ctypes import *

from cactus.utils.filesystem import fileList
from cactus.utils.network import retry

from fsevents import Observer, Stream

class struct_timespec(Structure):
    _fields_ = [('tv_sec', c_long), ('tv_nsec', c_long)]

class struct_stat64(Structure):
    _fields_ = [
        ('st_dev', c_int32),
        ('st_mode', c_uint16),
        ('st_nlink', c_uint16),
        ('st_ino', c_uint64),
        ('st_uid', c_uint32),
        ('st_gid', c_uint32),
        ('st_rdev', c_int32),
        ('st_atimespec', struct_timespec),
        ('st_mtimespec', struct_timespec),
        ('st_ctimespec', struct_timespec),
        ('st_birthtimespec', struct_timespec),
        ('dont_care', c_uint64 * 8)
    ]

libc = CDLL('/usr/lib/libc.dylib')
stat64 = libc.stat64
stat64.argtypes = [c_char_p, POINTER(struct_stat64)]

# OS-X only function to get actual creation date
def get_creation_time(path):
    buf = struct_stat64()
    rv = stat64(path, pointer(buf))
    if rv != 0:
        raise OSError("Couldn't stat file %r" % path)
    return buf.st_birthtimespec.tv_sec

def createStream(real_path, link_path, callback):

    def cb(event):

        if not os.path.isdir(link_path):
            event.name = link_path
        else:
            translated_path = os.path.join(link_path, os.path.relpath(event.name, real_path))
            event.name = translated_path

        callback(event)

    return Stream(cb, real_path, file_events=True)

class FSEventsListener(object):
    def __init__(self, path, f, ignore = None):

        logging.info("Using FSEvents")

        self.path = path
        self.f = f
        self.ignore = ignore

        self.observer = Observer()
        self.observer.daemon = True

        self._streams = []
        self._streams.append(createStream(self.path, path, self._update))

        self._streamed_folders = [self.path]

        def add_stream(p):
            if p in self._streamed_folders:
                return
            self._streams.append(
                createStream(p, file_path, self._update))
            self._streamed_folders.append(p)

        # Start an extra listener for all symlinks
        for file_path in fileList(self.path, folders=True):
            if os.path.islink(file_path):
                if os.path.isdir(file_path):
                    add_stream(os.path.realpath(file_path))
                else:
                    add_stream(os.path.dirname(os.path.realpath(file_path)))

    def run(self):
        self.resume()
        self.observer.start()

    def pause(self):
        logging.debug("MacListener.PAUSE")

        for stream in self._streams:
            self.observer.unschedule(stream)

    def resume(self):
        logging.debug("MacListener.RESUME")

        for stream in self._streams:
            self.observer.schedule(stream)

    def stop():
        self.observer.stop()

    def _update(self, event):

        path = event.name

        if self.ignore and self.ignore(path):
            return

        logging.debug("MacListener.update %s", event)

        result = {
            'added': [],
            'deleted': [],
            'changed': [],
        }

        if os.path.exists(path):

            seconds_since_created = int(time.time()) - get_creation_time(os.path.realpath(path))

            if seconds_since_created < 1.0:
                result["added"].append(path)
            else:
                result["changed"].append(path)
        else:
            result["deleted"].append(path)

        self.f(result)


from typing import Tuple, Dict, List

import torch
from torch import nn

from torchvision import datasets, transforms, models

# IMAGE_SIZE = 224  # NOTE: Table 3 in the ViT paper
IMAGE_SIZE = 64  # NOTE: TinyVGG default

def create_transforms(
    image_size: int = IMAGE_SIZE,
) -> Tuple[transforms.Compose, transforms.Compose]:
    transform = transforms.Compose(
        [
            transforms.Lambda(lambda x: x.convert("RGB") if x.mode == "L" else x),
            # transforms.Grayscale(num_output_channels=3),
            transforms.Resize((image_size, image_size)),
            transforms.TrivialAugmentWide(31),
            transforms.ToTensor(),
        ]
    )
    test_transform = transforms.Compose(
        [
            transforms.Lambda(lambda x: x.convert("RGB") if x.mode == "L" else x),
            # transforms.Grayscale(num_output_channels=3),
            transforms.Resize((image_size, image_size)),
            transforms.ToTensor(),
        ]
    )
    return transform, test_transform

class LinearRegressionModel(nn.Module):
    """linear regression formula (y = m*x + b)"""

    def __init__(self):
        super().__init__()
        self.weights = nn.Parameter(
            torch.randn(
                1,
                requires_grad=True,
                dtype=torch.float,
            )
        )
        self.bias = nn.Parameter(
            torch.randn(
                1,
                requires_grad=True,
                dtype=torch.float,
            )
        )

    def forward(self, x: torch.Tensor) -> torch.Tensor:
        return self.weights * x + self.bias

class LinearRegressionModelV2(nn.Module):
    def __init__(self):
        super().__init__()
        self.linear_layer = nn.Linear(in_features=1, out_features=1)

    def forward(self, x: torch.Tensor) -> torch.Tensor:
        return self.linear_layer(x)

class LinearReLURegressor(torch.nn.Module):
    def __init__(self):
        super().__init__()
        self.layer1 = torch.nn.Linear(2, 8)
        self.layer2 = torch.nn.Linear(8, 4)
        self.layer3 = nn.LazyLinear(out_features=1)
        # self.layer3 = torch.nn.Linear(4, 1)
        self.relu = torch.nn.ReLU()

    def forward(self, x: torch.Tensor) -> torch.Tensor:
        return self.layer3(self.relu(self.layer2(self.relu(self.layer1(x)))))

class TinyVGG(nn.Module):
    """Creates the TinyVGG architecture.

    Replicates the TinyVGG architecture from the CNN explainer website in PyTorch.
    See the original architecture here: https://poloclub.github.io/cnn-explainer/

    Args:
    hidden_units_num: An integer indicating number of hidden units between layers.
    output_shape: An integer indicating number of output units.
    """

    def __init__(
        self,
        hidden_units_num: int,
        output_shape: int,
        image_size: int,
    ) -> None:
        super().__init__()
        self.image_size = image_size
        rows, cols = image_size, image_size
        self.conv_block_1 = nn.Sequential(
            nn.Conv2d(
                in_channels=3,
                out_channels=hidden_units_num,
                kernel_size=3,
                stride=1,
                padding=1,
            ),
            nn.ReLU(),
            nn.Conv2d(
                in_channels=hidden_units_num,
                out_channels=hidden_units_num,
                kernel_size=3,
                stride=1,
                padding=1,
            ),
            nn.ReLU(),
            nn.MaxPool2d(kernel_size=2, stride=2),
        )
        self.conv_block_2 = nn.Sequential(
            nn.Conv2d(
                hidden_units_num, hidden_units_num, kernel_size=3, stride=1, padding=1
            ),
            nn.ReLU(),
            nn.Conv2d(
                hidden_units_num, hidden_units_num, kernel_size=3, stride=1, padding=1
            ),
            nn.ReLU(),
            nn.MaxPool2d(2),
        )
        self.classifier = nn.Sequential(
            nn.Flatten(),
            # Where did this in_features shape come from?
            # It's because each layer of our network compresses and changes the shape of our inputs data.
            nn.Linear(
                in_features=hidden_units_num * int(rows * cols / 4 / 4),
                out_features=output_shape,
            ),
        )

    def forward(self, x: torch.Tensor):
        # x = self.conv_block_1(x)
        # x = self.conv_block_2(x)
        # x = self.classifier(x)
        # return x
        return self.classifier(
            self.conv_block_2(self.conv_block_1(x))
        )  # <- leverage the benefits of operator fusion

    @property
    def transforms(self):
        return create_transforms(
            image_size=self.image_size,
        )

class CustomViT(nn.Module):
    class PatchAndPositionEmbeddingBlock(nn.Module):
        """Turns a 2D input image into a 1D sequence learnable embedding vector.

        Args:
            patch_size (int): Size of patches to convert input image into. Defaults to 16.
            embedding_dim (int): Size of embedding to turn image into. Defaults to 768.
        """

        def __init__(
            self,
            patch_size: int = 16,
            image_size: int = 224,
            embedding_dim: int = 768,
            embedding_dropout: float = 0.1,
        ):
            super().__init__()

            assert (
                image_size % patch_size == 0
            ), f"Input image size must be divisble by patch size, image shape: {image_size}, patch size: {patch_size}"
            self.patch_num = int(image_size**2 / patch_size**2)

            self.patcher = nn.Conv2d(
                in_channels=3,
                out_channels=embedding_dim,
                kernel_size=patch_size,
                stride=patch_size,
                padding=0,
            )

            self.flatten = nn.Flatten(
                start_dim=2,  # only flatten the feature map dimensions into a single vector
                end_dim=3,
            )

            self.class_embedding = nn.Parameter(
                torch.rand(
                    1, embedding_dim
                ),  # [batch_size, number_of_tokens, embedding_dimension]
                requires_grad=True,
            )

            self.position_embedding = nn.Parameter(
                torch.rand(self.patch_num + 1, embedding_dim), requires_grad=True
            )

            self.embedding_dropout = nn.Dropout(p=embedding_dropout)

        def forward(self, x):
            # LinearProjection of FlattenedPatche
            x_patched = self.flatten(self.patcher(x)).permute(0, 2, 1)
            # Prepend class_token for each image
            x_patched_with_class_embedding = torch.cat(
                (self.class_embedding.unsqueeze(0).repeat(x.shape[0], 1, 1), x_patched),
                dim=1,
            )
            # Add position embeddings
            patch_and_position_embedding = (
                x_patched_with_class_embedding
                + self.position_embedding.unsqueeze(0).repeat(x.shape[0], 1, 1)
            )

            return self.embedding_dropout(patch_and_position_embedding)

    class TransformerEncoderBlock(nn.Module):
        class MultiheadSelfAttentionBlock(nn.Module):
            """Creates a multi-head self-attention block ("MSA block" for short)."""

            def __init__(
                self,
                embedding_dim: int = 768,  # Hidden size D from Table 1 for ViT-Base
                heads_num: int = 12,  # Heads from Table 1 for ViT-Base
                attn_dropout: float = 0,
            ):  # doesn't look like the paper uses any dropout in MSABlocks
                super().__init__()

                # Create the Norm layer (LN)
                self.layer_norm = nn.LayerNorm(normalized_shape=embedding_dim)

                # Create the Multi-Head Attention (MSA) layer
                self.multihead_attn = nn.MultiheadAttention(
                    embed_dim=embedding_dim,
                    num_heads=heads_num,
                    dropout=attn_dropout,
                    batch_first=True,
                )  # does our batch dimension come first?(batch, seq, feature)

            def forward(self, x):
                x = self.layer_norm(x)
                attn_output, _ = self.multihead_attn(
                    query=x,  # query embeddings
                    key=x,  # key embeddings
                    value=x,  # value embeddings
                    need_weights=False,
                )  # do we need the weights or just the layer outputs?
                return attn_output

        class MLPBlock(nn.Module):
            def __init__(
                self,
                embedding_dim: int = 768,
                mlp_size: int = 3072,
                mlp_dropout: float = 0.1,
            ):
                super().__init__()

                self.layer_norm = nn.LayerNorm(normalized_shape=embedding_dim)

                self.mlp = nn.Sequential(
                    nn.Linear(in_features=embedding_dim, out_features=mlp_size),
                    nn.GELU(),
                    nn.Dropout(p=mlp_dropout),
                    nn.Linear(in_features=mlp_size, out_features=embedding_dim),
                    nn.Dropout(p=mlp_dropout),
                )

            def forward(self, x):
                return self.mlp(self.layer_norm(x))

        def __init__(
            self,
            embedding_dim: int = 768,
            heads_num: int = 12,
            mlp_size=3072,
            mlp_dropout: float = 0.1,
            attn_dropout: float = 0,
        ):
            super().__init__()

            self.msa_block = self.MultiheadSelfAttentionBlock(
                embedding_dim=embedding_dim,
                heads_num=heads_num,
                attn_dropout=attn_dropout,
            )

            self.mlp_block = self.MLPBlock(
                embedding_dim=embedding_dim, mlp_size=mlp_size, mlp_dropout=mlp_dropout
            )

        def forward(self, x):
            x = self.msa_block(x) + x
            x = self.mlp_block(x) + x
            return x

    def __init__(
        self,
        image_size: int = 224,
        patch_size: int = 16,
        tranformer_encoder_num: int = 12,
        embedding_dim: int = 768,
        mlp_size: int = 3072,
        heads_num: int = 12,
        attn_dropout: float = 0,
        mlp_dropout: float = 0.1,
        embedding_dropout: float = 0.1,
        output_shape: int = 1000,
    ):
        super().__init__()

        self.embed_block = self.PatchAndPositionEmbeddingBlock(
            patch_size=patch_size,
            image_size=image_size,
            embedding_dim=embedding_dim,
            embedding_dropout=embedding_dropout,
        )

        self.transformer_encoder = nn.ModuleList(
            [
                self.TransformerEncoderBlock(
                    embedding_dim=embedding_dim,
                    heads_num=heads_num,
                    mlp_size=mlp_size,
                    mlp_dropout=mlp_dropout,
                    attn_dropout=attn_dropout,
                )
                for _ in range(tranformer_encoder_num)
            ]
        )

        self.classifer = nn.Sequential(
            nn.LayerNorm(normalized_shape=embedding_dim),
            nn.Linear(in_features=embedding_dim, out_features=output_shape),
        )

    def forward(self, x):
        x = self.embed_block(x)
        for transformer_encoder_block in self.transformer_encoder:
            x = transformer_encoder_block(x)

        x = self.classifer(x[:, 0, :])

        return x

class NiceViTB16(nn.Module):
    WEIGHTS = models.ViT_B_16_Weights.IMAGENET1K_V1

    def __init__(self, hidden_units_num: int, output_shape: int):
        super().__init__()

        origin_model = models.vit_b_16(weights=self.WEIGHTS)

        # origin_model.conv_proj.requires_grad_(False)
        # origin_model.encoder.requires_grad_(False)

        # NOTE: 其实也可以考虑全都设置requires_grad = False，然后替换掉heads
        for param in origin_model.parameters():
            param.requires_grad = False

        heads = [
            nn.Linear(
                in_features=768,
                out_features=hidden_units_num,
            ),
            torch.nn.Dropout(p=0.2, inplace=True),
            torch.nn.Linear(
                in_features=hidden_units_num,
                out_features=output_shape,
                bias=True,
            ),
        ]
        origin_model.heads = nn.Sequential(*heads)
        self.origin_model = origin_model

    def forward(self, x: torch.Tensor):
        return self.origin_model(x)

    @property
    def transforms(self):
        origin_transform = self.WEIGHTS.transforms()
        transform = transforms.Compose(
            [transforms.Grayscale(num_output_channels=3), origin_transform]
        )

        return transform, transform  # NOTE: 分别看作train_transform和test_transform

if __name__ == "__main__":
    vit = CustomViT()
    x = torch.rand(10, 3, 224, 224)
    assert vit(x).shape == (10, 1000), "What??"


from typing import TextIO

a, b = [int(x) for x in input("Enter two numbers: ").split()]

f: TextIO = open("myfile.txt", "w")
try:
    result = a / b
    f.write("{} / {} = {}".format(a, b, result))
except ZeroDivisionError as exception:
    print("0 is not allowed as second number!")
    print(exception)
else:
    # else can be used for logic that should be executed only if no exception is thrown
    print("You have entered a non-zero value")
finally:
    f.close()


# -*- coding: utf-8 -*-
from __future__ import absolute_import, division, print_function

import tensorflow as tf
from tensorflow.python.framework import dtypes
from tensorflow.contrib import learn as tflearn
from tensorflow.contrib import layers as tflayers

def lstm_model(num_units, rnn_layers, dense_layers=None, learning_rate=0.1, optimizer='Adagrad'):
    """
    Creates a deep model based on:
        * stacked lstm cells
        * an optional dense layers
    :param num_units: the size of the cells.
    :param rnn_layers: list of int or dict
                         * list of int: the steps used to instantiate the `BasicLSTMCell` cell
                         * list of dict: [{steps: int, keep_prob: int}, ...]
    :param dense_layers: list of nodes for each layer
    :return: the model definition
    """

    def lstm_cells(layers):
        if isinstance(layers[0], dict):
            return [tf.contrib.rnn.DropoutWrapper(
                tf.contrib.rnn.BasicLSTMCell(
                    layer['num_units'], state_is_tuple=True
                ),
                layer['keep_prob']
            ) if layer.get('keep_prob') else tf.contrib.rnn.BasicLSTMCell(
                    layer['num_units'],
                    state_is_tuple=True
                ) for layer in layers
            ]
        return [tf.contrib.rnn.BasicLSTMCell(steps, state_is_tuple=True) for steps in layers]

    def dnn_layers(input_layers, layers):
        if layers and isinstance(layers, dict):
            return tflayers.stack(input_layers, tflayers.fully_connected,
                                  layers['layers'],
                                  activation=layers.get('activation'),
                                  dropout=layers.get('dropout'))
        elif layers:
            return tflayers.stack(input_layers, tflayers.fully_connected, layers)
        else:
            return input_layers

    def _lstm_model(X, y):
        stacked_lstm = tf.contrib.rnn.MultiRNNCell(lstm_cells(rnn_layers), state_is_tuple=True)
        x_ = tf.unstack(X, axis=1, num=num_units)
        output, layers = tf.contrib.rnn.static_rnn(stacked_lstm, x_, dtype=dtypes.float32)
        output = dnn_layers(output[-1], dense_layers)
        prediction, loss = tflearn.models.linear_regression(output, y)
        train_op = tf.contrib.layers.optimize_loss(
            loss, tf.contrib.framework.get_global_step(), optimizer=optimizer,
            learning_rate=learning_rate)
        return prediction, loss, train_op

    return _lstm_model


from ast import literal_eval

import tensorflow as tf
from tensorflow.keras.applications import DenseNet121
from tensorflow.keras.layers import Input, Dense, Dropout, BatchNormalization, Activation, \
	AlphaDropout, Conv1D, Lambda, Concatenate, MaxPooling1D, GlobalMaxPooling1D, Multiply, \
	Conv2D, MaxPooling2D, GlobalAveragePooling2D, add
from tensorflow.keras.models import Model
from tensorflow.keras.regularizers import l1_l2
from tensorflow.python.keras.layers.advanced_activations import LeakyReLU, PReLU

from tensorflow.keras import datasets, layers, models
import matplotlib.pyplot as plt

from keras.models import Sequential
from tensorflow.keras.layers import Conv2D, BatchNormalization, MaxPooling2D,Flatten,Dropout,Dense
from tensorflow.keras  import optimizers

from tensorflow.keras import optimizers
from tensorflow.keras.layers import Input, Dense, concatenate
from tensorflow.keras.metrics import MeanSquaredError, RootMeanSquaredError
from tensorflow.keras.models import Model

import sys
sys.path.append("..")

def buildDL(useCancerType=False, expr_dim=None, drug_dim=None, coeffs_dim=None, useCoeffs=False, useDrugs=True, useSingleAgent=False, mixedModel=False, expr_hlayers_sizes='[10]', drug_hlayers_sizes='[10]', coeffs_hlayers_sizes='[10]',
                          predictor_hlayers_sizes='[10]', initializer='he_normal', hidden_activation='relu', l1=0,
                          l2=0, input_dropout=0, hidden_dropout=0, learn_rate=0.001):
	"""Build a multi-input deep learning model with separate feature-encoding subnetworks for expression data, drugA
	and drugB, with fully-connected layers in all subnetworks."""

	if(mixedModel):
		useCoeffs=False

	expr_input = Input(shape=expr_dim, name='expr')
	if(useCoeffs):
		coeffs1_input = Input(shape=coeffs_dim, name='coeffsA')
		coeffs2_input = Input(shape=coeffs_dim, name='coeffsB')
	if(useDrugs):
		drug1_input = Input(shape=drug_dim, name='drugA')
		drug2_input = Input(shape=drug_dim, name='drugB')
	if(useSingleAgent):
		singleAgentInput = Input(shape=4, name='singleAgent')
	if(useCancerType):
		cancerTypeInput = Input(shape=1, name='cancerType')

	expr = dense_submodel(expr_input, hlayers_sizes=expr_hlayers_sizes, l1_regularization=l1, l2_regularization=l2,
	                      hidden_activation=hidden_activation, input_dropout=input_dropout,
	                      hidden_dropout=hidden_dropout)

	if(useDrugs):
		drug_submodel = drug_dense_submodel(drug_dim, hlayers_sizes=drug_hlayers_sizes, l1_regularization=l1,
											l2_regularization=l2, hidden_activation=hidden_activation,
											input_dropout=input_dropout, hidden_dropout=hidden_dropout)

		drugA = drug_submodel(drug1_input)
		drugB = drug_submodel(drug2_input)

	if(useCoeffs):
		coeffs_submodel = drug_dense_submodel(coeffs_dim, hlayers_sizes=coeffs_hlayers_sizes, l1_regularization=l1,
										l2_regularization=l2, hidden_activation=hidden_activation,
										input_dropout=input_dropout, hidden_dropout=hidden_dropout, layerName='coeffs_dense_submodel')

		coeffsA = coeffs_submodel(coeffs1_input)
		coeffsB = coeffs_submodel(coeffs2_input)

	fullConcat = [expr]
	if(useCoeffs):
		fullConcat.append(coeffsA)
		fullConcat.append(coeffsB)
	if(useDrugs):
		fullConcat.append(drugA)
		fullConcat.append(drugB)
	if(useSingleAgent):
		fullConcat.append(singleAgentInput)
	if(useCancerType):
		fullConcat.append(cancerTypeInput)

	concat = concatenate(fullConcat)

	# Additional dense layers after concatenating:
	main_branch = dense_submodel(concat, hlayers_sizes=predictor_hlayers_sizes,
	                             l1_regularization=l1, l2_regularization=l2,
	                             hidden_activation=hidden_activation, input_dropout=0,
	                             hidden_dropout=hidden_dropout)

	# Add output layer
	output = Dense(2, activation='linear', kernel_initializer=initializer, name='output')(main_branch)

	fullInputs = [expr_input]
	if(useCoeffs):
		fullInputs.append(coeffs1_input)
		fullInputs.append(coeffs2_input)
	if(useDrugs):
		fullInputs.append(drug1_input)
		fullInputs.append(drug2_input)
	if(useSingleAgent):
		fullInputs.append(singleAgentInput)
	if(useCancerType):
		fullInputs.append(cancerTypeInput)

	model = Model(inputs=fullInputs, outputs=[output])
	#model = Model(inputs=cnnInp, outputs=[output])

	model.compile(loss='mean_squared_error', optimizer=tf.keras.optimizers.Adam(learning_rate=learn_rate))

	return model

def drug_dense_submodel(input_dim, hlayers_sizes='[10]', l1_regularization=0, l2_regularization=0,
                        hidden_activation='relu', input_dropout=0, hidden_dropout=0, layerName='drug_dense_submodel'):
	"""Build a dense (fully-connected) submodel for drugs, so that it can be used later on to share weights
	between two drug subnetworks."""
	input_layer = Input(shape=input_dim)

	output = dense_submodel(input_layer, hlayers_sizes, l1_regularization, l2_regularization,
	                        hidden_activation, input_dropout, hidden_dropout)

	submodel = Model(inputs=input_layer, outputs=output, name=layerName)

	return submodel

def dense_submodel(input_layer, hlayers_sizes='[10]', l1_regularization=0, l2_regularization=0,
                   hidden_activation='relu', input_dropout=0, hidden_dropout=0):
	"""Build a dense (fully-connected) subnetwork."""
	hlayers_sizes = literal_eval(hlayers_sizes)  # because hlayers_sizes was passed as a string

	if hidden_activation == 'selu':
		# selu must be used with the LecunNormal initializer and AlphaDropout instead of normal Dropout
		initializer = 'lecun_normal'
		dropout = AlphaDropout
		batchnorm = False
	else:
		initializer = 'he_normal'
		dropout = Dropout
		batchnorm = True

	if input_dropout > 0:
		x = dropout(rate=input_dropout)(input_layer)
	else:
		x = input_layer

	for i in range(len(hlayers_sizes)):
		x = Dense(units=hlayers_sizes[i], kernel_initializer=initializer,
		          kernel_regularizer=l1_l2(l1=l1_regularization, l2=l2_regularization))(x)
		if hidden_activation.lower() == 'leakyrelu':
			x = LeakyReLU()(x)
		elif hidden_activation.lower() == 'prelu':
			x = PReLU()(x)
		else:
			x = Activation(hidden_activation)(x)

		if batchnorm:
			x = BatchNormalization()(x)

		if hidden_dropout > 0:
			x = dropout(rate=hidden_dropout)(x)

	return x

def cnnOmicsModel(useDrugs=False, useCoeffs=False, omicsOutputNeurons = 64, drugDim=1024, coeffsDim=0, sizeOmics = 0, filters=32, secondFilter=32, kernelSize=3, secondKernel=3, coeffsHlayerSizes= '[10]',drugHlayerSizes= '[10]',predictorHlayersSizes='[10]', cnnActivation = 'relu', hiddenActivation='relu', initializer='he_normal', hiddenDropout=0, l1=0, l2=0, useSingleAgent = True, learnRate = 0.001):

	if(useDrugs):
		drug1_input = Input(shape=drugDim, name='drugA')
		drug2_input = Input(shape=drugDim, name='drugB')

	if(useCoeffs):
		coeffs1_input = Input(shape=coeffsDim, name='coeffsA')
		coeffs2_input = Input(shape=coeffsDim, name='coeffsB')

	inputOmicsLayer = Input(shape=(3, sizeOmics))
	y = tf.keras.layers.Conv1D(filters, kernelSize, activation='relu', input_shape=(3, sizeOmics), padding='same')(inputOmicsLayer)
	yy = tf.keras.layers.Conv1D(secondFilter, secondKernel, activation='relu', input_shape=(3, sizeOmics), padding='same')(y)
	z = tf.keras.layers.Flatten()(yy)
	w = tf.keras.layers.Dense(omicsOutputNeurons)(z)

	fullInputs = [inputOmicsLayer]
	inputsForMain = [w]
	if(useSingleAgent):
		singleAgentInput = Input(shape=4, name='singleAgent')
		inputsForMain.append(singleAgentInput)
		fullInputs.append(singleAgentInput)
	if(useDrugs):
		fullInputs.append(drug1_input)
		fullInputs.append(drug2_input)

		drug_submodel = drug_dense_submodel(drugDim, hlayers_sizes=drugHlayerSizes, l1_regularization=l1,
							l2_regularization=l2, hidden_activation=hiddenActivation,
							input_dropout=0, hidden_dropout=hiddenDropout)
		drugA = drug_submodel(drug1_input)
		drugB = drug_submodel(drug2_input)

		inputsForMain.append(drugA)
		inputsForMain.append(drugB)

	if(useCoeffs):
		fullInputs.append(coeffs1_input)
		fullInputs.append(coeffs2_input)
		coeffs_submodel = drug_dense_submodel(coeffsDim, hlayers_sizes=coeffsHlayerSizes, l1_regularization=l1,
										l2_regularization=l2, hidden_activation=hiddenActivation,
										input_dropout=0, hidden_dropout=hiddenDropout, layerName='coeffs_dense_submodel')

		coeffsA = coeffs_submodel(coeffs1_input)
		coeffsB = coeffs_submodel(coeffs2_input)
		inputsForMain.append(coeffsA)
		inputsForMain.append(coeffsB)

	inputsForMain = concatenate(inputsForMain)

	# Additional dense layers after concatenating:
	mainBranch = dense_submodel(inputsForMain, hlayers_sizes=predictorHlayersSizes,
	                             l1_regularization=l1, l2_regularization=l2,
	                             hidden_activation=hiddenActivation, input_dropout=0,
	                             hidden_dropout=hiddenDropout)

	# Add output layer

	output = Dense(2, activation='linear', kernel_initializer=initializer, name='output')(mainBranch)

	model = Model(inputs=fullInputs , outputs=[output], name='CNN')
	model.compile(loss='mean_squared_error', optimizer=tf.keras.optimizers.Adam(learning_rate=learnRate))
	#return model

	return model


from company.module.company import Company
from django.http import HttpResponse, JsonResponse

def getCompanyInfo(request):
    company = Company()
    name = None
    code = None

    try:
        code = request.GET['code']
    except:
        name = request.GET['name']

    print("CODE : ",code)
    print("name : ",name)
    if code != None:
        result = JsonResponse(company.getCompanyInfoByCode(code))
    else :
        result = JsonResponse(company.getCompanyInfoByName(name))

    return result


from __future__ import absolute_import
from __future__ import division
# [internal] enable type annotations
from __future__ import print_function

# Dependency imports
import numpy as np
import tensorflow.compat.v2 as tf
from tensorflow_probability.python.internal import custom_gradient as tfp_custom_gradient
from tensorflow_probability.python.internal import dtype_util
from tensorflow_probability.python.internal import prefer_static
from tensorflow_probability.python.internal import tensorshape_util

__all__ = [
    'erfcinv',
    'round_exponential_bump_function',
    'lambertw',
    'lambertw_winitzki_approx',
    'log_gamma_correction',
    'log_gamma_difference',
    'lbeta',
]

def erfcinv(z, name=None):
  """Computes the inverse of `tf.math.erfc` of `z` element-wise.

  NOTE: This is mathematically equivalent to computing `erfinv(1 - x)`
  however is more numerically stable.

  Args:
    z: A Tensor with type `float32` or `float64`.
    name: A name for the operation (optional).

  Returns:
    erfcinv: erfcinv evaluated at `z`. A Tensor with the same shape and same
      dtype as `z`.
  """
  with tf.name_scope(name or 'erfcinv'):
    z = tf.convert_to_tensor(z)
    return -tf.math.ndtri(0.5 * z) * np.sqrt(0.5)

def round_exponential_bump_function(x, name=None):
  r"""Function supported on [-1, 1], smooth on the real line, with a round top.

  Define

  ```
  f(x) := exp(-1 / (1 - x**2)) * exp(1), for x in (-1, 1)
  f(x) := 0, for |x| >= 1.
  ```

  One can show that f(x)...

  * is C^\infty on the real line.
  * is supported on [-1, 1].
  * is equal to 1 at x = 0.
  * is strictly increasing on (-1, 0).
  * is strictly decreasing on (0, 1).
  * has gradient = 0 at 0.

  See [Bump Function](https://en.wikipedia.org/wiki/Bump_function)

  Args:
    x: Floating-point Tensor.
    name: Optional Python `str` naming the operation.

  Returns:
    y: Tensor of same shape and dtype as `x`.
  """
  with tf.name_scope(name or 'round_exponential_bump_function'):
    x = tf.convert_to_tensor(x, name='x')
    one_m_x2 = 1 - x**2
    y = tf.math.exp(1. - tf.math.reciprocal_no_nan(one_m_x2))
    return tf.where(one_m_x2 > 0., y, 0.)

def lambertw_winitzki_approx(z, name=None):
  """Computes Winitzki approximation to Lambert W function at z >= -1/exp(1).

  The approximation for z >= -1/exp(1) will be used as a starting point in the
  iterative algorithm to compute W(z). See _lambertw_principal_branch() below.
  See
  https://www.researchgate.net/post/Is_there_approximation_to_the_LambertWx_function
  and in particular (38) in
  https://pdfs.semanticscholar.org/e934/24f33e2742016ef18c36a80788400d2f17b4.pdf

  Args:
    z: value for which W(z) should be computed. Expected z >= -1/exp(1). If not
     then function will fail due to log(<0).
    name: optionally pass name for output.

  Returns:
    lambertw_winitzki_approx: Approximation for W(z) for z >= -1/exp(1).
  """
  with tf.name_scope(name or 'lambertw_winitzki_approx'):
    z = tf.convert_to_tensor(z)
    # See eq (38) here:
    # https://pdfs.semanticscholar.org/e934/24f33e2742016ef18c36a80788400d2f17b4.pdf
    # or (10) here:
    # https://hal.archives-ouvertes.fr/hal-01586546/document
    log1pz = tf.math.log1p(z)
    return log1pz * (1. - tf.math.log1p(log1pz) / (2. + log1pz))

def _fritsch_iteration(unused_should_stop, z, w, tol):
  """Root finding iteration for W(z) using Fritsch iteration."""
  # See Section 2.3 in https://arxiv.org/pdf/1209.0735.pdf
  # Approximate W(z) by viewing iterative algorithm as multiplicative factor
  #
  #  W(n+1) = W(n) * (1 + error)
  #
  # where error can be expressed as a function of z and W(n). See paper for
  # details.
  z = tf.convert_to_tensor(z)
  w = tf.convert_to_tensor(w)
  zn = tf.math.log(tf.abs(z)) - tf.math.log(tf.abs(w)) - w
  wp1 = w + 1.0
  q = 2. * wp1 * (wp1 + 2. / 3. * zn)
  q_minus_2zn = q - 2. * zn
  error = zn / wp1 * (1. + zn / q_minus_2zn)
  # Check absolute tolerance (not relative).  Here the iteration error is
  # for relative tolerance, as W(n+1) = W(n) * (1 + error).  Use
  # W(n+1) - W(n) = W(n) * error to get absolute tolerance.
  converged = abs(error * w) <= tol
  should_stop_next = tf.reduce_all(converged)
  return should_stop_next, w * (1. + error), z, tol

def _halley_iteration(unused_should_stop, w, z, tol, iteration_count):
  """Halley's method on root finding of w for the equation w * exp(w) = z."""
  w = tf.convert_to_tensor(w)
  z = tf.convert_to_tensor(z)
  f = w - z * tf.math.exp(-w)
  delta = f / (w + 1. - 0.5 * (w + 2.) * f / (w + 1.))
  w_next = w - delta
  converged = tf.math.abs(delta) <= tol * tf.math.abs(w_next)
  # We bound the number of iterations to be at most a 100.

  # When x is close to the branch point, the derivatives tend to very large
  # values, which causes the iteration to be slow. For x <= 0., 100 iterations
  # seems to be enough to guarantee a relative error of at most 1e-6.

  # The Winitzki approximation has a relative error of at most
  # 0.01. When x >= 0., the first through third derivatives are bounded such
  # that coupled with the initial approximation, we are in the realm of cubic
  # convergence.
  should_stop_next = tf.reduce_all(converged) | (iteration_count >= 100)
  return should_stop_next, w_next, z, tol, iteration_count + 1

def _lambertw_principal_branch(z, name=None):
  """Computes Lambert W of `z` element-wise at the principal (k = 0) branch.

  The Lambert W function is the inverse of `z = y * tf.exp(y)` and is a
  many-valued function. Here `y = W_0(z)`, where `W_0` is the Lambert W function
  evaluated at the 0-th branch (aka principal branch).

  Args:
    z: A Tensor with type `float32` or `float64`.
    name: A name for the operation (optional).
      Default value: `None` (i.e., 'lambertw_principal_branch').

  Returns:
    lambertw_principal_branch: A Tensor with same shape and same dtype as `z`.
  """
  with tf.name_scope(name or 'lambertw_principal_branch'):
    z = tf.convert_to_tensor(z)
    np_finfo = np.finfo(dtype_util.as_numpy_dtype(z.dtype))
    tolerance = tf.convert_to_tensor(2. * np_finfo.resolution, dtype=z.dtype)
    # Start while loop with the initial value at the approximate Lambert W
    # solution, instead of 'z' (for z > -1 / exp(1)).  Using 'z' has bad
    # convergence properties especially for large z (z > 5).
    z0 = tf.where(z > -np.exp(-1.), lambertw_winitzki_approx(z), z)
    z0 = tf.while_loop(cond=lambda stop, *_: ~stop,
                       body=_halley_iteration,
                       loop_vars=(False, z0, z, tolerance, 0))[1]
    return tf.cast(z0, dtype=z.dtype)

@tf.custom_gradient
def lambertw(z, name=None):
  """Computes Lambert W of `z` element-wise.

  The Lambert W function is the inverse of `z = u * exp(u)`, i. e., it is the
  function that satisfies `u = W(z) * exp(W(z))`.  The solution cannot be
  expressed as a composition of elementary functions and is thus part of the
  *special* functions in mathematics.  See
  https://en.wikipedia.org/wiki/Lambert_W_function.

  In general it is a complex-valued function with multiple branches. The `k=0`
  branch is known as the *principal branch* of the Lambert W function and is
  implemented here. See also `scipy.special.lambertw`.

  This code returns only the real part of the image of the Lambert W function.

  # References

  Corless, R.M., Gonnet, G.H., Hare, D.E.G. et al. On the LambertW function.
  Adv Comput Math 5, 329-359 (1996) doi:10.1007/BF02124750

  Args:
    z: A Tensor with type `float32` or `float64`.
    name: A name for the operation (optional).

  Returns:
    lambertw: The Lambert W function evaluated at `z`. A Tensor with same shape
      and same dtype as `z`.
  """
  with tf.name_scope(name or 'lambertw'):
    z = tf.convert_to_tensor(z)
    wz = _lambertw_principal_branch(z, name)

    def grad(dy):
      """Computes the derivative of Lambert W of `z` element-wise.

      The first derivative W'(z) can be computed from W(z) as it holds

        W'(z) = W(z) / (z * (1 + W(z)))

      Args:
        dy: A Tensor with type `float32` or `float64`.

      Returns:
        A Tensor with same shape and dtype as `z`.
      """
      # At z = 0 the analytic expressions for the gradient results in a 0/0
      # expression.  However, the continuous expansion (l'Hospital rule) gives a
      # derivative of 1.0 at z = 0.  This case has to be handled separately with
      # a where clause.
      grad_wz = (dy * tf.where(tf.equal(z, 0.0),
                               tf.ones_like(wz),
                               wz / (z * (1. + wz))))
      return grad_wz

    return wz, grad

def log_gamma_correction(x, name=None):
  """Returns the error of the Stirling approximation to lgamma(x) for x >= 8.

  This is useful for accurately evaluating ratios between Gamma functions, as
  happens when trying to compute Beta functions.

  Specifically,
  ```
  lgamma(x) approx (x - 0.5) * log(x) - x + 0.5 log (2 pi)
                   + log_gamma_correction(x)
  ```
  for x >= 8.

  This is the function called Delta in [1], eq (30).  We implement it with
  the rational minimax approximation given in [1], eq (32).

  References:

  [1] DiDonato and Morris, "Significant Digit Computation of the Incomplete Beta
      Function Ratios", 1988.  Technical report NSWC TR 88-365, Naval Surface
      Warfare Center (K33), Dahlgren, VA 22448-5000.  Section IV, Auxiliary
      Functions.  https://apps.dtic.mil/dtic/tr/fulltext/u2/a210118.pdf

  Args:
    x: Floating-point Tensor at which to evaluate the log gamma correction
      elementwise.  The approximation is accurate when x >= 8.
    name: Optional Python `str` naming the operation.

  Returns:
    lgamma_corr: Tensor of elementwise log gamma corrections.
  """
  with tf.name_scope(name or 'log_gamma_correction'):
    dtype = dtype_util.common_dtype([x], tf.float32)
    x = tf.convert_to_tensor(x, dtype=dtype)

    minimax_coeff = tf.constant([
        0.833333333333333e-01,
        -0.277777777760991e-02,
        0.793650666825390e-03,
        -0.595202931351870e-03,
        0.837308034031215e-03,
        -0.165322962780713e-02,
    ], dtype=dtype)

    inverse_x = 1 / x
    inverse_x_squared = inverse_x * inverse_x
    accum = minimax_coeff[5]
    for i in reversed(range(5)):
      accum = accum * inverse_x_squared + minimax_coeff[i]
    return accum * inverse_x

def _fix_gradient_for_broadcasting(a, b, grad_a, grad_b):
  """Reduces broadcast dimensions for a custom gradient."""
  if (tensorshape_util.is_fully_defined(a.shape) and
      tensorshape_util.is_fully_defined(b.shape) and
      a.shape == b.shape):
    return [grad_a, grad_b]
  a_shape = tf.shape(a)
  b_shape = tf.shape(b)
  ra, rb = tf.raw_ops.BroadcastGradientArgs(s0=a_shape, s1=b_shape)
  grad_a = tf.reshape(tf.reduce_sum(grad_a, axis=ra), a_shape)
  grad_b = tf.reshape(tf.reduce_sum(grad_b, axis=rb), b_shape)
  return [grad_a, grad_b]

def _log_gamma_difference_big_y(x, y):
  """Returns lgamma(y) - lgamma(x + y), accurately if 0 <= x <= y and y >= 8.

  This is more accurate than subtracting lgammas directly because lgamma grows
  as `x log(x) - x + o(x)`, and thus subtracting the value of lgamma for two
  close, large arguments incurs catastrophic cancellation.

  The method is to partition lgamma into the Striling approximation and the
  correction `log_gamma_correction`, symbolically cancel the former, and compute
  and subtract the latter.

  Args:
    x: Floating-point Tensor.  `x` should be non-negative, and elementwise no
      more than `y`.
    y: Floating-point Tensor.  `y` should be elementwise no less than 8.

  Returns:
    lgamma_diff: Floating-point Tensor, the difference lgamma(y) - lgamma(x+y),
      computed elementwise.
  """
  cancelled_stirling = (-1 * (x + y - 0.5) * tf.math.log1p(x / y)
                        - x * tf.math.log(y) + x)
  correction = log_gamma_correction(y) - log_gamma_correction(x + y)
  return correction + cancelled_stirling

def _log_gamma_difference_naive_gradient(x, y):
  big_y = _log_gamma_difference_big_y(x, y)
  small_y = tf.math.lgamma(y) - tf.math.lgamma(x + y)
  return tf.where(y >= 8, big_y, small_y)

def _log_gamma_difference_fwd(x, y):
  """Compute output, aux (collaborates with _log_gamma_difference_bwd)."""
  return _log_gamma_difference_naive_gradient(x, y), (x, y)

def _log_gamma_difference_bwd(aux, g):
  """Reverse mode impl for log-gamma-diff."""
  x, y = aux
  # Computing the gradient naively as the difference of digammas because
  # (i) digamma grows slower than gamma, so gets into bad cancellations
  # later, and (ii) doing better is work.  This matches what the gradient
  # would be if the forward pass were computed naively as the difference
  # of lgammas.
  #
  # Note: This gradient assumes x and y are the same shape; this needs to
  # be arranged by pre-broadcasting before calling
  # `_log_gamma_difference`.
  px = -tf.math.digamma(x + y)
  py = tf.math.digamma(y) + px
  return _fix_gradient_for_broadcasting(x, y, px * g, py * g)

def _log_gamma_difference_jvp(primals, tangents):
  """Computes JVP for log-gamma-difference (supports JAX custom derivative)."""
  x, y = primals
  dx, dy = tangents
  # TODO(https://github.com/google/jax/issues/3768): eliminate broadcast_to?
  bc_shp = prefer_static.broadcast_shape(prefer_static.shape(dx),
                                         prefer_static.shape(dy))
  dx = tf.broadcast_to(dx, bc_shp)
  dy = tf.broadcast_to(dy, bc_shp)
  # See note above in _log_gamma_difference_bwd.
  px = -tf.math.digamma(x + y)
  py = tf.math.digamma(y) + px
  return _log_gamma_difference_naive_gradient(x, y), px * dx + py * dy

@tfp_custom_gradient.custom_gradient(
    vjp_fwd=_log_gamma_difference_fwd,
    vjp_bwd=_log_gamma_difference_bwd,
    jvp_fn=_log_gamma_difference_jvp)
def _log_gamma_difference_custom_gradient(x, y):
  return _log_gamma_difference_naive_gradient(x, y)

def log_gamma_difference(x, y, name=None):
  """Returns lgamma(y) - lgamma(x + y), accurately.

  This is more accurate than subtracting lgammas directly because lgamma grows
  as `x log(x) - x + o(x)`, and thus subtracting the value of lgamma for two
  close, large arguments incurs catastrophic cancellation.

  The method is to partition lgamma into the Striling approximation and the
  correction `log_gamma_correction`, symbolically cancel the former, and compute
  and subtract the latter.

  Args:
    x: Floating-point Tensor.  `x` should be non-negative, and elementwise no
      more than `y`.
    y: Floating-point Tensor.  `y` should be elementwise no less than 8.
    name: Optional Python `str` naming the operation.

  Returns:
    lgamma_diff: Floating-point Tensor, the difference lgamma(y) - lgamma(x+y),
      computed elementwise.
  """
  with tf.name_scope(name or 'log_gamma_difference'):
    dtype = dtype_util.common_dtype([x, y], tf.float32)
    x = tf.convert_to_tensor(x, dtype=dtype)
    y = tf.convert_to_tensor(y, dtype=dtype)
    return _log_gamma_difference_custom_gradient(x, y)

def _lbeta_naive_gradient(x, y):
  """Computes log(Beta(x, y)) with autodiff gradients only."""
  # Flip args if needed so y >= x.  Beta is mathematically symmetric but our
  # method for computing it is not.
  x, y = tf.minimum(x, y), tf.maximum(x, y)

  log2pi = tf.constant(np.log(2 * np.pi), dtype=x.dtype)
  # Two large arguments case: y >= x >= 8.
  log_beta_two_large = (0.5 * log2pi
                        - 0.5 * tf.math.log(y)
                        + log_gamma_correction(x)
                        + log_gamma_correction(y)
                        - log_gamma_correction(x + y)
                        + (x - 0.5) * tf.math.log(x / (x + y))
                        - y * tf.math.log1p(x / y))

  # One large argument case: x < 8, y >= 8.
  log_beta_one_large = tf.math.lgamma(x) + _log_gamma_difference_big_y(x, y)

  # Small arguments case: x <= y < 8.
  log_beta_small = tf.math.lgamma(x) + tf.math.lgamma(y) - tf.math.lgamma(x + y)

  # Reference [1] has two more arms, for cases where x or y falls into the
  # interval (2, 8).  In these cases, reference [1] recommends iteratively
  # reducing the arguments using the identity
  #   B(x, y) = B(x - 1, y) * (x - 1) / (x + y - 1)
  # so they fall in the interval [1, 2].  We choose not to do that here to avoid
  # a TensorFlow while loop, and hope that subtracting lgammas will be accurate
  # enough for the user's purposes.

  return tf.where(x >= 8,
                  log_beta_two_large,
                  tf.where(y >= 8,
                           log_beta_one_large,
                           log_beta_small))

def _lbeta_fwd(x, y):
  """Compute output, aux (collaborates with _lbeta_bwd)."""
  return _lbeta_naive_gradient(x, y), (x, y)

def _lbeta_bwd(aux, g):
  x, y = aux
  total_digamma = tf.math.digamma(x + y)
  px = tf.math.digamma(x) - total_digamma
  py = tf.math.digamma(y) - total_digamma
  return _fix_gradient_for_broadcasting(x, y, px * g, py * g)

def _lbeta_jvp(primals, tangents):
  """Computes JVP for log-beta (supports JAX custom derivative)."""
  x, y = primals
  dx, dy = tangents
  # TODO(https://github.com/google/jax/issues/3768): eliminate broadcast_to?
  bc_shp = prefer_static.broadcast_shape(prefer_static.shape(dx),
                                         prefer_static.shape(dy))
  dx = tf.broadcast_to(dx, bc_shp)
  dy = tf.broadcast_to(dy, bc_shp)
  total_digamma = tf.math.digamma(x + y)
  px = tf.math.digamma(x) - total_digamma
  py = tf.math.digamma(y) - total_digamma
  return _lbeta_naive_gradient(x, y), px * dx + py * dy

@tfp_custom_gradient.custom_gradient(
    vjp_fwd=_lbeta_fwd,
    vjp_bwd=_lbeta_bwd,
    jvp_fn=_lbeta_jvp)
def _lbeta_custom_gradient(x, y):
  """Computes log(Beta(x, y)) with correct custom gradient."""
  return _lbeta_naive_gradient(x, y)

def lbeta(x, y, name=None):
  """Returns log(Beta(x, y)).

  This is semantically equal to
    lgamma(x) + lgamma(y) - lgamma(x + y)
  but the method is more accurate for arguments above 8.

  The reason for accuracy loss in the naive computation is catastrophic
  cancellation between the lgammas.  This method avoids the numeric cancellation
  by explicitly decomposing lgamma into the Stirling approximation and an
  explicit `log_gamma_correction`, and cancelling the large terms from the
  Striling analytically.

  The computed gradients are the same as for the naive forward computation,
  because (i) digamma grows much slower than lgamma, so cancellations aren't as
  bad, and (ii) it's simpler and faster than trying to be more accurate.

  References:

  [1] DiDonato and Morris, "Significant Digit Computation of the Incomplete Beta
      Function Ratios", 1988.  Technical report NSWC TR 88-365, Naval Surface
      Warfare Center (K33), Dahlgren, VA 22448-5000.  Section IV, Auxiliary
      Functions.  https://apps.dtic.mil/dtic/tr/fulltext/u2/a210118.pdf

  Args:
    x: Floating-point Tensor.
    y: Floating-point Tensor.
    name: Optional Python `str` naming the operation.

  Returns:
    lbeta: Tensor of elementwise log beta(x, y).
  """
  with tf.name_scope(name or 'tfp_lbeta'):
    dtype = dtype_util.common_dtype([x, y], tf.float32)
    x = tf.convert_to_tensor(x, dtype=dtype)
    y = tf.convert_to_tensor(y, dtype=dtype)
    return _lbeta_custom_gradient(x, y)


# python3
# Kristiāns Martiņjaks 221RDB223

def build_heap(data):
    swaps = []
    n = len(data)

    for i in range(n // 2, -1, -1):
        minHeap(data, n, i, swaps)
    return swaps

def minHeap(data, n, i, swaps):
    lSide = 2 * i + 1
    rSide = 2 * i + 2
    min = i

    if lSide <= n - 1 and data[lSide] < data[min]:
        min = lSide
    if rSide <= n - 1 and data[rSide] < data[min]:
        min = rSide
    if i != min:
        data[i], data[min] = data[min], data[i]
        swaps.append((i, min))
        minHeap(data, n, min, swaps)

    return swaps

def main():

    inputs = input()
    if "I" in inputs:
        n = int(input())
        data = list(map(int, input().split()))
    elif "F" in inputs:
        inputs2 = input()
        if "a" not in inputs2:
            with open("./tests/"+inputs2, mode='r') as fails:
                n = int(fails.readline())
                data = list(map(int,fails.readline().split()))
    else:
        print("error")
        return

    assert len(data) == n

    swaps = build_heap(data)

    print(len(swaps))
    for i, j in swaps:
        print(i, j)

if __name__ == "__main__":
    main()


"""
Given the following matrix:
[
    [ 1, 2, 3 ],
    [ 4, 5, 6 ],
    [ 7, 8, 9 ]
]
You should return
[1, 2, 3, 6, 9, 8, 7, 4, 5]
"""

def iterate(matrix):
    for row_id, row in enumerate(matrix):
        if row_id % 2 == 0:
            print(row)
        else:
            print(row[::-1])

if __name__ == "__main__":
    mx = [ [ 1, 2, 3 ], [ 4, 5, 6 ], [ 7, 8, 9 ]]
    iterate(mx)


def calcular_frequencias(s):
    dicionario={}
    for k in s:
        if k in dicionario.keys():
            dicionario[k] += 1
        else:
            dicionario[k] = 1
    return dicionario

def gerar_arvore_de_huffman(s):
    dicionario = calcular_frequencias(s)
    for i, j in dicionario.items():
        char = i
        menor = j
        break
    for i, j in dicionario.items():
        if j <= menor:
            menor = j
            char = i
    dicionario.__delitem__(char)
    arvore = Arvore(char, menor)
    while len(dicionario.keys()) > 0:
        for i, j in dicionario.items():
            char = i
            menor = j
            break
        for i, j in dicionario.items():
            if j <= menor:
                char = i
                menor = j
        arvore = arvore.fundir(Arvore(char, menor))
        dicionario.__delitem__(char)
    return arvore

def codificar(cod_dict, s):
    c = ""
    for k in s:
        c = c + cod_dict[k]
    return c

class Noh:
    def __init__(self, peso):
        self.peso = peso
        self.direito = None
        self.esquerdo = None
        self.caminho = None
    def __hash__(self):
        return hash(self.peso)

    def __eq__(self, other):
        if other is None or not isinstance(other, Noh):
            return False
        return self.peso == other.peso and self.esquerdo == other.esquerdo and self.direito == other.direito

    def os(self):
        return "noh"

class Folha():
    def __init__(self, char, peso):
        self.char = char
        self.peso = peso
    def __hash__(self):
        return hash(self.__dict__)

    def __eq__(self, other):
        if other is None or not isinstance(other, Folha):
            return False
        return self.__dict__ == other.__dict__

    def os(self):
        return "folha"

class Arvore(object):
    def __init__(self, char = None, peso = None):
        self.dic = {}
        if char == None:
            self.raiz=None
        else:
            self.raiz = Folha(char,peso)

    def __hash__(self):
        return hash(self.raiz)

    def __eq__(self, other):
        if other is None:
            return False
        return self.raiz == other.raiz

    def decodificar(self,s):
        self.cod_dict()
        a = ""
        b = ""
        for k in s:
            b = b + k
            for c, d in self.dic.items():
                if d == b:
                    a = a + c
                    b = ""
        return a

    def fundir(self,arvore):
        arvoreNova = Arvore()
        arvoreNova.raiz = Noh(self.raiz.peso+arvore.raiz.peso)
        if self.raiz.peso > arvore.raiz.peso:
            arvoreNova.raiz.esquerdo = self.raiz
            arvoreNova.raiz.direito = arvore.raiz
        else:
            arvoreNova.raiz.direito = self.raiz
            arvoreNova.raiz.esquerdo = arvore.raiz
        return arvoreNova

    def cod_dict(self):
        c = ""

        cod_dict_rec("", self.dic, self.raiz)
        return self.dic

def cod_dict_rec(caminho, dic, vez):
    if vez.os() == "folha":
        dic[vez.char]=caminho
    else:
        cod_dict_rec(caminho + "0", dic, vez.esquerdo)
        cod_dict_rec(caminho + "1", dic, vez.direito)

import unittest
from unittest import TestCase

class CalcularFrequenciaCarecteresTestes(TestCase):
    def teste_string_vazia(self):
        self.assertDictEqual({}, calcular_frequencias(''))

    def teste_string_nao_vazia(self):
        self.assertDictEqual({'a': 3, 'b': 2, 'c': 1}, calcular_frequencias('aaabbc'))

class NohTestes(TestCase):
    def teste_folha_init(self):
        folha = Folha('a', 3)
        self.assertEqual('a', folha.char)
        self.assertEqual(3, folha.peso)

    def teste_folha_eq(self):
        self.assertEqual(Folha('a', 3), Folha('a', 3))
        self.assertNotEqual(Folha('a', 3), Folha('b', 3))
        self.assertNotEqual(Folha('a', 3), Folha('a', 2))
        self.assertNotEqual(Folha('a', 3), Folha('b', 2))

    def testes_eq_sem_filhos(self):
        self.assertEqual(Noh(2), Noh(2))
        self.assertNotEqual(Noh(2), Noh(3))

    def testes_eq_com_filhos(self):
        noh_com_filho = Noh(2)
        noh_com_filho.esquerdo = Noh(3)
        self.assertNotEqual(Noh(2), noh_com_filho)

    def teste_noh_init(self):
        noh = Noh(3)
        self.assertEqual(3, noh.peso)
        self.assertIsNone(noh.esquerdo)
        self.assertIsNone(noh.direito)

def _gerar_arvore_aaaa_bb_c():
    raiz = Noh(7)
    raiz.esquerdo = Folha('a', 4)
    noh = Noh(3)
    raiz.direito = noh
    noh.esquerdo = Folha('b', 2)
    noh.direito = Folha('c', 1)
    arvore_esperada = Arvore()
    arvore_esperada.raiz = raiz
    return arvore_esperada

class ArvoreTestes(TestCase):
    def teste_init_com_defaults(self):
        arvore = Arvore()
        self.assertIsNone(arvore.raiz)

    def teste_init_sem_defaults(self):
        arvore = Arvore('a', 3)
        self.assertEqual(Folha('a', 3), arvore.raiz)

    def teste_fundir_arvores_iniciais(self):
        raiz = Noh(3)
        raiz.esquerdo = Folha('b', 2)
        raiz.direito = Folha('c', 1)
        arvore_esperada = Arvore()
        arvore_esperada.raiz = raiz
        arvore = Arvore('b', 2)
        arvore2 = Arvore('c', 1)
        arvore_fundida = arvore.fundir(arvore2)
        self.assertEqual(arvore_esperada, arvore_fundida)

    def teste_fundir_arvores_nao_iniciais(self):
        arvore_esperada = _gerar_arvore_aaaa_bb_c()
        arvore = Arvore('b', 2)
        arvore2 = Arvore('c', 1)
        arvore3 = Arvore('a', 4)
        arvore_fundida = arvore.fundir(arvore2)
        arvore_fundida = arvore3.fundir(arvore_fundida)
        self.assertEqual(arvore_esperada, arvore_fundida)

    def teste_gerar_dicionario_de_codificacao(self):
        arvore = _gerar_arvore_aaaa_bb_c()
        self.assertDictEqual({'a': '0', 'b': '10', 'c': '11'}, arvore.cod_dict())

    def teste_decodificar(self):
        arvore = _gerar_arvore_aaaa_bb_c()
        self.assertEqual('aaaabbc', arvore.decodificar('0000101011'))

class TestesDeIntegracao(TestCase):
    def teste_gerar_arvore_de_huffman(self):
        arvore = _gerar_arvore_aaaa_bb_c()
        self.assertEqual(arvore, gerar_arvore_de_huffman('aaaabbc'))

    def teste_codificar(self):
        arvore = gerar_arvore_de_huffman('aaaabbc')
        self.assertEqual('0000101011', codificar(arvore.cod_dict(), 'aaaabbc'))
        self.assertEqual('aaaabbc', arvore.decodificar('0000101011'))
if __name__ == '__main__':
    unittest.main()


from PyQt5.QtCore import QPoint, QPointF
from PyQt5.QtWidgets import QWidget
from PyQt5.QtGui import QTransform, QPainter

class World2D(QWidget):
    """A Widget which has it's own 2D world space, onto which shapes can be drawn.
    """

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.world_transform = QTransform()
        self.zoom_base = 1.001
        self._is_mouse_down = False
        self._last_mouse_pos = QPoint()

    def inverse_world_transform(self):
        """Returns the inverted world_transform.
        """
        inverted, _ = self.world_transform.inverted()
        return inverted

    def world_painter(self, painter_class=QPainter):
        """Create a painter with the world transformation.

        Args:
            painter_class: You may specify a different class for the painter to be created. This
                should be a subclass of QPainter. Default is QPainter.
        """
        painter = painter_class()
        painter.begin(self)
        painter.setWorldMatrixEnabled(True)
        painter.setWorldTransform(self.world_transform)
        return painter

    def translate(self, dx, dy):
        """Translate the viewport.
        """
        self.world_transform.translate(dx, dy)
        self.update()

    def zoom(self, amount, center):
        """Scale the viewport around a center point.
        """
        self.world_transform.translate(center.x(), center.y())
        self.world_transform.scale(amount, amount)
        self.world_transform.translate(-center.x(), -center.y())
        self.update()

    def zoom_to_fit(self, bounding_box):
        """Set the scale to fit the bounding_box and center on it.
        """
        scale_x = self.width() / bounding_box.width()
        scale_y = self.height() / bounding_box.height()
        scale = min(scale_x, scale_y)

        dx = bounding_box.center().x()
        dy = bounding_box.center().y()

        self.world_transform = QTransform()
        self.world_transform.translate(self.width() / 2, self.height() / 2)
        self.world_transform.scale(scale, scale)
        self.world_transform.translate(-dx, -dy)
        self.update()

    def wheelEvent(self, wheel_event):
        super().wheelEvent(wheel_event)
        zoom_amount = self.zoom_base ** wheel_event.angleDelta().y()
        center = QPointF(wheel_event.pos()) * self.inverse_world_transform()
        self.zoom(zoom_amount, center)

    def mousePressEvent(self, mouse_event):
        super().mousePressEvent(mouse_event)
        self._last_mouse_pos = mouse_event.pos()

    def mouseMoveEvent(self, mouse_event):
        super().mouseMoveEvent(mouse_event)

        new_mouse_pos = mouse_event.pos()
        new_mouse_in_world = QPointF(new_mouse_pos) * self.inverse_world_transform()
        last_mouse_in_world = QPointF(self._last_mouse_pos) * self.inverse_world_transform()

        dx = new_mouse_in_world.x() - last_mouse_in_world.x()
        dy = new_mouse_in_world.y() - last_mouse_in_world.y()
        self.translate(dx, dy)

        self._last_mouse_pos = new_mouse_pos


print("Welcome to Weasleys’ Wizard Wheezes!")
name= input("What is your name?")
hatNumber= input ("How many Headless Hats do you want to buy, at 2 galleons \
each?")
boxingTelescopes= input("How many Boxing Telescopes do you want to buy, \
at 12 sickles 26 knuts each?")
canaryCreams= input("How many Canary Creams do you want to buy, at 7 sickles\
 each?")
hat=int(hatNumber)
box=int(boxingTelescopes)
cream=int(canaryCreams)
total=(hat*986+box*374+cream*203)
print("You're total is:", total, "Knuts.")
payment= input ("How many knuts are you paying with?")
pay=int(payment)
remainder= pay - total
print("Your change is ", remainder, " Knuts, paid as")
galleons=remainder//493
print(galleons, " galleons")
amount2 = remainder%493
sickles=amount2//29
print(sickles, " sickles")
knutschange= amount2%29
print(knutschange, " Knuts")
print("Thank you,", name)

#-------------------------------------------------------------------------------
# Name: Sean Gamble
# Project 1
# Section 002
# Due Date:9/7/2014
#-------------------------------------------------------------------------------
# Honor Code Statement: I received no assistance on this assignment that
# violates the ethical guidelines set forth by professor and class syllabus.
#-------------------------------------------------------------------------------
# References: Slides from Lab 2
#-------------------------------------------------------------------------------
# Comments and assumptions: A note to the grader as to any problems or
# uncompleted aspects of the assignment, as well as any assumptions about the
# meaning of the specification.
#-------------------------------------------------------------------------------
# NOTE: width of source code should be <= 80 characters to facilitate printing.
#2345678901234567890123456789012345678901234567890123456789012345678901234567890
# 10 20 30 40 50 60 70 80
#---------------------------------------------------------------------


import requests
import os
import json
import pandas as pd
import sys
from fileinput import filename
from google.cloud import bigquery

import logging
from sys import stdout
from datetime import datetime
import os
from pyspark.sql import SparkSession
from pyspark.sql import functions as f

bearer_token = ''
search_url = "https://api.twitter.com/2/tweets/search/recent"
max_results = "?max_results="
qtd_results = "50"
search_url_50 = search_url + max_results + qtd_results

query_params_palavras = {'query': 'Boticário maquiagem','expansions':'author_id','user.fields':'username,description'}
query_params_twitts_50 = {'query': 'Boticário','expansions':'author_id','user.fields':'username,description'}
query_params_twitts_port = {'query': 'Boticário lang:pt','expansions':'author_id','user.fields':'username,description'}

table_words = 'raw.tb_twitter_words'
table_portugues = 'raw.tb_twitter_portugues'
table_50 = 'raw.tb_twitter_50_recentes'
field_name = 'author_id'

p_tipo = sys.argv[1]

def config_log(flag_stdout=True, flag_logfile=False):
    handler_list = list()
    LOGGER = logging.getLogger(__name__)

    [LOGGER.removeHandler(h) for h in LOGGER.handlers]

    if flag_logfile:
        path_log = './logs/{}_{:%Y%m%d}.log'.format('log', datetime.now())
        if not os.path.isdir('./logs'):
            os.makedirs('./logs')
        handler_list.append(logging.FileHandler(path_log))

    if flag_stdout:
        handler_list.append(logging.StreamHandler(stdout))

    logging.basicConfig(
        level=logging.INFO\
        ,format='[%(asctime)s] {%(filename)s:%(lineno)d} %(levelname)s - %(message)s'\
        ,handlers=handler_list)
    return LOGGER

log = config_log()

def bearer_oauth(r):
    r.headers["Authorization"] = f"Bearer {bearer_token}"
    r.headers["User-Agent"] = "v2RecentSearchPython"
    return r

def connect_to_endpoint(url, params):
    response = requests.get(url, auth=bearer_oauth, params=params)
    if response.status_code != 200:
       raise Exception(response.status_code, response.text)
    return json.loads(response.text)

def save(df,table_id,field_name):
    client = bigquery.Client()
    job_config = bigquery.LoadJobConfig(schema=[
                 bigquery.SchemaField(field_name, "STRING"),
				 ], write_disposition="WRITE_TRUNCATE")
    client.load_table_from_dataframe(df, table_id, job_config=job_config)

def trata_reponse(search_url,query_params_palavras):
    log.info('iniciando')
    response = connect_to_endpoint(search_url, query_params_palavras)
    data_norm = pd.json_normalize(response['data'])
    users_norm = pd.json_normalize(response['includes']['users'])

    df_data=pd.DataFrame(data_norm)
    del df_data['id']

    df_users=pd.DataFrame(users_norm)
    del df_users['description']
    del df_users['username']
    df_users = df_users.rename(columns={'id': 'author_id'})

    df_final = df_data.merge(df_users, how='left', on=['author_id'])

    return df_final

def orquestrador_portugues():
    df_final = trata_reponse(search_url,query_params_twitts_port)
    return df_final

def orquestrador_palavras():
    df_final = trata_reponse(search_url,query_params_palavras)
    return df_final

def orquestrador_50():
    df_final = trata_reponse(search_url_50,query_params_twitts_50)
    return df_final

def main():
    print(p_tipo)
    if p_tipo=='palavras':
        log.info('palavras')
        df_palavras=orquestrador_palavras()
        save(df_palavras,table_words,field_name)
    elif p_tipo == '50':
        log.info('50')
        df_50=orquestrador_50()
        save(df_50,table_50,field_name)
    elif p_tipo == 'portugues':
        log.info('PORTUGUES')
        df_portugues=orquestrador_portugues()
        save(df_portugues,table_portugues,field_name)
    else:
        log.warning(f'Paraâmetro inválido:{p_tipo}')

if __name__ == '__main__':
    spark = SparkSession.Builder()\
                       .appName("Twitter")\
					   .getOrCreate()
    main()