from lib.mqtt import MQTTClient   # For use of MQTT protocol to talk to Adafruit IO
import time                   # Allows use of time.sleep() for delays
from adafruitIO import AdafruitIO    # Import the new AdafruitIO class
import ubinascii              # Conversions between binary data and various encodings
import machine                # Interfaces with hardware components
import micropython            # Needed to run any MicroPython code
import random                 # Random number generator
from machine import Pin       # Define pin
from secrets import secrets
import dht                 # import the builtin library

tempSensor = dht.DHT11(Pin(27))

# BEGIN SETTINGS
RANDOMS_INTERVAL = 10000    # milliseconds
last_random_sent_ticks = 0  # milliseconds
led = Pin("LED", Pin.OUT)   # led pin initialization for Raspberry Pi Pico W

# Adafruit IO (AIO) configuration
aio = AdafruitIO()    # Instantiate AdafruitIO object
AIO_SERVER = aio.get_server()
AIO_PORT = aio.get_port()
AIO_USER = aio.get_user()
AIO_KEY = aio.get_key()
AIO_CLIENT_ID = ubinascii.hexlify(machine.unique_id())
AIO_LIGHTS_FEED = aio.get_lights_feed()
AIO_RANDOMS_FEED = aio.get_randoms_feed()
AIO_TEMPERATURE_FEED = aio.get_temperature_feed()
AIO_HUMIDITY_FEED = aio.get_humidity_feed()

# END SETTINGS

# FUNCTIONS

# Function to connect Pico to the WiFi
def do_connect():
    import network
    from time import sleep
    import machine
    wlan = network.WLAN(network.STA_IF)         # Put modem on Station mode

    if not wlan.isconnected():                  # Check if already connected
        print('connecting to network...')
        wlan.active(True)                       # Activate network interface
        # set power mode to get WiFi power-saving off (if needed)
        wlan.config(pm = 0xa11140)
        wlan.connect(secrets["WIFI_SSID"], secrets["WIFI_PASS"])  # Your WiFi Credential
        print('Waiting for connection...', end='')
        # Check if it is connected otherwise wait
        while not wlan.isconnected() and wlan.status() >= 0:
            print('.', end='')
            sleep(1)
    # Print the IP assigned by router
    ip = wlan.ifconfig()[0]
    print('\nConnected on {}'.format(ip))
    return ip

# Callback Function to respond to messages from Adafruit IO
def sub_cb(topic, msg):          # sub_cb means "callback subroutine"
    print((topic, msg))          # Outputs the message that was received. Debugging use.
    if msg == b"ON":             # If message says "ON" ...
        led.on()                 # ... then LED on
    elif msg == b"OFF":          # If message says "OFF" ...
        led.off()                # ... then LED off
    else:                        # If any other message is received ...
        print("Unknown message") # ... do nothing but output that it happened.

# Function to generate a random number between 0 and the upper_bound
def random_integer(upper_bound):
    return random.getrandbits(32) % upper_bound

# Function to publish random number to Adafruit IO MQTT server at fixed interval
def send_random():
    global last_random_sent_ticks
    global RANDOMS_INTERVAL

    if ((time.ticks_ms() - last_random_sent_ticks) < RANDOMS_INTERVAL):
        return; # Too soon since last one sent.

    some_number = random_integer(100)
    tempSensor.measure()
    temperature = tempSensor.temperature()
    humidity = tempSensor.humidity()
    print("RANDOM: Publishing: {0} to {1} ... ".format(some_number, AIO_RANDOMS_FEED), end='')
    print("\nHUMIDITY: Publishing: {0} to {1} ... ".format(humidity, AIO_HUMIDITY_FEED), end='')
    print("\nTEMPERATURE: Publishing: {0} to {1} ... ".format(temperature, AIO_TEMPERATURE_FEED), end='')
    try:
        client.publish(topic=AIO_RANDOMS_FEED, msg=str(some_number))
        client.publish(topic=AIO_HUMIDITY_FEED, msg=str(humidity))
        client.publish(topic=AIO_TEMPERATURE_FEED, msg=str(temperature))
        print("DONE")
    except Exception as e:
        print("FAILED")
    finally:
        last_random_sent_ticks = time.ticks_ms()

# Try WiFi Connection
try:
    ip = do_connect()
except KeyboardInterrupt:
    print("Keyboard interrupt")

# Use the MQTT protocol to connect to Adafruit IO
client = MQTTClient(AIO_CLIENT_ID, AIO_SERVER, AIO_PORT, AIO_USER, AIO_KEY)

# Subscribed messages will be delivered to this callback
client.set_callback(sub_cb)
client.connect()
client.subscribe(AIO_LIGHTS_FEED)
print("Connected to %s, subscribed to %s topic" % (AIO_SERVER, AIO_LIGHTS_FEED))

try:                      # Code between try: and finally: may cause an error
                          # so ensure the client disconnects the server if
                          # that happens.
    while 1:              # Repeat this loop forever
        client.check_msg()# Action a message if one is received. Non-blocking.
        send_random()     # Send a random number to Adafruit IO if it's time.
finally:                  # If an exception is thrown ...
    client.disconnect()   # ... disconnect the client and clean up.
    client = None
    print("Disconnected from Adafruit IO.")


# coding:utf8
import visdom
import time
import numpy as np
import matplotlib.pyplot as plt

class Visualizer(object):
    """
    封装了visdom的基本操作，但是你仍然可以通过`self.vis.function`
    调用原生的visdom接口
    比如
    self.text('hello visdom')
    self.histogram(t.randn(1000))
    self.line(t.arange(0, 10),t.arange(1, 11))
    """

    def __init__(self, env='default', **kwargs):
        self.vis = visdom.Visdom(env=env,use_incoming_socket=False, **kwargs)

        # 画的第几个数，相当于横座标
        # 保存（’loss',23） 即loss的第23个点
        self.index = {}
        self.log_text = ''

    def reinit(self, env='default', **kwargs):
        """
        修改visdom的配置
        """
        self.vis = visdom.Visdom(env=env, **kwargs)
        return self

    def plot_many(self, d):
        """
        一次plot多个
        @params d: dict (name,value) i.e. ('loss',0.11)
        """
        for k, v in d.items():
            self.plot(k, v)

    def img_many(self, d):
        for k, v in d.items():
            self.img(k, v)

    def plot(self, name, y, **kwargs):
        """
        self.plot('loss',1.00)
        """
        x = self.index.get(name, 0)
        self.vis.line(Y=np.array([y]), X=np.array([x]),
                      win=name,
                      opts=dict(title=name),
                      update=None if x == 0 else 'append',
                      **kwargs
                      )
        self.index[name] = x + 1

    def scatter_reach(self, name, d):
        """
        画三维散点图
        """
        label = []
        label.append(1)
        for i in range(1, len(d)-1):
            label.append(2)
        label.append(3)
        win = self.vis.scatter(
            X=np.array(d),
            Y=np.array(label),
            win=name,
            opts=dict(
                title=name,
                legend=['start', 'action', 'target'],
                xtickmin=0.2,
                xtickmax=0.7,
                xtickstep=0.05,
                ytickmin=-0.3,
                ytickmax=0.3,
                ytickstep=0.05,
                ztickmin=0.0,
                ztickmax=0.55,
                ztickstep=0.05,
                markersize=5,
                height=500,
                width=500,
                markercolor=np.array([[255, 0, 0], [0, 255, 0], [0, 0, 255]]),
            )
        )
        return win

    def scatter_updata(self, win, d):
        self.vis.scatter(
            X=[d],
            win=win,
            update='new',
            opts=dict(
                markersize=15,
                markercolor=np.array([[0, 0, 255]]),
            )
        )

    def scatter_a(self, name ,d):
        """
        画三维点线图
        """
        x = []
        y = []
        z = []
        ax = plt.gca(projection="3d")
        for i in range(len(d)):
            x.append(d[i][0])
            y.append(d[i][1])
            z.append(d[i][2])
        # x, y, z = [1, 1.5, 3], [1, 2.4, 3], [3.4, 1.4, 1]
        ax.scatter(x, y, z, c='r')
        ax.plot(x, y, z, color='r')
        plt.title(name)
        self.vis.matplot(plt)

    def img(self, name, img_, **kwargs):
        """
        self.img('input_img',t.Tensor(64,64))
        self.img('input_imgs',t.Tensor(3,64,64))
        self.img('input_imgs',t.Tensor(100,1,64,64))
        self.img('input_imgs',t.Tensor(100,3,64,64),nrows=10)

        ！！！don‘t ~~self.img('input_imgs',t.Tensor(100,64,64),nrows=10)~~！！！
        """
        self.vis.images(img_.cpu().numpy(),
                        win=name,
                        opts=dict(title=name),
                        **kwargs
                        )

    def log(self, info, win='log_text'):
        """
        self.log({'loss':1,'lr':0.0001})
        """

        self.log_text += ('[{time}] {info} <br>'.format(
            time=time.strftime('%m%d_%H%M%S'),
            info=info))
        self.vis.text(self.log_text, win)

    def __getattr__(self, name):
        """
        自定义的plot,image,log,plot_many等除外
        self.function 等价于self.vis.function
        """
        return getattr(self.vis, name)


import whisper
import torch
import torchaudio
import ffmpeg
import subprocess
import os.path as osp

LANGUAGES = {
    "english": "en",
    "chinese": "zh",
    "german": "de",
    "spanish": "es",
    "russian": "ru",
    "korean": "ko",
    "french": "fr",
    "japanese": "ja",
    "portuguese": "pt",
    "turkish": "tr",
    "polish": "pl",
    "catalan": "ca",
    "dutch": "nl",
    "arabic": "ar",
    "swedish": "sv",
    "italian": "it",
    "indonesian": "id",
    "hindi": "hi",
    "finnish": "fi",
    "vietnamese": "vi",
    "hebrew": "iw",
    "ukrainian": "uk",
    "greek": "el",
    "malay": "ms",
    "czech": "cs",
    "romanian": "ro",
    "danish": "da",
    "hungarian": "hu",
    "tamil": "ta",
    "norwegian": "no",
    "thai": "th",
    "urdu": "ur",
    "croatian": "hr",
    "bulgarian": "bg",
    "lithuanian": "lt",
    "latin": "la",
    "maori": "mi",
    "malayalam": "ml",
    "welsh": "cy",
    "slovak": "sk",
    "telugu": "te",
    "persian": "fa",
    "latvian": "lv",
    "bengali": "bn",
    "serbian": "sr",
    "azerbaijani": "az",
    "slovenian": "sl",
    "kannada": "kn",
    "estonian": "et",
    "macedonian": "mk",
    "breton": "br",
    "basque": "eu",
    "icelandic": "is",
    "armenian": "hy",
    "nepali": "ne",
    "mongolian": "mn",
    "bosnian": "bs",
    "kazakh": "kk",
    "albanian": "sq",
    "swahili": "sw",
    "galician": "gl",
    "marathi": "mr",
    "punjabi": "pa",
    "sinhala": "si",
    "khmer": "km",
    "shona": "sn",
    "yoruba": "yo",
    "somali": "so",
    "afrikaans": "af",
    "occitan": "oc",
    "georgian": "ka",
    "belarusian": "be",
    "tajik": "tg",
    "sindhi": "sd",
    "gujarati": "gu",
    "amharic": "am",
    "yiddish": "yi",
    "lao": "lo",
    "uzbek": "uz",
    "faroese": "fo",
    "haitian creole": "ht",
    "pashto": "ps",
    "turkmen": "tk",
    "nynorsk": "nn",
    "maltese": "mt",
    "sanskrit": "sa",
    "luxembourgish": "lb",
    "myanmar": "my",
    "tibetan": "bo",
    "tagalog": "tl",
    "malagasy": "mg",
    "assamese": "as",
    "tatar": "tt",
    "hawaiian": "haw",
    "lingala": "ln",
    "hausa": "ha",
    "bashkir": "ba",
    "javanese": "jw",
    "sundanese": "su",
}

def load_audio(path):
    filename = osp.basename(path)
    filename = osp.splitext(filename)[0]
    path_converted = "files/" + filename + ".mp3"
    subprocess.run(
        ["ffmpeg", "-y", "-i", path, "-c:v", "copy", "-c:a", "libmp3lame", "-q:a", "4", path_converted],
        stdout=subprocess.DEVNULL,
        stderr=subprocess.DEVNULL,
    )

    waveform, sample_rate = torchaudio.load(path_converted)
    if sample_rate != 16000:
        waveform = torchaudio.transforms.Resample(sample_rate, 16000)(waveform)
    return waveform.squeeze(0)

model = whisper.load_model("base")
audio = load_audio("memo.m4a")
audio = whisper.pad_or_trim(audio)
mel = whisper.log_mel_spectrogram(audio).to(model.device)

language = LANGUAGES["english"]
configuration = {"beam_size": 5, "fp16": False, "task": "transcribe", "language": language}
options = whisper.DecodingOptions(**configuration)

result = whisper.decode(model, mel, options)
text = result.text
print(text)


from collections import defaultdict
import numpy as np
import torch
from torch_geometric.utils import add_self_loops

import source_embedding as S

def _to_w2w_lang(lang):
    if lang == 'zh':
        return 'zh_cn'
    return lang

class DHG:

    def __init__(self, dict_name='word2word', directed=True):
        self.directed = directed
        self.vocabs = defaultdict(dict)
        self.langs = []
        self.dictionary = defaultdict(dict)
        self.w2v_dict = {}
        self.dict_name = dict_name
        self.edges = None

    def add_lang(self, lang, w2v=None):

        if w2v is not None:
            print(f'load w2v: {w2v}, lang: {lang}')
            if w2v == 'rcsls':
                self.w2v_dict[lang] = S.FastTextAlignedEmbedding(lang)
            elif w2v == 'fasttext':
                self.w2v_dict[lang] = S.FastTextWikiEmbedding(lang)
            elif w2v.startswith('wk2v'):
                dim = int(w2v[4:])
                self.w2v_dict[lang] = S.Wikipedia2VecEmbedding(lang, dim)
            else:
                assert lang == 'en', 'invalid w2v'
                if w2v.startswith('glove'):
                    dim = int(w2v[5:])
                    self.w2v_dict[lang] = S.GloveEmbedding(
                        'wikipedia_gigaword', dim)
                elif w2v == 'crawl':
                    self.w2v_dict[lang] = S.GloveEmbedding('common_crawl_840')
                elif w2v == 'twitter':
                    self.w2v_dict[lang] = S.GloveEmbedding('twitter', 200)
                elif w2v == 'word2vec':
                    self.w2v_dict[lang] = S.Word2VecEmbedding()

        if len(self.langs) > 0:
            for lang2 in self.langs:
                if self.dict_name == 'word2word':
                    from word2word import Word2word
                    w2w_lang, w2w_lang2 = _to_w2w_lang(
                        lang), _to_w2w_lang(lang2)
                    self.dictionary[lang][lang2] = Word2word(
                        w2w_lang, w2w_lang2)
                    self.dictionary[lang2][lang] = Word2word(
                        w2w_lang2, w2w_lang)
        self.langs.append(lang)

    def _add_edges(self, source_lang, target_lang, dict_name=None):
        assert self.edges is not None, 'use this method via create_graph'
        lang, tlang = source_lang, target_lang
        if not self.directed:
            relation = f'{lang}-{tlang}' if lang < tlang else f'{tlang}-{lang}'
            rev_relation = relation
        else:
            relation = f'{lang}-{tlang}'
            rev_relation = f'{tlang}-{lang}'
        if dict_name is not None:
            relation += f'_{dict_name}'
            rev_relation += f'_{dict_name}'
        w2w = self.dictionary[source_lang][target_lang]

        for word, sword_id in sorted(self.vocabs[lang].items(), key=lambda x: x[1]):
            if word not in w2w.word2x:
                continue
            for tword in w2w(word):
                if (tword not in self.vocabs[tlang]) and (tlang in self.w2v_dict) and (tword in self.w2v_dict[tlang]):
                    self.vocabs[tlang][tword] = len(self.vocabs[tlang])
                if tword not in self.vocabs[tlang]:
                    continue
                tword_id = self.vocabs[tlang][tword]
                self.edges[tlang][lang][relation][tword_id][sword_id] = 1
                if not self.directed:
                    self.edges[lang][tlang][rev_relation][sword_id][tword_id] = 1

    def create_graph(self, to_first_only=True):
        self.edges = defaultdict(
            lambda: defaultdict(
                lambda: defaultdict(
                    lambda: defaultdict(dict)
                )
            )
        )

        for lang in self.langs:
            for tlang in self.dictionary[lang]:
                if to_first_only and (lang != self.langs[0] and tlang != self.langs[0]):
                    continue
                self._add_edges(lang, tlang)

    def get_graph_data(self, self_loop=True, reverse=False):
        assert self.edges is not None, 'call create_graph before getting graph data'

        offset = []
        _offset = 0
        node_type = []
        for i, lang in enumerate(self.langs):
            offset.append(_offset)
            num_vocab = max(self.vocabs[lang].values()) + 1
            _offset += num_vocab
            node_type.append((torch.ones(num_vocab) * i).long())
        offset.append(_offset)
        node_type = torch.cat(node_type)

        relation2id = {}
        lang2id = {lang: i for i, lang in enumerate(self.langs)}
        relation_langs = []

        pairs = defaultdict(list)

        n_true_edges = 0
        for tlang in self.langs:
            t_offset = offset[lang2id[tlang]]
            for slang in sorted(self.edges[tlang].keys()):
                s_offset = offset[lang2id[slang]]
                for relation in sorted(self.edges[tlang][slang].keys()):
                    if relation not in relation2id:
                        relation2id[relation] = len(relation2id)
                        if reverse:
                            relation_langs.append(
                                (lang2id[tlang], lang2id[slang]))
                        else:
                            relation_langs.append(
                                (lang2id[slang], lang2id[tlang]))
                    rid = relation2id[relation]
                    for tword_id in self.edges[tlang][slang][relation]:
                        tid = tword_id + t_offset
                        for sword_id in self.edges[tlang][slang][relation][tword_id]:
                            sid = sword_id + s_offset
                            if reverse:
                                pairs[(tid, sid)].append(rid)
                            else:
                                pairs[(sid, tid)].append(rid)
                            n_true_edges += 1

        print(relation2id)
        edge_index = []
        edge_type = []

        def _add_edge(sid, tid, r_list, rev_list):
            for rid in r_list:
                edge_index.append([sid, tid])
                edge_type.append(rid)
            for rid in rev_list:
                edge_index.append([tid, sid])
                edge_type.append(rid)

        while len(pairs) > 0:
            pair, r_list = pairs.popitem()
            sid, tid = pair
            rev_list = pairs.pop((tid, sid)) if (tid, sid) in pairs else []
            _add_edge(sid, tid, r_list, rev_list)

        node_lang = {}
        for lang, stoi in self.vocabs.items():
            for i in stoi.values():
                node_lang[i + offset[lang2id[lang]]] = lang

        edge_index = torch.LongTensor(edge_index).t()
        edge_type = torch.LongTensor(edge_type)

        if self_loop:
            edge_index, edge_type = add_self_loops(
                edge_index, edge_weight=edge_type, fill_value=len(relation2id))
        offset = torch.LongTensor(offset)
        relation_langs = torch.LongTensor(relation_langs)
        return edge_index, edge_type, node_type, offset, relation_langs

    def get_pretrain(self):
        pretrains = []
        for lang in self.langs:
            if lang not in self.w2v_dict:
                pretrains.append(None)
                continue
            num_vocab = max(self.vocabs[lang].values()) + 1
            pretrain = None
            for w, wid in self.vocabs[lang].items():
                vec = torch.from_numpy(np.array(self.w2v_dict[lang][w]))
                if pretrain is None:
                    pretrain = vec.new_zeros([num_vocab, vec.numel()])
                pretrain[wid] = vec
            pretrains.append(pretrain)
        return pretrains

    def dump_w2v_temp(self):
        for w2v in self.w2v_dict.values():
            if isinstance(w2v, S.Embedding):
                w2v.dump_temp_query()


import os
from io import BytesIO
from flask import Flask, request, send_from_directory, send_file, jsonify
from flask_pymongo import PyMongo
from PIL import Image
import numpy as np
import glob
import json
import subprocess
import skimage

app = Flask(__name__, static_url_path='/static', static_folder = "./frontend/public")
# This is the app.config I used
# app.config['MONGO_URI'] = "mongodb://host.docker.internal:27017/main"
app.config['MONGO_URI'] = "mongodb://%s:27017/main"%(os.environ['DB_PORT_27017_TCP_ADDR'])

mongo = PyMongo(app)
db = mongo.db

def display_array(arr):
    """
    Display an image represented as an array
    """
    img = Image.fromarray(arr.astype(np.uint8))
    bytesIO = BytesIO()
    img.save(bytesIO, 'PNG')
    bytesIO.seek(0)
    return bytesIO

def convert_to_array(path):
    """
    Converts an image file to an array for later processing
    """
    image_file = Image.open(path).convert("RGB")
    image_array = np.array(image_file)
    return image_array

def apply_grayscale_filter(img_data):
    """
    Converts a colored image to grascale
    """
    for i in range(len(img_data)):
        for j in range(len(img_data[i])):
            blue = img_data[i, j, 0]
            green = img_data[i, j, 1]
            red = img_data[i, j, 2]

            greyscale = blue * 0.114 + green * 0.587 + red * 0.299
            img_data[i, j] = greyscale

    return img_data

def crop_image(img_data):
    """
    Crops the image to the maximum square crop from the centre of the image
    """
    img_data = apply_grayscale_filter(img_data)
    y, x, z = img_data.shape
    if x == y:
        return img_data
    if x > y:
        x_crop = x - y
        cropped_data = img_data[: , x_crop // 2: x - x_crop // 2]
        return cropped_data
    elif y > x:
        y_crop = y - x
        cropped_data = img_data[y_crop // 2: y - y_crop // 2, :]
        return cropped_data

def crop_for_normalizing(np_data):
    """
    Crops the image dimensions to the highest multiple of 32 for creating 32 x 32 patches
    """
    y, x, z = np_data.shape

    if y % 2 != 0:
        y -= 1
    if x % 2 != 0:
        x -= 1
    x_crop = x % 32
    y_crop = y % 32

    cropped_data = np_data[y_crop // 2: y - y_crop // 2, x_crop // 2: x - x_crop // 2]

    return cropped_data

def downsample_image(img_data, x, filtertype):
    """
    Converts the image data to grayscale first, then resizes the image down by the donwsample factor x provided
    """
    if filtertype != "original":
        img_data = apply_grayscale_filter(img_data)
    img = Image.fromarray(img_data)
    new_width = int(img_data.shape[1] // x)
    new_height = int(img_data.shape[0] // x)
    new_dimensions = (new_width, new_height)

    # Downsizing the image using the nearest neighbour resampling method
    downsampled_img = img.resize(new_dimensions, resample=Image.NEAREST)

    return np.asarray(downsampled_img)

def normalize_data(img_data):
    """
    This method performs the following operation in order to transform the image data:

    1.  Splits up the image into multiple 32x32 patches
    2.  For each patch, computes the mean and standard deviation of image values
    3.  Computes u = median of the means and v = median of the standard deviations** of all patches
    4.  Rescales the image values so that the minimum value of u - 3*v and the maximum value of u + 3*v map to 0 and 255
        respectively
    """
    crop_data = crop_for_normalizing(img_data)
    img_data = apply_grayscale_filter(crop_data)

    patches = skimage.util.view_as_blocks(img_data, (32, 32, 3))
    avg = []
    std = []

    for patch in patches:
        patch_matrix = patch[0][0]
        avg.append(np.mean(patch_matrix))
        std.append(np.std(patch_matrix))

    u = np.median(avg)
    v = np.median(std)
    upper_limit = u + 3 * v
    lower_limit = u - 3 * v

    def mapping_func(i):
        if i < lower_limit:
            return 0
        if i > upper_limit:
            return 255
        else:
            return i

    contrast_normalize = np.vectorize(mapping_func)
    normalized_data = contrast_normalize(img_data)

    return normalized_data.astype(np.uint8)

def power_spectrum(img_data):
    """
    Takes the largest square crop from the centre of the image. Then, computes the Fourier transform of that cropped
    image, takes the square of the absolute value of each (complex valued) Fourier component, normalizes to the range
    0-255, and returns the result.
    """
    img_data = crop_image(img_data)
    fourier_transform = np.fft.fft(img_data)
    fourier_transform_squared = np.square(np.abs(fourier_transform))

    return normalize_data(fourier_transform_squared)

@app.route("/", defaults={'path': ''})
@app.route("/<path:path>")
def base(path):
  return send_from_directory('frontend/public', 'index.html')

@app.route("/api/populate_database", methods=['GET'])
def populate_database():
    """
    Finds all images files of type .png inside the assets folder and for each image, inserts into the database images
    collection a document with the following fields:
    file_name, width, height, area, size_bytes
    Creates an index on the 'width' field for better search and sorting performance.
    """
    if request.method == "GET":
        file_path = "./assets/"
        img_files = glob.glob(file_path + "*.png")
        img_documents = []

        for img_file in img_files:
            img_size = os.stat(img_file).st_size
            img = Image.open(img_file)
            width, height = img.size
            img_document = {
                "file_name": str(img_file.replace(file_path, "")),
                "width": width,
                "height": height,
                "area": width * height,
                "size_bytes": img_size
            }
            img_documents.append(img_document)

        db.images.insert_many(img_documents)
        # Creating an index on the "width" field
        db.images.create_index("width")
        response = "database populated successfully"

        return jsonify(response), 201

@app.route("/api/all", methods=['GET'])
def image_content():
    """
    Serves all the contents of the images collection in JSON format.
    """
    if request.method == "GET":
        all_images = db.images.find({}, {'_id': False})
        img_info_list = [img for img in all_images]

        return json.dumps(img_info_list)

@app.route("/api/query", methods=['GET'])
def get_images():
    """
    Serves a list of all available image file names, that match query parameters of maximum width, minimum area and
    maximum image size in bytes.
    """
    if request.method == "GET":
        parameters = request.args

        max_width = int(parameters['max_width'])
        min_area = int(parameters['min_area'])
        max_size_bytes = int(parameters['max_size_bytes'])

        images = db.images.find({"width": {"$lte": max_width}, "area": {"$gte": min_area}, "size_bytes": {"$lte": max_size_bytes}},
                                {"file_name": True, "_id": False})
        img_list = [img["file_name"] for img in images]

        return json.dumps(img_list)

@app.route("/api/filter/<imagename>/<filtertype>", methods=['GET'])
def transform_image(imagename, filtertype):
    """
    Transforms the image based on the following filters:

    1. `original`: returns the original image as a png
    2. `grayscale`: returns the grayscale version of the image as a png
    3. `crop`: returns the largest possible square crop from the center of the image
    4. `downsample`: returns a `value` downsampled version of the image (i.e. if value=1.5, the output is 1.5x smaller
        than the input)
    5. `normalize`: performs robust contrast normalization using patches
    """
    if request.method == "GET":
        # x is the factor by which the image will be scaled
        try:
            x = float(request.args.get("value"))
        except TypeError:
            x = None

        # Check if full image name is provided, else and the '.png' extension
        if imagename[-4:] != ".png":
            imagename += ".png"
        file_path = "./assets/" + imagename
        img_data = convert_to_array(file_path)

        if filtertype == "original":
            img_data = img_data
        if filtertype == "grayscale":
            img_data = apply_grayscale_filter(img_data)
        if filtertype == "crop":
            img_data = crop_image(img_data)
        if filtertype == "normalize":
            img_data = normalize_data(img_data)
        if filtertype == "power_spectrum":
            img_data = power_spectrum(img_data)
        if x and x != 0:
            img_data = downsample_image(img_data, x, filtertype)

        return send_file(display_array(img_data), mimetype="png")

@app.route("/api/backup", methods=['GET'])
def generate_backup():
    """
    Uses the subprocess module to call zip to create a zip of all the images in the 'assets' directory and store it in
    the 'backups' directory
    """
    if request.method == "GET":
        dir = os.path.dirname(os.path.abspath(__file__))
        # The instructions refer to the 'images' directory, but the assignment directory name is set to 'assets'
        file_path1 = "assets"
        file_path2 = os.path.join(dir, "backups/")
        zip_file_name = "assets"

        command = [f"zip -r {zip_file_name}.zip {file_path1}; mv {zip_file_name}.zip {file_path2}"]
        process = subprocess.run(command, shell=True, capture_output=True)

        if process.returncode == 0:
            return jsonify("back up complete"), 200
        else:
            return jsonify("back up failed"), 417

if __name__ == "__main__":
  app.run(host='0.0.0.0', debug=True)


#https://discordpy.readthedocs.io/en/latest/api.html
#API for Discord.py

import discord
import asyncio
from datetime import *
import time

import asyncio
import websockets
import json

LAST_CHANNEL = {} # keeps track of the last place a useer messaged

class MyClient(discord.Client):

    #ON MESSAGE
    # Function is called whenever the bot sees a message
    async def on_message(self,message):
        if(message.content.startswith("e!")): # If message starts with e!
            LAST_CHANNEL[message.author.id] = message.channel
            LAST_CHANNEL[self.user.id] = message.channel
            await self.process_commands(message)
        if(message.author.id == self.user.id): # save last place bot messaged
            LAST_CHANNEL[self.user.id] = message.channel

    #PROCESS COMMANDS
    # Parse the command message, run the correct command
    async def process_commands(self,message):
        command = message.content.split()[0].lower()

        #ADMIN COMMANDS
        if(command == "e!ping"):
            pass
            #await self.ping(message)
        elif(command == "e!add_repo"):
            await self.admin_add_repo(message)
        elif(command == "e!add_user"):
            await self.admin_add_user(message)

        #USER COMMANDS
        elif(command == "e!switch"):
            await self.switch(message)
        elif(command == "e!commit"):
            await self.commit(message)
        elif(command == "e!update"):
            await self.update(message)
        elif(command == "e!checkout"):
            await self.checkout(message)
        elif(command == "e!add"):
            await self.add(message)
        elif(command == "e!remove"):
            await self.remove(message)

    # Admin command to add a repo to the database
    async def admin_add_repo(self,message):
        start = time.time()
        command = message.content.split()
        if(len(command) != 2):
           await message.channel.send("Invalid usage: `add_repo`")
           return
        print("Adding new repo:",command[1])
        await self.websocket.send(json.dumps({"command":"admin_add_repo","url":command[1],"id":str(message.author.id)}))

    # Admin command to grant a user access to a repo
    async def admin_add_user(self,message):
        start = time.time()
        command = message.content.split()
        if(len(command) < 3):
            await message.channel.send("Invalid usage: `add_user`")
            return
        print("Adding user(s):",command[2:],"to repo:",command[1])
        ids = [x.id for x in message.mentions]
        await self.websocket.send(json.dumps({"command":"admin_add_user","users":ids,"repo":command[1],"id":str(message.author.id)}))

    # Command to switch a user's current working repo
    async def switch(self,message):
        start = time.time()
        command = message.content.split()
        if(len(command) != 2):
            await message.channel.send("Invalid usage: `switch`")
            return
        print("Switching",message.author.name,"to repo",command[1])
        await self.websocket.send(json.dumps({"command":"switch","repo":command[1],"id":str(message.author.id)}))

    # Command to have the client commit your repo
    async def commit(self,message):
        start = time.time()
        msg = " ".join(message.content.split()[1:])
        print("Telling",message.author.name,"to commit")
        await self.websocket.send(json.dumps({"command":"commit","message":msg,"id":str(message.author.id)}))

    # Command to have the client update your repo
    async def update(self,message):
        start = time.time()
        #target = message.content.split()[1]
        print("Telling",message.author.name,"to update")
        await self.websocket.send(json.dumps({"command":"update","id":str(message.author.id)}))

    # Command to checkout a repo to the set working directory
    async def checkout(self,message):
        start = time.time()
        print("Telling",message.author.name,"to update")
        await self.websocket.send(json.dumps({"command":"checkout","id":str(message.author.id)}))

    # Command to ping all clients. Currently disabled
    async def ping(self,message):
        await self.websocket.send(json.dumps({"command":"ping","id":str(message.author.id)}))

    # Command to have a client add files to repo
    async def add(self,message):
        start = time.time()
        print("Sending add command")
        await self.websocket.send(json.dumps({"command":"add","id":str(message.author.id),"files":message.content.split()[1:]}))

    # Command to have a client remove files from a repo
    async def remove(self,message):
        start = time.time()
        print("Sending remove command")
        await self.websocket.send(json.dumps({"command":"remove","id":str(message.author.id),"files":message.content.split()[1:]}))

    #WHEN READY
    # Function runs when the bot first connects to Discord's server
    async def on_ready(self):
        await self.change_presence(activity=discord.Game(name = "game"))
        print("Successfully set Bot's game status")

        while(not self.is_closed()): #Main loop, gets messages from websocket and parses them
            try:
                #Connect to server
                self.websocket = await websockets.connect(uri)
                await self.websocket.send("888218725810049055")
                status = json.loads(await self.websocket.recv())

                default_list = json.loads(await self.websocket.recv())
                print(default_list)

                # Loop through sent messages
                async for message in self.websocket:
                    data = json.loads(message)
                    if(data["command"] == "send"): # If server told bot to send a message
                        try:
                            await LAST_CHANNEL[int(data["id"])].send(self.get_user(int(data["id"])).mention+ " "+data["message"])
                        except KeyError:
                            await LAST_CHANNEL[self.user.id].send(self.get_user(int(data["id"])).mention+ " "+data["message"])
                    elif(data["command"] == "ping_client"): # Ping response. Currently unused
                        pass
                        #await self.websocket.send(json.dumps({"command":"ping_response"}))
                    else:
                        print("UNHANDLED COMM:",data)

            # If error occurs, wait 1 second and reconnect
            except Exception as e:
                print("Waiting due to:",e)

                await asyncio.sleep(1)

    #CONNECTION
    async def on_connect(self):
        print("Bot has connected to server at time:",datetime.now())

    #DISCONNECTION
    async def on_disconnect(self):
        print("Bot has disconnected from server at time:",datetime.now())

# Set variables needed for bot to run
uri = "ws://192.168.1.231:6969"
print("Starting Bot")
bot = MyClient(intents=discord.Intents.all())
file = open("TOKEN.txt",'r')
TOKEN = file.read()
file.close()

# Start Bot
bot.run(TOKEN)


"""Models for the users app."""
from django.db import models
from django.contrib.auth.models import User

class Profile(models.Model):
    """
    Created profile model for users.

    Every user will have profile. If the user is deleted the profile will also
    be deleted.
    """

    user = models.OneToOneField(
        User,
        on_delete=models.CASCADE
    )
    image = models.ImageField(
        default='profilepic.jpg',
        upload_to='profile_pictures'
    )
    location = models.CharField(
        max_length=100
    )

    def __str__(self):
        """Represent the profile object as a string."""
        return self.user.username


import django_filters
from django_filters import DateFilter

from django import forms

from .models import *

class DateInput(forms.DateInput):
    input_type = 'date'

class ExpenseFilter(django_filters.FilterSet):
    start_date = DateFilter(field_name="transaction_date", lookup_expr='gte')
    end_date = DateFilter(field_name="transaction_date", lookup_expr='lte')

    class Meta:
        model = Expense
        fields = '__all__'
        exclude = ['image', 'description', 'date_created',
                   'amount', 'transaction_date', 'title']
        # widgets = {
        #     'transaction_date': forms.DateField(attrs={'type': 'date'})
        # }


# Import necessary libraries
import pandas as pd
from sklearn.ensemble import RandomForestRegressor
from sklearn.model_selection import train_test_split
import pickle
from flask import Flask, render_template, request

# Load the data
data = pd.read_csv('df.csv')

# Split the data into training and testing sets
X = data[['bookid']]
y = data['rating']
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)

# Train the model
model = RandomForestRegressor()
model.fit(X_train, y_train)

# Save the model to a pickle file
with open('model.pkl', 'wb') as f:
    pickle.dump(model, f)

# Create a Flask app
app = Flask(__name__)

# Define a route to render the form
@app.route('/')
def form():
    return render_template('form.html')

# Define a route to predict the rating
@app.route('/predict', methods=['POST'])
def predict():
    # Get the book_id from the form
    book_id = request.form['bookid']

    # Use the model to make a prediction
    prediction = model.predict([[book_id]])

    # Return the prediction as a response
    return render_template('result.html', prediction=prediction[0])

if __name__ == '__main__':
    app.run(debug=False,host='0.0.0.0')


from cProfile import label
from ctrl_env import CtrlEnv
import matplotlib.pyplot as plt
import numpy as np

env = CtrlEnv()

X,Y =[],[]
for x in range(-3,3):
    Y.append(np.absolute(x))
    X.append(x)

plt.plot(X,Y)
plt.show()
input('ok')

i=0
l, t, r, z, x = [], [], [], [], []
for ref in range (-3,3):
    for x0 in range(-3,3):
        env.reset(x0=x0, ref=ref)
        for x1 in range(-5,5):
            _,d = env.done(x1, i)
            if d:
                l.append(0.5)
            else:
                l.append(0)
            r.append(ref)
            z.append(x0)
            x.append(x1)
            t.append(i)
            i+=1

plt.plot(t,l, label='dones')
plt.plot(t,r, label='Ref')
plt.plot(t,z, label='X0')
plt.plot(t,x, label='x0')
plt.grid()
plt.legend()
plt.show()
input('ok?')


import birdy.twitter
import pydash
import requests

from django.conf import settings

FACEBOOK_API_URL = 'https://graph.facebook.com/v3.2/'
GOOGLE_API_URL = 'https://www.googleapis.com/'
INSTAGRAM_API_URL = 'https://api.instagram.com/v1/'

__all__ = (
    'facebook_retrieve_user',
    'google_retrieve_user',
    'instagram_retrieve_user',
    'twitter_retrieve_user',
)

def facebook_retrieve_user(access_token: str) -> dict:
    """
    Retrieve facebook user information
    :param access_token:
    :return: dict
    """
    fields = 'id', 'first_name', 'last_name', 'email', 'picture{url}'
    endpoint = 'me?fields={}'.format(','.join(fields))
    endpoint += f'&access_token={access_token}'

    response = requests.get(FACEBOOK_API_URL + endpoint)

    if response.status_code == 200:
        user = response.json()
        result = dict(
            provider_id=user['id'],
            email=user.get('email', f'{user["id"]}@facebook.com'),
            avatar_url=f'https://graph.facebook.com/{user["id"]}/picture?width=250',
            first_name=user['first_name'],
            last_name=user['last_name'],
        )
    else:
        result = dict(error=pydash.get(response.json(), 'error.message'))

    return result

def google_retrieve_user(access_token: str) -> dict:
    """
    Retrieve google user information
    :param access_token:
    :return: dict
    """
    endpoint = 'oauth2/v2/userinfo'

    response = requests.get(
        GOOGLE_API_URL + endpoint,
        headers={'Authorization': f'Bearer {access_token}'},
    )

    if response.status_code == 200:
        user = response.json()
        result = dict(
            provider_id=user['id'],
            email=user['email'],
            avatar_url=user['picture'],
            first_name=user['given_name'],
            last_name=user['family_name'],
        )
    else:
        result = dict(error=response.json().get('error_description', None))

    return result

def instagram_retrieve_user(access_token: str) -> dict:
    """
    Retrieve instagram user information
    :param access_token:
    :return: dict
    """
    endpoint = f'users/self/?access_token={access_token}'

    response = requests.get(INSTAGRAM_API_URL + endpoint)

    if response.status_code == 200:
        user = response.json()['data']

        try:
            f_name, l_name = user['full_name'].split(' ', 1)
        except ValueError:
            f_name = user['full_name']
            l_name = user['full_name']

        result = dict(
            provider_id=user['id'],
            avatar_url=user['profile_picture'],
            first_name=f_name,
            last_name=l_name,
        )
    else:
        result = dict(error=pydash.get(response.json(), 'meta.error_message', None))

    return result

def twitter_retrieve_user(oauth_token: str, oauth_token_secret: str) -> dict:
    """
    Retrieve twitter user information
    :type oauth_token: str
    :type oauth_token_secret: str
    :return: dict
    """
    client = birdy.twitter.UserClient(
        settings.SOCIAL_TWITTER_CONSUMER_KEY,
        settings.SOCIAL_TWITTER_CONSUMER_SECRET,
        oauth_token, oauth_token_secret,
    )

    response = client.api['account']['verify_credentials'].get()

    try:
        first_name, last_name = response.data.get('name').split(' ', 1)
    except (ValueError, AttributeError):
        first_name = last_name = None

    return dict(
        provider_id=response.data.get('id'),
        avatar_url=response.data.get('profile_image_url_https'),
        first_name=first_name,
        last_name=last_name,
    )


from bs4 import BeautifulSoup
import requests
import os
import io
import pandas as pd
from datetime import datetime
from tqdm import tqdm

CERMAT_URL = "https://vysledky.cermat.cz/data/Default.aspx"

headers = {
    'Access-Control-Allow-Origin': '*',
    'Access-Control-Allow-Methods': 'GET',
    'Access-Control-Allow-Headers': 'Content-Type',
    'Access-Control-Max-Age': '3600',
    'User-Agent': 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:52.0) Gecko/20100101 Firefox/52.0'
}

def get_option_values(selector):
    return [option["value"] for option in soup.select(selector) if option["value"] != "X"]

def request_data(soup, year, region, course, exam):
    fname = f"backup_{year}_{region}_{course}_{exam}.html"

    content = None
    if not os.path.exists(fname):
        url = CERMAT_URL
        payload = {
            "__EVENTTARGET": "upParametry",
            "__EVENTARGUMENT": "DZ",
            "__VIEWSTATE": soup.select("#__VIEWSTATE")[0]["value"],
            "__VIEWSTATEGENERATOR": soup.select("#__VIEWSTATEGENERATOR")[0]["value"],
            "__VIEWSTATEENCRYPTED": soup.select("#__VIEWSTATEENCRYPTED")[0]["value"],
            "__EVENTVALIDATION": soup.select("#__EVENTVALIDATION")[0]["value"],
            "ctl00$LeftContent$ddRok": year,
            "ctl00$LeftContent$ddKraj": region,
            "ctl00$LeftContent$ddPredmet": course,
            "ctl00$LeftContent$ddDilciZkouska": exam
        }
        req = requests.post(url, data=payload, headers = headers)
        with io.open(fname, mode = "w", encoding="utf8") as f:
            f.write(req.text)
        content = req.text
    else:
        with io.open(fname, mode = "r", encoding="utf8") as f:
            content = f.read()

    excel_name =  f"cermat_maturita_{year}_{region}_{course}_{exam}.xlsx"
    return store_table_as_excel(excel_name, content)

def store_table_as_excel(file_name, page_content):
    soup = BeautifulSoup(page_content, 'html.parser')
    rows = soup.select("#table tr")

    header = ["REDIZO", "Název školy", "Kraj"]
    for cell in rows[1].select("th"):
        header.append(cell.text.strip())

    data = []
    for row in rows[2:]:
        row_data = []
        cells = row.select("td")

        # Skip aggregations at the top of the table
        if len(cells) < 20:
            continue

        for cell in cells[1:]:
            row_data.append(cell.text)
        data.append(row_data)

    df = pd.DataFrame(data, columns = header)
    df.to_excel(file_name, index = False)
    return df

req = requests.get(CERMAT_URL, headers)
soup = BeautifulSoup(req.content, 'html.parser')

years = get_option_values("#ddRok option")
regions = get_option_values("#ddKraj option")
courses = get_option_values("#ddPredmet option")
exams = get_option_values("#ddDilciZkouska option")

iterations = []
for year in years:
    for region in regions:
        for course in courses:
            for exam in exams:
                iterations.append((year, region, course, exam))

dataframes = []
for  year, region, course, exam in tqdm(iterations):
    df = request_data(soup, year, region, course, exam)
    df["Rok"] = year
    df["Předmět"] = course
    df["Dílčí zkouška"] = exam
    dataframes.append(df)

final_filename = f"maturita_{datetime.today().strftime('%d-%m-%Y')}.xlsx"
final_df = pd.concat(dataframes)
final_df.to_excel(final_filename, index = False)
print(f"Collected {len(dataframes)} dataframes with {len(final_df.index)} rows and joined them into {final_filename}.")


import json
import socket
import time
from struct import pack
from threading import Thread
from argparse import ArgumentParser
from datetime import datetime

endpoint_addr = '127.0.0.1'

def apply():
    packet = json.dumps({'type':'ack','priority':150,'task':'add Host'})
    dst = '10.255.255.255'
    with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as s:
        print("Sending UDP Packet")
        s.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
        s.sendto(str.encode(packet),('10.255.255.255',2100))

def alive():
    for i in range(100):
        time.sleep(5)
        packet = json.dumps({'type':'ack','priority':150,'task':'I am here'})
        dst = '10.255.255.255'
        with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as s:
            s.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
            s.sendto(str.encode(packet),(dst,2100))

def listen():
    dst = '10.255.255.255'
    while(True):
        task_addr = ''
        with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as s:
            s.bind(("",1900))
            # s.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
            data, addr = s.recvfrom(1024)
            str_data = data.decode()
            print(str_data, addr)

        # Check if we got a valid job description

        json_data = json.loads(str_data)
        result_req_time = json_data.get('time')
        result_port = json_data.get('port')
        if result_req_time is None or result_port is None:
            continue
        print(str_data)
        task_addr = (addr[0],json_data['port'])

        busy(json_data['time'])
        if json_data["task"] == 'prime_check':
            num, start, end = json_data["task_desc"]
            prime_result = primality_check(num,start,end)
        packet = json.dumps({'type':'result','priority':150,'task':'prime_check', "time": json_data["time"], "result": prime_result})
        result(packet, task_addr)
        apply()

def primality_check(num, start, end):

    for i in range(start, end):
        if i == 1:
            continue
        if num%i == 0:
            return False
    return True

def busy(time_stamp):
    packet = json.dumps({'type':'busy','priority':100,'time':time_stamp})
    dst = '10.255.255.255'
    with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as s:
        print("Sending UDP Packet for Busy")
        s.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
        s.sendto(str.encode(packet),(dst,1900))

def result(packet, task_addr):
    # dst = '10.255.255.255'
    with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as s:
        print("Announcing Result")
        s.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
        s.sendto(str.encode(packet),(task_addr))

def exit():
    packet = json.dumps({'type':'nak','priority':150,'task':'del Host'})
    dst = '10.255.255.255'
    with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as s:
        print("Sending UDP Packet for Exit")
        s.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
        s.sendto(str.encode(packet),(dst,1900))

if __name__ == '__main__':
    apply()
    t1 = Thread(target=alive)
    t1.start()
    listen_thread = Thread(target=listen)
    listen_thread.start()
    print('My work is done')


import time
from pathlib import Path
import pandas as pd
import cv2
from skimage import transform
from src import radon, iradon

if __name__ == '__main__':
    imagePath = Path('res')
    file_name_list = list(imagePath.glob('shepp-logan*.jpg'))

    method_list = ['my algorithm', 'skimage']

    results = []

    for file in file_name_list:
        print('begin ' + str(file))
        for method in method_list:
            if method == 'my algorithm':
                radon1 = radon
                iradon1 = iradon
            else:
                radon1 = transform.radon
                iradon1 = transform.iradon
            img = cv2.imread(str(file), cv2.IMREAD_GRAYSCALE)
            start1 = time.time()
            sinogram = radon1(img)
            end1 = time.time()

            start2 = time.time()
            reconstruct = iradon1(sinogram, filter_name=None)
            end2 = time.time()

            start3 = time.time()
            filtered_reconstruct = iradon1(sinogram, filter_name='ramp')
            end3 = time.time()

            results.append({'file': file, 'method': method, 'radon': end1 - start1, 'iradon(direct)': end2 - start2,
                            'iradon(filter)': end3 - start3})

    df = pd.DataFrame(results).round(2)
    df.set_index(['file', 'method'], inplace=True)
    df.to_csv('time_cost.csv')


import numpy as np
import torch
from einops import rearrange, repeat, reduce
from einops.layers.torch import Rearrange

def ccw_sort(points):
    """Sort given polygon points in CCW order"""
    points = np.array(points)
    mean = np.mean(points, axis=0)
    coords = points - mean
    s = np.arctan2(coords[:, 0], coords[:, 1])
    return points[np.argsort(s), :]

def index_points(points, idx):
    """
    find idx of each batch points
    Input:
        points: input points data, [B, N, C]
        idx: sample index data, [B, S]
    Return:
        new_points:, indexed points data, [B, S, C]
    """
    device = points.device
    B = points.shape[0]
    view_shape = list(idx.shape)
    view_shape[1:] = [1] * (len(view_shape) - 1)
    repeat_shape = list(idx.shape)
    repeat_shape[0] = 1
    batch_indices = torch.arange(B, dtype=torch.long).to(device).view(view_shape).repeat(repeat_shape)
    new_points = points[batch_indices, idx, :]
    return new_points

# helper
def knn(x1, x2, k):
    """
    caculate topk distance from x1 to x2
        Input:
        x1: input points data, [b, n1, c]
        x2: input points data, [b, n2, c]
        k: int
    Return:
        new_points:, indexed points data, [B, S, C]
    """
    # x1 [b, n1, c], x2 [b, n2, c]
    inner = -2 * torch.matmul(x1, rearrange(x2, 'b n c -> b c n'))  # [b n1 n2]
    xx = torch.sum(x1 ** 2, dim=-1, keepdim=True)  # [b, n1, 1]
    yy = torch.sum(x2 ** 2, dim=-1, keepdim=True)  # [b, n2, 1]
    pairwise_distance = -xx - inner - yy.transpose(2, 1)

    idx = pairwise_distance.topk(k=k, dim=-1)[1]  # (batch_size, n1, k)
    return idx

def gen_uniform_grid(x):
    """
    Args:
        x: input coordinates
    Returns:
        res: input transform
    """
    shape = x.shape
    if len(shape) == 3:

        batchsize, size_x, size_y = shape[0], shape[1], shape[2]
        gridx = torch.linspace(0, 1, size_x, dtype=torch.float32)
        gridx = gridx.reshape(1, size_x, 1).repeat([batchsize, 1, 1])
        return gridx.to(x.device)

    elif len(shape) == 4:

        batchsize, size_x, size_y = shape[0], shape[1], shape[2]
        gridx = torch.linspace(0, 1, size_x, dtype=torch.float32)
        gridx = gridx.reshape(1, size_x, 1, 1).repeat([batchsize, 1, size_y, 1])
        gridy = torch.linspace(0, 1, size_y, dtype=torch.float32)
        gridy = gridy.reshape(1, 1, size_y, 1).repeat([batchsize, size_x, 1, 1])
        return torch.cat((gridx, gridy), dim=-1).to(x.device)

    elif len(shape) == 5:
        batchsize, size_x, size_y, size_z = shape[0], shape[1], shape[2], shape[3]
        gridx = torch.linspace(0, 1, size_x, dtype=torch.float32)
        gridx = gridx.reshape(1, size_x, 1, 1, 1).repeat([batchsize, 1, size_y, size_z, 1])
        gridy = torch.linspace(0, 1, size_y, dtype=torch.float32)
        gridy = gridy.reshape(1, 1, size_y, 1, 1).repeat([batchsize, size_x, 1, size_z, 1])
        gridz = torch.linspace(0, 1, size_z, dtype=torch.float32)
        gridz = gridz.reshape(1, 1, 1, size_y, 1).repeat([batchsize, size_x, size_y, 1, 1])
        return torch.cat((gridx, gridy, gridz), dim=-1).to(x.device)
    else:
        raise NotImplementedError("The tensor shape is Not implemented yet!")


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

# Looks for musical samples in arbitrary audio
# Adapted from: https://github.com/kylemcdonald/AudioNotebooks/blob/master/Multisamples%20to%20Samples.ipynb
# Usage:
    # python audio_to_images.py -plot 1
    # python audio_to_images.py -save 1
    # python audio_to_images.py -in "../data/usergen/saved_birds.json"

import argparse
import csv
import glob
import json
import librosa
from librosa import display
import matplotlib.pyplot as plt
import matplotlib.transforms as mtransforms
from multiprocessing import Pool
from multiprocessing.dummy import Pool as ThreadPool
import os
from os.path import join
import numpy as np
from pprint import pprint
import sys

# input
parser = argparse.ArgumentParser()
parser.add_argument('-in', dest="INPUT_FILES", default="../data/usergen/saved_birds.json", help="Input file pattern")
parser.add_argument('-dir', dest="INPUT_AUDIO_DIR", default="../audio/downloads/birds/%s.mp3", help="Input audio directory")
parser.add_argument('-save', dest="SAVE", default=0, type=int, help="Save files?")
parser.add_argument('-plot', dest="PLOT", default=0, type=int, help="Show plot?")
parser.add_argument('-width', dest="WIDTH", default=3600, type=int, help="Target width")
parser.add_argument('-height', dest="HEIGHT", default=600, type=int, help="Target height")
parser.add_argument('-out', dest="OUTPUT_FILE", default="../data/output/images/%s.png", help="Output file pattern")
parser.add_argument('-overwrite', dest="OVERWRITE", default=0, type=int, help="Overwrite existing images?")
args = parser.parse_args()

# Parse arguments
INPUT_FILES = args.INPUT_FILES
INPUT_AUDIO_DIR = args.INPUT_AUDIO_DIR
SAVE = args.SAVE > 0
PLOT = args.PLOT > 0
OUTPUT_FILE = args.OUTPUT_FILE
OVERWRITE = args.OVERWRITE > 0

# Audio config
FFT = 2048
HOP_LEN = FFT/4

# Read files
files = []
if "*" in INPUT_FILES:
    files = glob.glob(INPUT_FILES)
elif ".json" in INPUT_FILES:
    with open(INPUT_FILES) as f:
        files = [INPUT_AUDIO_DIR % fn for fn in json.load(f)]

fileCount = len(files)
print("Found %s files" % fileCount)

# Make sure output dirs exist
outDirs = [os.path.dirname(OUTPUT_FILE)]
for outDir in outDirs:
    if not os.path.exists(outDir):
        os.makedirs(outDir)

progress = 0
# files = files[:1]

def makeImage(fn):
    global progress
    basename = basename = os.path.splitext(os.path.basename(fn))[0]
    fileout = OUTPUT_FILE % basename
    w = 24
    h = 8

    y, sr = librosa.load(fn)
    D = librosa.amplitude_to_db(np.abs(librosa.stft(y)), ref=np.max)

    figure = plt.figure(figsize=(3600, 600), dpi=1)
    librosa.display.specshow(D, y_axis='log')

    if PLOT:
        plt.show()

    if SAVE and (OVERWRITE or not os.path.isfile(fileout)):
        axis = plt.subplot(1, 1, 1)
        plt.axis('off')
        plt.tick_params(axis='both', left='off', top='off', right='off', bottom='off', labelleft='off', labeltop='off', labelright='off', labelbottom='off')
        extent = axis.get_window_extent().transformed(figure.dpi_scale_trans.inverted())
        pts = extent.get_points()
        pad = 3.5
        pts[0][0] += pad
        pts[0][1] += pad
        pts[1][0] -= pad
        pts[1][1] -= pad
        extent.set_points(pts)
        plt.savefig(fileout, bbox_inches=extent, pad_inches=0)
        # print("Saved %s" % fileout)
    plt.cla()
    plt.clf()
    plt.close()

    progress += 1
    sys.stdout.write('\r')
    sys.stdout.write("%s%%" % round(1.0*progress/fileCount*100,1))
    sys.stdout.flush()

    return fileout

# pool = ThreadPool()
# data = pool.map(makeImage, files)
# pool.close()
# pool.join()
for fn in files:
    makeImage(fn)


from django.db import models

class Base(models.Model):
    created = models.DateTimeField('Data de criação', auto_now_add=True)
    updated = models.DateTimeField('Última atualização', auto_now=True)
    availability = models.BooleanField('Disponibilidade', default=True)

    # Configurar para ser usado por qualquer outro modelo
    class Meta:
        abstract = True

class Nouns(Base):
    question = models.CharField('Questão', max_length=100)
    name = models.CharField('Nome do substantivo', max_length=100)
    translation = models.CharField('Tradução do substantivo', max_length=100)

    def __str__(self):
        return self.name

    # Rótulos para o Django template admin
    class Meta:
        verbose_name = 'Substantivo'
        verbose_name_plural = verbose_name + 's'


import json
from pamda import pamda
from scgraph.utils import hard_round, distance_converter
from collections import Counter

# This `geojson_file` is not comitted in the git repo for size reasons
# It can be downloaded from:
# https://geodata.bts.gov/datasets/usdot::north-american-rail-network-lines-class-i-freight-railroads-view/about
geojson_file = "utils/north_america_rail_network.geojson"
out_filename = "scgraph/geographs/north_america_rail.py"
initialized_class_name = "north_america_rail_geograph"

data_geojson = json.load(open(geojson_file, "r"))

def lessThanAbs(threshold, a):
    abs_a = abs(a)
    while abs_a > threshold:
        abs_a -= threshold
    return abs_a * (1 if a > 0 else -1)

def format_coord_pair(coord_pair):
    try:
        return [lessThanAbs(180,hard_round(3, coord_pair[0])), lessThanAbs(90,hard_round(3, coord_pair[1]))]
    except:
        print(coord_pair)
        raise Exception()

def get_agg_arc(origin, destination, arcs_dict):
    distance = 0
    current_node = origin
    next_node = destination
    arc_dict = arcs_dict.get(current_node)
    while True:
        distance += arc_dict.get(next_node, 0)
        arc_dict = arcs_dict.get(next_node)
        if len(arc_dict)!=2:
            break
        new_next_node = [k for k in arc_dict.keys() if k != current_node][0]
        current_node = next_node
        next_node = new_next_node
    return {
        'origin':origin,
        'destination':next_node,
        'distance':round(distance,3),
    }

def invert_arc(arc):
    return {
        'origin':arc['destination'],
        'destination':arc['origin'],
        'distance':arc['distance'],
    }

def agg_arcs(arcs, remove_tips:bool=False, tip_threshold:int=5):
    arcs_dict = {}
    for arc in arcs:
        arcs_dict = pamda.assocPath([str(arc['origin']),str(arc['destination'])], arc['distance'], arcs_dict)
        arcs_dict = pamda.assocPath([str(arc['destination']),str(arc['origin'])], arc['distance'], arcs_dict)

    intersections = [k for k, v in arcs_dict.items() if len(v) > 2]
    tips = set([k for k, v in arcs_dict.items() if len(v) == 1])

    agg_arcs = []
    for intersection in intersections:
        for outbound in arcs_dict.get(intersection):
            agg_arc = get_agg_arc(intersection, outbound, arcs_dict)
            if remove_tips:
                # Remove all small arcs that are connected to tips (short offshoots - eg to local factories)
                if agg_arc['origin'] in tips or agg_arc['destination'] in tips:
                    if agg_arc['distance']<tip_threshold:
                        continue
            agg_arcs.append(agg_arc)
            agg_arcs.append(invert_arc(agg_arc))
    return agg_arcs

def get_arcs(geojson):
    arcs = [{
        'origin':format_coord_pair(arc['geometry']['coordinates'][0][0]),
        'destination':format_coord_pair(arc['geometry']['coordinates'][0][-1]),
        'distance':round(distance_converter(distance=pamda.path(["properties","MILES"], arc), input_units='mi', output_units='km'),2),
    } for arc in geojson["features"]]
    # Aggregate up arcs then remove arcs with tips that are too short
    arcs_no_tips = agg_arcs(arcs, remove_tips=True, tip_threshold=5)
    # After removing tips, aggregate up arcs again to merge arcs on intersections that were previously broken by a tip
    return agg_arcs(arcs_no_tips, remove_tips=False)

arcs = get_arcs(data_geojson)

raw_nodes = {}
for i in arcs:
    origin = json.loads(i['origin'])
    raw_nodes[str(origin)] = {"longitude": origin[0], "latitude": origin[1]}

key_mapping = {node_id:idx for idx, node_id in enumerate(raw_nodes.keys())}
nodes = {key_mapping[node_id]: node for node_id, node in raw_nodes.items()}
graph = {}
for arc in arcs:
    origin_id = key_mapping[arc['origin']]
    destination_id = key_mapping[arc['destination']]
    pamda.assocPath([origin_id, destination_id], arc['distance'], graph)
    pamda.assocPath([destination_id, origin_id], arc['distance'], graph)

out_string = f"""
from scgraph.core import GeoGraph
graph={str(graph)}
nodes={str(nodes)}
{initialized_class_name} = GeoGraph(graph=graph, nodes=nodes)
"""

with open(out_filename, "w") as f:
    f.write(out_string)


import mariadb as db
import DbInteractions.dbhandler as dbh
import traceback
import secrets

# Function to delete a login token(log a user out)

def delete_login(loginToken):
    conn, cursor = dbh.db_connect()
    try:
        # Delete statement, commit disconnect and return true
        cursor.execute(
            "DELETE FROM user_session WHERE logintoken = ? ", [loginToken])
        conn.commit()
    except db.OperationalError:
        traceback.print_exc()
        print('Something went  wrong with the db!')
    except db.ProgrammingError:
        traceback.print_exc()
        print('Error running DB query')
    except:
        traceback.print_exc()
        print("Something unexpected went wrong")
    dbh.db_disconnect(conn, cursor)
    return True

# Function that creates a new user session(log a user in)

def post_login(email, username, pass_hash):
    user = []
    userId = None
    conn, cursor = dbh.db_connect()
    try:
        # Check to see wether we are passed the username or email, and based on which does not have a value of None is which statement is ran to get the userId.
        if(email != None):
            cursor.execute(
                "SELECT `user`.id FROM `user` WHERE email = ? and password = ?", [email, pass_hash])
            userId = cursor.fetchone()
            userId = userId[0]
        elif(username != None):
            cursor.execute(
                "SELECT `user`.id FROM `user` WHERE username = ? and password = ?", [username, pass_hash])
            userId = cursor.fetchone()
            userId = userId[0]
        # Insert statement to insert a session to the user_session table based on the userId we get above. Commit the changes
        token = secrets.token_urlsafe(40)
        cursor.execute(
            "INSERT INTO user_session (user_id, logintoken) VALUES (?, ?)", [userId, token])
        conn.commit()
        # Select statement to grab information about the user, aswell as the just created login token, save data to variable change it to an object and return the data
        cursor.execute(
            "SELECT `user`.id, email, username, bio, birthdate, imageUrl, bannerUrl, loginToken FROM `user` inner join user_session on `user`.id = user_session.user_id WHERE `user`.id = ?", [userId])
        user = cursor.fetchone()
        user = {
            'userId': user[0],
            'email': user[1],
            'username': user[2],
            'bio': user[3],
            'birthdate': user[4],
            'imageUrl': user[5],
            'bannerUrl': user[6],
            'loginToken': user[7]
        }
    except db.OperationalError:
        traceback.print_exc()
        print('Something went  wrong with the db!')
    except db.ProgrammingError:
        traceback.print_exc()
        print('Error running DB query')
    except:
        traceback.print_exc()
        print("Something unexpected went wrong")
    dbh.db_disconnect(conn, cursor)
    return True, user


from django.shortcuts import render, get_object_or_404, HttpResponseRedirect, redirect
from .models import Post
from .forms import PostForm

# Create your views here.

def gallery(request):
    posts = Post.objects.all()
    return render(request, 'gallery/gallery.html', {'posts': posts})
def drawing(request):
    posts = Post.objects.all().filter(drawing_or_design='drawing')
    return render(request, 'gallery/drawing.html', {'posts': posts})
def design(request):
    posts = Post.objects.filter(drawing_or_design='design')
    return render(request, 'gallery/design.html', {'posts': posts})

def create(request):
    if request.method == "POST":
        form = PostForm(request.POST, request.FILES)
        if form.is_valid():
            post = form.save()
            return HttpResponseRedirect(post.get_absolute_url())

    else:
        form = PostForm()

    context = {
        'form': form,
    }

    # title = request.POST.get('title')
    # image = request.POST.get('image')
    # publishing_date = request.POST.get('publishing_date')
    # Post.objects.create(title=title, image=image, publishing_date=publishing_date)

    return render(request, 'gallery/create.html', context)
def detail(request, id):
    post = get_object_or_404(Post, id=id)
    context = {
        'post': post,
    }
    return render(request, 'gallery/detail.html', context)
def delete(request, id):
    post = get_object_or_404(Post, id=id)
    post.delete()
    return redirect("gallery:gallery")


"""
example cmdline:

python test/awd_lstm_lm/test_lstm_manual.py

"""

import os
import time
import argparse
import numpy as np
import pickle as pkl

import sys
sys.path.insert(0, '.')
sys.path.insert(1, '../open-box')    # for dependency
from test.utils import timeit
from lstm_obj import *

parser = argparse.ArgumentParser()
parser.add_argument('--dataset', type=str, default='penn')

args = parser.parse_args()
dataset = args.dataset

seed = 47  # no use

def lstm_objective_func_gpu(config, corpus, device='cuda'):  # device='cuda' 'cuda:0'
    t0 = time.time()
    assert corpus is not None

    device = torch.device(device)

    criterion = None
    dropout = config['dropout']
    dropouth = config['dropouth']
    dropouti = config['dropouti']
    dropoute = config['dropoute']
    wdrop = config['wdrop']
    emsize = config['emsize']
    hidden_size = config['hidden_size']
    weight_decay = config['wdecay']
    batch_size = config['batch_size']
    lr = config['lr']
    print('worker receive config:', config)

    epoch_ratio = 1

    ntokens = len(corpus.dictionary)
    model = RNNModel('LSTM', ntokens, emsize, hidden_size, n_layers, dropout, dropouth,
                     dropouti, dropoute, wdrop, tied)

    train_data = batchify(corpus.train, batch_size, device)
    val_data = batchify(corpus.valid, eval_batch_size, device)

    init_epoch_num = 1
    epoch_num = ceil(max_epoch * epoch_ratio)
    print('epoch_num', epoch_num)
    ###
    if not criterion:
        splits = []
        if ntokens > 500000:
            # One Billion
            # This produces fairly even matrix mults for the buckets:
            # 0: 11723136, 1: 10854630, 2: 11270961, 3: 11219422
            splits = [4200, 35000, 180000]
        elif ntokens > 75000:
            # WikiText-103
            splits = [2800, 20000, 76000]
        print('Using splits:', splits)
        criterion = SplitCrossEntropyLoss(emsize, splits=splits, verbose=False)
    ###

    model = model.to(device)
    criterion = criterion.to(device)
    ###
    params = list(model.parameters()) + list(criterion.parameters())
    total_params = sum(x.size()[0] * x.size()[1] if len(x.size()) > 1 else x.size()[0] for x in params if x.size())
    print('Model total parameters:', total_params)
    # Loop over epochs.
    best_val_loss = []
    stored_loss = 100000000
    evals_result = []

    # Ensure the optimizer is optimizing params, which includes both the model's weights as well as the criterion's weight (i.e. Adaptive Softmax)
    optimizer = torch.optim.SGD(params, lr=lr, weight_decay=weight_decay)

    return_pp = 1e10
    for epoch in range(init_epoch_num, init_epoch_num + epoch_num):
        epoch_start_time = time.time()
        train(corpus, model, criterion, optimizer, epoch, batch_size, train_data, bptt)
        if 't0' in optimizer.param_groups[0]:
            tmp = {}
            for prm in model.parameters():
                tmp[prm] = prm.data.clone()
                if 'ax' in optimizer.state[prm]:
                    prm.data = optimizer.state[prm]['ax'].clone()

            val_loss2 = evaluate(corpus, model, criterion, val_data)
            print('-' * 89)
            print('| end of epoch {:3d} | time: {:5.2f}s | valid loss {:5.2f} | '
                  'valid ppl {:8.2f} | valid bpc {:8.3f}'.format(
                epoch, (time.time() - epoch_start_time), val_loss2, math.exp(val_loss2), val_loss2 / math.log(2)))
            print('-' * 89)

            for prm in model.parameters():
                if prm in tmp:
                    prm.data = tmp[prm].clone()
            return_pp = math.exp(val_loss2)

        else:
            val_loss = evaluate(corpus, model, criterion, val_data, eval_batch_size)
            print('-' * 89)
            print('| end of epoch {:3d} | time: {:5.2f}s | valid loss {:5.2f} | '
                  'valid ppl {:8.2f} | valid bpc {:8.3f}'.format(
                epoch, (time.time() - epoch_start_time), val_loss, math.exp(val_loss), val_loss / math.log(2)))
            print('-' * 89)

            if epoch in decay_epoch:
                print('Dividing learning rate by 10')
                optimizer.param_groups[0]['lr'] /= 10.

            best_val_loss.append(val_loss)
            return_pp = math.exp(val_loss)

        evals_result.append(return_pp)

    perf = return_pp
    test_perf = None
    train_time = time.time() - t0

    return perf, test_perf, evals_result, train_time

data_path = './test/awd_lstm_lm/data/penn'
cs = get_lstm_configspace()
config = cs.get_default_configuration()   # todo
corpus = get_corpus(data_path)

with timeit('%s' % (dataset, )):
    print('=== resnet manual param (my default)===')
    perf, test_perf, evals_result, train_time = lstm_objective_func_gpu(config, corpus)
    print(evals_result)
    print('=== perf(val, test):', perf, test_perf)
    print('=== train time(s):', train_time)
    # print(list(evals_result['validation_0'].values())[0])

    save_item = (config, perf, test_perf, evals_result, train_time)

    timestamp = time.strftime('%Y-%m-%d-%H-%M-%S', time.localtime(time.time()))
    dir_path = 'data/default_test/lstm-%s/' % (dataset, )
    file_name = 'lstm_manual-%s-%04d-%s.pkl' % (dataset, seed, timestamp)
    try:
        if not os.path.exists(dir_path):
            os.makedirs(dir_path)
    except FileExistsError:
        pass
    with open(os.path.join(dir_path, file_name), 'wb') as f:
        pkl.dump(save_item, f)
    print('save to:', dir_path, file_name)


'''
Arduino
requirement:
    pip3 install pymata-aio --user
'''
import zmq
import subprocess
import pathlib
import platform
import time
import threading

from codelab_adapter import settings
from codelab_adapter.core_extension import Extension

def get_python3_path():
    # If it is not working,  Please replace python3_path with your local python3 path. shell: which python3
    if (platform.system() == "Darwin"):
        # which python3
        # 不如用PATH python
        # 不确定
        path = "/usr/local/bin/python3"
    if platform.system() == "Windows":
        path = "python3"
    if platform.system() == "Linux":
        path = "/usr/bin/python3"
    return path

python3_path = get_python3_path()

class arduinoExtension(Extension):
    def __init__(self):
        name = type(self).__name__  # class name
        super().__init__(name)
        self.scratch3_message = {}
        self.TOPIC = "eim/arduino"
        self.first_start = 1

    def run(self):
        # 抽象掉这部分 Class
        port = 38782  # todo 随机分配
        context = zmq.Context.instance()
        socket = context.socket(zmq.REQ)
        socket.connect("tcp://localhost:%s" % port)

        codelab_adapter_server_dir = pathlib.Path.home(
        ) / "codelab_adapter" / "servers"
        script = "{}/arduino_server.py".format(codelab_adapter_server_dir)

        cmd = [python3_path, script]
        arduino_server = subprocess.Popen(cmd)
        settings.running_child_procs.append(arduino_server)

        lock = threading.Lock()

        def request():
            while self._running:
                lock.acquire()
                self.scratch3_message = self.read()
                lock.release()

        bg_task = threading.Thread(target=request)
        self.logger.debug("thread start")
        bg_task.daemon = True
        bg_task.start()

        while self._running:
            scratch3_message = self.scratch3_message
            self.logger.debug("scratch3_message {}".format(scratch3_message))
            self.scratch3_message = {}
            if scratch3_message == {}:
                scratch3_message = {"topic": self.TOPIC, "payload": ""}

            topic = scratch3_message.get('topic')
            arduino_code = scratch3_message.get("payload")

            if  topic == self.TOPIC:
                socket.send_json({"arduino_code": arduino_code})

            result = socket.recv_json().get("result")

            if self.first_start == 1:
                self.publish({"topic": "eim/arduino/init","payload": ""})
                self.first_start = 0

            # 发往scratch3.0
            self.publish({"topic": self.TOPIC,"payload": result})
            time.sleep(0.05)

        # release socket
        socket.send_json({"arduino_code": "quit!"})
        result = socket.recv_json().get("result")
        arduino_server.terminate()
        arduino_server.wait()
        socket.close()
        context.term()

export = arduinoExtension


__license__ = '''
 License (GPL-3.0) :
    This file is part of PPQT Version 2.
    PPQT is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You can find a copy of the GNU General Public License in the file
    extras/COPYING.TXT included in the distribution of this program, or see:
    <http://www.gnu.org/licenses/>.
'''
__version__ = "2.0.0"
__author__  = "David Cortesi"
__copyright__ = "Copyright 2013, 2014 David Cortesi"
__maintainer__ = "David Cortesi"
__email__ = "tallforasmurf@yahoo.com"

'''
Unit test for paths.py.
'''
import test_boilerplate as T
T.set_up_paths()
T.make_app()
import os
import logging
import constants as C
import paths
T.settings.clear()
# test readable folder
test_path = T.path_to_Files
assert paths.check_path(test_path)
# nonexistent file
assert not paths.check_path(os.path.join(test_path,'arglebargle'))
# file that has the read perms turned off
assert not paths.check_path(os.path.join(test_path,'unreadable.aff'))

paths.initialize(T.settings)

# with null settings, extras defaults to cwd = test_path
assert T.check_log('initial extras path is '+test_path ,logging.INFO)
assert paths.get_extras_path() == test_path
assert paths.get_dicts_path() == ''
# check assuming bookloupe is installed
if C.PLATFORM_IS_WIN:
    assert paths.get_loupe_path() == '' # TODO FIX WHEN KNOWN
else:
    assert paths.get_loupe_path() == '/usr/local/bin/bookloupe'
# point settings to an extras, expect dicts to follow
test_extras = os.path.join(T.path_to_Files,'extras')
T.settings.setValue("paths/extras_path", test_extras)
paths.initialize(T.settings)
assert T.check_log('initial extras path is '+test_extras ,logging.INFO)
assert paths.get_extras_path() == test_extras
test_dicts = os.path.join(test_extras,'dicts')
assert paths.get_dicts_path() == test_dicts
# Make sure that what we put into loupe, we get back
test_loupe = os.path.join(test_extras,'bookloupe.exe') # which doesn't exist
paths.set_loupe_path(test_loupe)
assert paths.get_loupe_path() == test_loupe
# test shutdown
T.settings.clear()
paths.shutdown(T.settings)
assert T.settings.value("paths/extras_path",'wrong') == test_extras
assert T.settings.value("paths/dicts_path",'wrong') == test_dicts
assert T.settings.value("paths/loupe_path",'wrong') == test_loupe
# set bad values because paths expects caller to verify validity
dummy_dicts = '/some/where/dicts'
paths.set_dicts_path(dummy_dicts)
dummy_extras = '/what/ever/extras'
paths.set_extras_path(dummy_extras)
dummy_loupe = 'nexist/pas/bookloupe'
paths.set_loupe_path(dummy_loupe)
assert paths.get_dicts_path() == dummy_dicts
assert paths.get_extras_path() == dummy_extras
assert paths.get_loupe_path() == dummy_loupe
# shut down with those bad values
paths.shutdown(T.settings)
# start up with bad values, expect defaults
paths.initialize(T.settings)
assert paths.get_extras_path() == test_path # bad path -> cwd
assert paths.get_dicts_path() == '' # bad path -> null
assert paths.get_loupe_path() == '' # bad path -> null
# Check sending of signal
sig_value = None
def catcher(what):
    global sig_value
    sig_value = what
paths.notify_me(catcher)
paths.set_extras_path('/somewhere/over/the/rainbow')
assert sig_value == 'extras'
paths.set_loupe_path('/somewhere/over/the/rainbow')
assert sig_value == 'loupe'
paths.set_dicts_path('/somewhere/over/the/rainbow')
assert sig_value == 'dicts'


import json
import time

import pytest
import requests_mock
from django.core import mail
from django.core.management import call_command
from django.utils.crypto import get_random_string
from django.utils.encoding import force_str

from gore.models import Event
from gore.tests.conftest import project, raven_with_project  # noqa: F401
from gore.tests.data import exc_payload
from gotify.models import SlackNotifier
from gotify.models.email_notifier import EmailNotifier

@pytest.mark.django_db  # noqa: F811
def test_email_notifier(project, settings):  # noqa: F811
    settings.GOTIFY_IMMEDIATE = False
    en = EmailNotifier.objects.create(emails='test@example.com')
    en.projects.add(project)
    event = Event.objects.create_from_raven(project_id=project.id, body=json.loads(exc_payload))
    call_command('gotify_send')
    message = mail.outbox[-1]
    assert event.message in message.subject
    assert event.project.name in message.subject

@pytest.mark.django_db  # noqa: F811
def test_slack_notifier(project, settings):  # noqa: F811
    settings.GOTIFY_IMMEDIATE = False
    sn = SlackNotifier.objects.create(
        webhook_url='http://example.com',
        message_header_suffix=get_random_string(12),
    )
    sn.projects.add(project)
    event = Event.objects.create_from_raven(project_id=project.id, body=json.loads(exc_payload))
    with requests_mock.mock() as m:
        m.post('http://example.com', text='ok')
        call_command('gotify_send')
    assert m.called
    req = m.request_history[0]
    assert req.method == 'POST'
    payload = json.loads(force_str(req.body))
    assert event.message in payload['text']
    assert event.project.name in payload['text']
    assert sn.message_header_suffix in payload['text']

@pytest.mark.django_db(transaction=True)
@pytest.mark.parametrize('thread', [True, False])
def test_immediate_notify(raven_with_project, settings, thread):  # noqa: F811
    settings.GOTIFY_IMMEDIATE = True
    settings.GOTIFY_IMMEDIATE_THREAD = thread
    project = raven_with_project.project  # noqa: F811
    en = EmailNotifier.objects.create(emails='test@example.com')
    en.projects.add(project)
    raven_with_project.captureMessage('hello world')
    if thread:
        time.sleep(1)
    assert len(mail.outbox) == 1

@pytest.mark.django_db  # noqa: F811
def test_exclude(raven_with_project, settings):  # noqa: F811
    settings.GOTIFY_IMMEDIATE = True
    project = raven_with_project.project  # noqa: F811
    en = EmailNotifier.objects.create(emails='test@example.com')
    en.excludes.create(pattern='hello')
    en.projects.add(project)
    raven_with_project.captureMessage('hello world')
    assert len(mail.outbox) == 0


import torch
import torch.nn as nn
import torch.nn.functional as F
from torch import Tensor

class LateTemporalTokenizer(nn.Module):
    """
    Late Temporal Tokenizer is a 3D feature map tokenizer modules. It creates spatio-temporal tokens that summarize
    information along the spatial and temporal dimensions of the input feature map.
    Params:
    - in_channels: channel size of input feature map
    - spatial_dim: spatial dimension size of tokens
    - temporal_dim: temporal dimension size of tokens
    - token_dim: dimension of each spatio-temporal token
    """

    def __init__(self, in_channels: int, spatial_dim: int, temporal_dim: int, token_dim: int) -> None:
        super().__init__()

        self.in_channels = in_channels
        self.spatial_dim = spatial_dim
        self.temporal_dim = temporal_dim
        self.token_dim = token_dim

        self.spatial_proj = nn.Linear(in_channels, token_dim)
        self.temporal_proj = nn.Linear(token_dim, token_dim)

        self.spatial_linear = nn.Linear(in_channels, spatial_dim)
        self.temporal_linear = nn.Linear(token_dim, temporal_dim)

    def forward(self, x: Tensor) -> Tensor:
        """
        Expected Input Dimensions: (B, T, HW, C), where:
        - B: batch size
        - T: number of video frames
        - HW: number of pixels
        - C: size of input feature map channels

        Expected Output Dimensions: (B, F, L, D), where:
        - L: spatial dimension of tokens
        - F: temporal dimension of tokens
        - D: size of token dimension
        """

        # spatial tokenization
        x_proj = self.spatial_proj(x)  # -> (B, T, HW, D)
        a = self.spatial_linear(x)  # -> (B, T, HW, L)
        a = F.softmax(a, dim=2)  # -> (B, T, HW, L)
        a = torch.einsum('btij, btik -> btjk', a, x_proj)  # -> (B, T, L, D)

        # temporal tokenization
        a_proj = self.temporal_proj(a)  # -> (B, T, L, D)
        t = self.temporal_linear(a)  # -> (B, T, L, F)
        t = F.softmax(t, dim=1)  # -> (B, T, L, F)
        t = torch.einsum('btlf, btld -> bfld', t, a_proj)  # -> (B, F, L, D)

        return t


import discord

from ... import command_decorator, helpers

@command_decorator.command("set prefix ", "Sets anna-bots prefix for this server. The prefix might take a minute to update. "
                                          "Set the prefix to @mention to use real @mention instead of a text prefix.")
@helpers.async_uses_persistent_file("configured_prefixes.json")
async def cmd_set_prefix(prefix_data: dict, message: discord.Message, client: discord.Client, config: dict):
    """Sets the prefix for a server, by writing it to disk. This means we don't actually update the dict in helpers.py."""

    # This can obviously not be used in PMs
    if message.channel.is_private:
        await client.send_message(message.author, "PM commands do not have prefixes, and as such, this command can not be used in PMs.")
        return

    # The issuing user needs to have the manage server permission or be an anna admin
    if ((not helpers.is_member_anna_admin(message.author, config)) or
        not (message.author.server_permissions.administrator or message.author.server_permissions.manage_server)):
        await client.send_message(message.channel, message.author.mention + ", you are not authorised to use this command. "
                            "This command requires either the `administrator` permission or the `manage server` permission.")
        return

    # Since the prefix file is a dict with server ids as keys and prefixes as values,
    # we parse the value, check the validity and then insert the value at the key
    raw_prefix_string = helpers.remove_anna_mention(client, message).strip()[len("set prefix "):].strip()

    # We check that the message is not too long or too short
    if not (1 < len(raw_prefix_string) < 50):
        await client.send_message(message.channel, message.author.mention +
                                  ", that prefix is not of proper length, minimum length is **1** and max is **50**.")
        return

    # If the data is @mention, we just remove the entry if it exists
    if raw_prefix_string == "@mention":
        prefix_data.pop(str(message.server.id), None)
    else:
        prefix_data[str(message.server.id)] = raw_prefix_string

    # We tell the user the command is done
    await client.send_message(message.channel, message.author.mention + ", the prefix is now **{0}**. "
                                                                        "This might take some time to activate."
                              .format(helpers.remove_discord_formatting(raw_prefix_string)[0]))

    return prefix_data,


import vtk

def main():
    rw = vtk.vtkRenderWindow()
    rw.SetSize(1000, 600)
    rw.SetWindowName("Alya")

    iren = vtk.vtkRenderWindowInteractor()
    iren.SetRenderWindow(rw)

    #Create a sphere
    sphereSource = []
    sphereSource.append( vtk.vtkSphereSource() )
    sphereSource.append( vtk.vtkSphereSource() )
    sphereSource.append( vtk.vtkSphereSource() )

    sphereSource[0].SetCenter(0.0, 0.0, 0.0)
    sphereSource[0].SetRadius(0.5)
    sphereSource[1].SetCenter(0.0, 0.0, 0.0)
    sphereSource[1].SetRadius(2.5)
    sphereSource[2].SetCenter(0.0, 0.0, 0.0)
    sphereSource[2].SetRadius(5.0)

    color = []
    color.append( (1.0,0.0,0.0) )
    color.append( (0.0,1.0,0.0) )
    color.append( (0.0,0.0,1.0) )

    color_background = []
    color_background.append( (0.8,0.8,0.9) )
    color_background.append( (0.8,0.8,0.8) )
    color_background.append( (0.8,0.8,0.7) )

    xmins=[0.0, 0.5, 0.5]
    ymins=[0.0, 0.5, 0.0]
    xmaxs=[0.5, 1.0, 1.0]
    ymaxs=[1.0, 1.0, 0.5]

    iren_list = []
    for i in range(3):
        ren = vtk.vtkRenderer()
        rw.AddRenderer(ren)
        ren.SetViewport(xmins[i],ymins[i],xmaxs[i],ymaxs[i])

        mapper = vtk.vtkPolyDataMapper()
        actor  = vtk.vtkActor()

        mapper.SetInputConnection(sphereSource[i].GetOutputPort())
        actor.SetMapper(mapper)
        actor.GetProperty().SetColor(color[i])
        actor.GetProperty().SetRepresentationToWireframe()

        ren.AddActor(actor)
        ren.SetBackground(color_background[i])
        ren.ResetCamera()

    rw.Render()
    iren.Start()

if __name__ == '__main__':
    main()


# -*- coding: UTF-8 -*-
"""
-------------------------------------------------
   FileName：        main
   Description：     钉钉消息通知机器人API服务
   Author：          kizai
   Date：            2023/3/1
-------------------------------------------------
"""
import os.path
from flask import request, Flask, jsonify
from flask_json import as_json, FlaskJSON
import requests
import time
import hmac
import urllib
import base64
import hashlib
import json
import logging

log_path = './run.log'
logging.basicConfig(filename=log_path, filemode='a+', level=logging.INFO,
                    format='%(asctime)s %(levelname)s %(filename)s %(funcName)s %(lineno)d %(message)s',
                    datefmt="%Y-%m-%d %H:%M:%S")

config_path = os.path.join(os.path.dirname(__file__), "config.json")

# 读取配置文件
with open(config_path, 'r', encoding='utf8') as f:
    config = json.load(f)

webhook = config['ws']['webhook']
secrets = config['ws']['secret']

app = Flask(__name__)
FlaskJSON(app)

# 加签
def signature_url(webhook_url: str, secret: str):
    # 生成当前时间戳，单位是毫秒，与请求调用时间误差不能超过1小时
    timestamp = str(round(time.time() * 1000))
    # 修改编码格式为utf-8
    secret_enc = secret.encode('utf-8')
    # 将timestamp和secret合并
    string_to_sign = '{}\n{}'.format(timestamp, secret)
    # 修改编码格式为utf-8
    string_to_sign_enc = string_to_sign.encode('utf-8')
    # 将字段进行加密，加密类型采用sha256
    hmac_code = hmac.new(secret_enc, string_to_sign_enc, digestmod=hashlib.sha256).digest()
    sign = urllib.parse.quote_plus(base64.b64encode(hmac_code))
    # 生成请求的URL，WebHook地址
    post_url = ("%s&timestamp=%s&sign=%s" % (webhook_url, timestamp, sign))
    logging.info(post_url)
    return post_url

# 发送Text信息
def send_msg(text: str, is_at_all: str, at_user_id: str = None):
    headers = {'Content-Type': 'application/json;charset=utf-8'}
    url = signature_url(webhook, secrets)
    data = {
        "msgtype": "text",
        "text": {
            "content": text
        },
        "at": {
            "atMobiles": [
            ],
            "atUserIds": [at_user_id
                          ],
            "isAtAll": is_at_all
        }
    }
    r = requests.post(url, data=json.dumps(data), headers=headers)
    logging.info(r.text)
    return r.text

# 发送MarkDown信息
def send_markdown_msg(text: str, is_at_all: str = False, at_user_id: str = None):
    headers = {'Content-Type': 'application/json;charset=utf-8'}
    url = signature_url(webhook, secrets)
    data = {
        "msgtype": "markdown",
        "markdown": {"title": 'Markdown Message',
                     "text": text},
        "at": {
            "atMobiles": [
            ],
            "atUserIds": [at_user_id
                          ],
            "isAtAll": is_at_all
        }
    }
    r = requests.post(url, data=json.dumps(data), headers=headers)
    logging.info(r.text)
    return r.text

# 检查服务端口是否正常
@app.route('/api/v1', methods=['GET', 'POST'])
def check():
    return jsonify({"code": 0, "message": config['msg']['0']})

# 发送文本信息接口
@app.route('/api/v1/text', methods=['POST'])
@as_json
def dingbot_text():
    if request.method == 'POST':
        try:
            data = request.args
            message = data['message']
            is_at_all = data.get('is_at_all')
            at_user_id = data.get('at_user_id')
            if message:
                send_msg(message, is_at_all, at_user_id)
                return jsonify({"code": 0, "message": config['msg']['0']})
            else:
                logging.error(config['msg']['-1'])
                return jsonify({"code": -1, "message": config['msg']['-1']})
        except:
            logging.error(config['msg']['400'])
            return jsonify({"code": 400, "message": config['msg']['400']})

# 发送markdown信息接口
@app.route('/api/v1/md', methods=['POST'])
@as_json
def dingbot_link():
    if request.method == 'POST':
        try:
            data = request.args
            text = data['text']
            message_url = data['message_url']
            is_at_all = data.get('is_at_all')
            at_user_id = data.get('at_user_id')
            if text and message_url:
                if at_user_id:
                    text_content = "{},[消息链接]({}),\n@{}".format(text, message_url, at_user_id)
                    send_markdown_msg(text_content, is_at_all, at_user_id)
                    return jsonify({"code": 0, "message": config['msg']['0']})
                else:
                    text_content = "{},[消息链接]({})".format(text, message_url)
                    send_markdown_msg(text_content, is_at_all)
                    return jsonify({"code": 0, "message": config['msg']['0']})
            else:
                logging.error(config['msg']['-1'])
                return jsonify({"code": -1, "message": config['msg']['-1']})
        except:
            logging.error(config['msg']['400'])
            return jsonify({"code": 400, "message": config['msg']['400']})

if __name__ == "__main__":
    app.run(host='0.0.0.0', port=config['port'], debug=True)


from itertools import permutations
from collections import deque
from cmath import inf

class GraphAL:
    def init(self, size):
        self.size=size
        self.arregloDeListas = [0]*size # = [0,0,0,0...]
        for i in range(size):
            self.arregloDeListas[i] = deque()

    def addArc(self, source, destination, weight):
        laListaLlegada = self.arregloDeListas[source]
        unaPareja = (destination,weight)
        laListaLlegada.append(unaPareja)

    def getWeight(self, source, destination):
        laListaLlegada = self.arregloDeListas[source]
        if destination not in self.getSuccessors(source):
            return inf
        for i in range(len(laListaLlegada)):
            pareja = laListaLlegada[i] # O(n)
            theDestination = pareja[0]
            theWeight = pareja[1]
            if theDestination == destination:
                return theWeight
        for (theDestination,theWeight) in laListaLlegada:
            if theDestination == destination:
                return theWeight
        return 0
    def getSuccessors(self, source):
        otraListica = deque()
        laListaLlegada = self.arregloDeListas[source]
        for (theDestination,theWeight) in laListaLlegada:
            otraListica.append(theDestination)
        return otraListica
def recorridos(grafo):
    lista = []
    visitado=[False]*grafo.size
    for i in range(grafo.size):
        if not visitado[i]:
            visitado[i]=True
            lista.append(i)
            for sucesor in grafo.getSuccessors(i):
                if not visitado[i]:
                    visitado[sucesor]=True
                    lista.append(i)
    return lista

def permutaciones(grafo,perm):
    perm1 = permutations(perm)
    for i in list(perm1):
        print
        print (i)
    perm1 = permutations(perm)
    pesoT = inf
    for i in list(perm1):
        peso = 0
        count = 0
        for j in i:
            count = count + 1
            if j != i[-1]:
                peso += grafo.getWeight(j,i[count])
            else :
                peso += grafo.getWeight(j,i[0])
                print(peso)
                if peso < pesoT:
                    pesoT = peso
    print("este es el menor peso: " + str(pesoT) )

def main():
    grafo=GraphAL(3)
    grafo.addArc(0,0,4)
    grafo.addArc(0,1,8)
    grafo.addArc(0,2,3)
    grafo.addArc(1,0,1)
    grafo.addArc(1,1,7)
    grafo.addArc(1,2,3)
    grafo.addArc(2,0,6)
    grafo.addArc(2,1,2)
    grafo.addArc(2,2,5)
    lista = recorridos(grafo)
    permutaciones(grafo,lista)
main()

laboratorios/lab02/codigo/lab 01 punto 1.py