from flask import Flask, render_template_string
app = Flask(__name__)

@app.route('/hello/<name>')
def hello(name):
    html = """"

Hello, {{ name }}

    """
    return render_template_string(html, name=name)  # string as template

if __name__ == '__main__':
    app.run(debug=True, host='0.0.0.0', port=8080)    # run also takes hot, port and options.


from dataclasses import dataclass, field
from typing import Tuple, Union, Dict, Callable, Optional

import matplotlib.pyplot as plt
import numpy as np
from scipy import optimize
from sklearn.base import BaseEstimator, RegressorMixin

from fit_psyche.models.logit import logit
from fit_psyche.models.wh2001 import wh2001

@dataclass
class PsychometricCurve(BaseEstimator, RegressorMixin):
    model: str = "logit"
    mean_lims: Tuple[float, float] = (0, 20)
    var_lims: Tuple[float, float] = (0.001, 20)
    guess_rate_lims: Tuple[float, float] = (0.01, 0.05)
    lapse_rate_lims: Tuple[float, float] = (0.01, 0.05)

    _fit_func: Optional[Callable] = field(default=None, init=False)
    coefs_: Optional[Union[None, Dict[str, float]]] = field(default=None, init=False)

    """
   Fit a Logit or Wichmann and Hill 2001 psychometric curve.

   Model parameters:
     - Both:
       - mean (bias): The mean point of the experimental variable where the decision flips (on average).
                      Describes decision bias.
       - var / discrimination threshold: The distribution variance. Lower means the decision flips quicker, so is
                                         "better". Both models are cumulative normal distributions. Greater
                                         variance = wider distribution = more change in x before decision flips.
     - wh only
       - Guess and lapse rates: Model subject fallibility. Essentially allow either end of the fit cumulative
                                distribution to anchor to points other than 0 and 1 at each end of the curve
                                (respectively). See Wichmann and Hill, 2001.

   For all parameters, starting points are set as a mean of the specified limits.

   :param model: Which model to use, 'logit' or 'wh'. Logit model has two parameters, mean and variance. WH
                 adds guess and lapse rate. Default 'logit'.
   :param mean_lims: Limit for the mean parameter. Should be set according to range of independent (x) variable.
                     For example, if the x variable is set between 10 and 20 units in the experiment, limits within
                     that range are reasonable. If it's outside something weird is going on!. Specified as
                     tuple(min, max). Default (0, 20).
   :param var_lims: Limit for the var parameter. Lower limit should be >0 and upper limit should be set according
                    to task difficulty. Specified as tuple(min, max). Default (0.001, 100).
   :param guess_rate_lims: Limit for the guess parameter. Sets anchor point for start of curve and represents
                           proportion of trails where subject acts randomly. Limits should be set according the
                           expectations about subject.
                           For example, it should be higher for humans than a machine learning model... Unless,
                           it's a machine learning model with stochastic elements like a NN with dropout or
                           reinforcement learning model that uses Epsilon greedy.
                           Suggestions:
                             - Human (0.01, 0.05) ie. 1-5%
                             - Deterministic ML model (0, 1e-6) - the 'logit' model may be more appropriate.
                             - Stochastic ML model: Around known epsilon greedy value, or some low value in other
                               cases.
                           Specified as tuple(min, max). Default (0.01, 0.05).
   :param lapse_rate_lims: Sets the anchor point for the upper end of the curve. See guess_rate_lims.
   """

    def __post_init__(self):
        if self.model not in ['logit', 'wh']:
            raise ValueError(f"Unknown model: {self.model}. Available models: 'logit', 'wh'")

    def fit(self, x: np.ndarray, y: np.ndarray) -> "PsychometricCurve":
        if self.model.lower() == "wh":
            self._fit_func = wh2001
            lims = [
                self.mean_lims,
                self.var_lims,
                self.guess_rate_lims,
                self.lapse_rate_lims,
            ]

            bounds = (
                [
                    self.mean_lims[0],
                    self.var_lims[0],
                    self.guess_rate_lims[0],
                    self.lapse_rate_lims[0],
                ],
                [
                    self.mean_lims[1],
                    self.var_lims[1],
                    self.guess_rate_lims[1],
                    self.lapse_rate_lims[1],
                ],
            )
        else:
            self._fit_func = logit
            lims = [self.mean_lims, self.var_lims]
            bounds = (
                [self.mean_lims[0], self.var_lims[0]],
                [self.mean_lims[1], self.var_lims[1]],
            )

        popt, pcov = optimize.curve_fit(
            f=self._fit_func,
            xdata=x,
            ydata=y,
            p0=[np.mean(lim) for lim in lims],
            bounds=bounds,
        )

        self.coefs_ = {"mean": popt[0], "var": popt[1]}
        if self.model.lower() == "wh":
            self.coefs_.update({"guess_rate": popt[2], "lapse_rate": popt[3]})

        return self

    def predict(self, x: np.array) -> np.ndarray:
        return self._fit_func(x, **self.coefs_)

    def plot(
            self,
            x: np.ndarray,
            y: np.ndarray = None,
            show: bool = True,
            y_label: str = "Prop.",
            x_label: str = "Independent variable",
    ) -> None:
        fig, ax = plt.subplots()

        ax.plot(x, self.predict(x), label="y_pred")

        if y is not None:
            ax.scatter(x, y, label="y")

        ax.legend()
        ax.set_xlabel(x_label)
        ax.set_ylabel(y_label)
        ax.set_title(f"Model: {self.model}")
        fig.tight_layout()

        if show:
            fig.show()

        return fig

if __name__ == "__main__":
    x_ = np.linspace(start=8, stop=16, num=16)
    y_ = (x_ > x_.mean()).astype(float)

    pc = PsychometricCurve(model="wh", guess_rate_lims=(0, 0.2)).fit(x_, y_)
    pc.plot(x_, y_)


from kafka import KafkaProducer
from pyspark.streaming import StreamingContext
from pyspark.streaming.kafka import KafkaUtils
from pyspark import SparkConf, SparkContext
import json
import sys
import nltk
from nltk import sent_tokenize, word_tokenize
from nltk.stem import WordNetLemmatizer
from nltk.corpus import stopwords
from stop_words import get_stop_words

#nltk.download('punkt')

def createSparkContext():
    spark_conf = SparkConf().setAppName("KafkaWordCount")
    sc = SparkContext(conf=spark_conf)
    sc.setLogLevel("ERROR")

    return sc

def createStreamingContext(sc):
    ssc = StreamingContext(sc, 5)
    #ssc.checkpoint("file:///usr/local/spark/checkpoint")
    # 这里表示把检查点文件写入分布式文件系统HDFS，所以要启动Hadoop
    ssc.checkpoint("_checkpoint")

    return ssc

def createKafkaStream(ssc, zkQuorum, group, topics, numThreads):
    topicAry = topics.split(",")
    # 将topic转换为hashmap形式，而python中字典就是一种hashmap
    topicMap = {}
    for topic in topicAry:
        topicMap[topic] = numThreads
    lines = KafkaUtils.createStream(ssc, zkQuorum, group, topicMap).map(lambda x: x[1])

    return lines

def updateFunc(new_values, last_sum):
    return sum(new_values) + (last_sum or 0)

def preprocessing(text):
    # tokenize into words
    tokens = [word for sent in nltk.sent_tokenize(text) for word in nltk.word_tokenize(sent)]

    # remove stopwords
    stop = stopwords.words('english')
    tokens = [token for token in tokens if token not in stop]

    # remove words less than three letters
    tokens = [word for word in tokens if len(word) >= 3]

    # lower capitalization
    tokens = [word.lower() for word in tokens]

    # lemmatize
    lmtzr = WordNetLemmatizer()
    tokens = [lmtzr.lemmatize(word) for word in tokens]
    preprocessed_text= ' '.join(tokens)

    return preprocessed_text

def getStatDSFromKafkaStream(sc, lines):
    # RDD with initial state (key, value) pairs
    initialStateRDD = sc.parallelize([(u'hello', 1), (u'world', 1)])

    words = lines.\
            flatMap(word_tokenize)

    statDS = words.\
                map(lambda x: (x, 1)).\
                updateStateByKey(updateFunc, initialRDD=initialStateRDD)

    return statDS

def setStopWordFilterOnStatDS(statDS):
    stop_words = get_stop_words('en')
    print("--------- stop word ---------")
    print(stop_words)

    statDS = statDS.\
                filter(lambda x: x[1]>=5).\
                filter(lambda x: x[0] not in stop_words)

    return statDS

def createStatDSOnKafkaStream(sc, lines):
    statDS = getStatDSFromKafkaStream(sc, lines)

    statDS = setStopWordFilterOnStatDS(statDS)

    return statDS

# 格式转化，将[["1", 3], ["0", 4], ["2", 3]]变为[{'1': 3}, {'0': 4}, {'2': 3}]，这样就不用修改第四个教程的代码了
def Get_dic(rdd_list):
    res = []
    for elm in rdd_list:
        tmp = {elm[0]: elm[1]}
        res.append(tmp)
    return json.dumps(res)

def sendmsg(rdd):
    if rdd.count != 0:
        msg = Get_dic(rdd.collect())
        producer = KafkaProducer(bootstrap_servers='localhost:9092')
        # 实例化一个KafkaProducer示例，用于向Kafka投递消息
        producer.send("wordStats", msg.encode('utf8'))
        # 很重要，不然不会更新
        producer.flush()

def setSenderOnStatDS(statDS):
    statDS.foreachRDD(lambda x: sendmsg(x))

    statDS.pprint()

def KafkaWordCount(zkQuorum, group, topics, numThreads):
    sc = createSparkContext()
    ssc = createStreamingContext(sc)

    lines = createKafkaStream(ssc, zkQuorum, group, topics, numThreads)

    statDS = createStatDSOnKafkaStream(sc, lines)

    setSenderOnStatDS(statDS)

    ssc.start()
    ssc.awaitTermination()

if __name__ == '__main__':
    # 输入的四个参数分别代表着
    # 1.zkQuorum为zookeeper地址
    # 2.group为消费者所在的组
    # 3.topics该消费者所消费的topics
    # 4.numThreads开启消费topic线程的个数
    if (len(sys.argv) < 5):
        print("Usage: KafkaWordCount <zkQuorum> <group> <topics> <numThreads>")
        exit(1)

    zkQuorum = sys.argv[1]
    group = sys.argv[2]
    topics = sys.argv[3]
    numThreads = int(sys.argv[4])
    print(group, topics)
    KafkaWordCount(zkQuorum, group, topics, numThreads)


from django.shortcuts import render
from graphs.models import Graph
from django.http import Http404
from django.contrib.auth.decorators import login_required

@login_required
def graph_by_query(request, query, type_):
    if type_ == 'isp':
        imgs = Graph.objects.filter(isp=query)
    elif type_ == 'period':
        pd = {'daily': 'd',
              'weekly': 'w',
              'monthly': 'm',
              'yearly': 'y'}
        imgs = Graph.objects.filter(period=pd[query])
    if len(imgs) == 0:
        raise Http404
    return render(request, 'traf/graph_list.html', {'imgs': imgs, 'type_': type_})


#!/usr/bin/python3.8
#coding:u8

import discord

from commandes.all_cmd import *

class MyClient(discord.Client):
    """
    Confirme dans la console que Clio est connectée.

    Clio affiche : "Regarde !help" sous son nom.

    Prend tous les message en entrée pour vérifier s'il s'agit d'une commande.

    Appelle is_it_cmd, affiche le text dans le canal définit ou ne fait rien.
    """
    async def on_ready(self):

        print(f'{self.user} est connectée à Discord !')
        await client.change_presence(activity=discord.Activity(type=3, name="!aide"))

    async def on_message(self, message):
        canal, text = all_users_cmd(message, client)
        if text != "not a cmd":
            await canal.send(text)

client = MyClient()
client.run('XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX')

# cd /home/jaenne/Python/clio
# ./clio.py


from flask import Flask, render_template, request
import os
from random import randint
app = Flask(__name__)

sk = os.environ.get('SECRET_KEY')
URL = os.environ.get('HEROKU_URL', 'http://127.0.0.1:5000/')

app_settings = {
    'SECRET_KEY': sk,
    "TEMPLATES_AUTO_RELOAD": True,
    'SQLALCHEMY_DATABASE_URI': os.environ.get(
                                            'DATABASE_URL',
                                            'sqlite:///data.db'
                                            ),
    'SQLALCHEMY_TRACK_MODIFICATIONS': False,
    'SESSION_TYPE': 'filesystem',
    'PERMANENT_SESSION_LIFETIME': (1 * 60 * 60)
}

app.config.update(app_settings)

@app.route("/", methods=["GET","POST"])
def insult():
    if request.method == "GET":
        A = [line.rstrip('\n') for line in open('a.txt')]
        B = [line.rstrip('\n') for line in open('b.txt')]
        C = [line.rstrip('\n') for line in open('c.txt')]

        string = "{} {} {}".format(
                                    A[randint(0, len(A)-1)],
                                    B[randint(0, len(B)-1)],
                                    C[randint(0, len(C)-1)]
                                    )

      #  return render_template('index.html', top="Thou", bottom=string)
    else:
        string = request.form.get('insult')
    return render_template('index.html', top="Thou", bottom=string)

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


import json
import pika
import hashlib
import os

config_file_path = "/config/config.json"
config = None
with open(config_file_path, "r") as config_file:
    config = json.load(open(config_file_path, "r"))
general_config = config["general"]
local_config = config["MOM"]

class MOM:
    def __init__(self, connection_mode: str, receiver_callback):
        self.connection = pika.BlockingConnection(pika.ConnectionParameters(local_config["broker_address"]))
        self.channel = self.connection.channel()
        self.receiver = None # exchange | queue
        self.sender = None # [(exchange name, [hashing attributes], connections_amount)] | [queue name]
        self.connection_mode = None
        self.queue_tag = None
        self.previous_stage_size = None
        connections = local_config["connections"]
        connections_names = list(connections.keys())
        connections_names.append("accepter_sender")
        if not (connection_mode in connections_names):
            raise ValueError(f"Connection mode is {connection_mode}, and should be one of the following: {connections_names}")

        receives_messages = True

        subscribes_to_keywords = False # reads from publisher/subscriber
        self.sends_to_publisher = False # sends to publisher/subscriber

        if connection_mode == "accepter" or connection_mode == "accepter_sender":
            if connection_mode == "accepter_sender":
                receives_messages = False

            connection_mode = "accepter"
            # Sending
            self.sends_to_publisher = True

            # Receiving

            # subscribes_to_keywords is already false
            self.previous_stage_size = 0
            for previous_stage in config[connection_mode]["receives_from"]:
                self.previous_stage_size += config[previous_stage]["computers_amount"]

        elif  connection_mode in ["funny_filter", "likes_filter", "countries_amount_filter", "trending_days_filter"]:
            # Sending
            self.sends_to_publisher = True

            # Receiving
            subscribes_to_keywords = True

        elif connection_mode in ["duplication_filter", "views_sum", "thumbnails_downloader"]:
            # Sending
            # sends_to_publisher is already false

            # Receiving
            subscribes_to_keywords = True

        elif connection_mode != "max_views_day":
            # If connection_mode == "max_views_day" then
            # Sending
            # sends_to_publisher is already false

            # Receiving
            # subscribes_to_keywords is already false

            raise ValueError(f"Unexpected connection mode {connection_mode}, it should be one of the following: {connections.keys()}")

        self.connection_mode = connection_mode

        if self.previous_stage_size == None:
            previous_stage = config[connection_mode]["receives_from"]
            if previous_stage == "accepter":
                self.previous_stage_size = config[previous_stage]["processes_amount"]
            else:
                self.previous_stage_size = config[previous_stage]["computers_amount"]

        if receives_messages:
            if subscribes_to_keywords:
                self.channel.exchange_declare(exchange = connection_mode, exchange_type = "direct")
                self.receiver = connection_mode
                result = self.channel.queue_declare(queue='', exclusive=True)
                queue_name = result.method.queue
                self.channel.queue_bind(exchange = self.receiver, queue = queue_name, routing_key = os.environ["NODE_ID"])
                self.channel.queue_bind(exchange = self.receiver, queue = queue_name, routing_key = general_config["general_subscription_routing_key"])
                self.queue_tag = self.channel.basic_consume(queue = queue_name, on_message_callback=receiver_callback, auto_ack=True)
            else:
                self.receiver = connection_mode
                self.channel.queue_declare(queue = connection_mode)
                self.queue_tag = self.channel.basic_consume(queue = connection_mode, on_message_callback=receiver_callback, auto_ack=True)

        if self.sends_to_publisher:
            self.sender = []
            connections_array = connections[connection_mode]["sends_to"]
            for connecting_to in connections_array:
                self.sender.append((connecting_to, config[connecting_to]["hashed_by"], config[connecting_to]["computers_amount"])) # (exchange name, [hashing attributes], receiver computers amount)
                self.channel.exchange_declare(exchange = connecting_to, exchange_type = "direct")
        else:
            self.sender = []
            for connection in connections[connection_mode]["sends_to"]:
                self.sender.append(connection)
                self.channel.queue_declare(queue = connection)

    def __get_hashing_key(self, line, receiving_end, hashing_attributes):
        indexes_object = config[receiving_end]["indexes"]
        hashing_attributes_iterator = iter(hashing_attributes)
        hashing_string = line[indexes_object[next(hashing_attributes_iterator)]]
        for hashing_attribute in hashing_attributes_iterator: # Extends to more than 2 receiving ends
            aux = line[indexes_object[hashing_attribute]]
            hashing_string += f"-{aux}"
        return hashing_string

    def send(self, message):
        message_string = json.dumps(message)
        if self.sends_to_publisher:
            for receiving_end in self.sender:
                line = message
                hashing_attributes = receiving_end[1]
                hashing_string = self.__get_hashing_key(line, receiving_end[0], hashing_attributes)

                routing_key_number = int(hashlib.sha512(hashing_string.encode()).hexdigest(), 16) % receiving_end[2]

                self.channel.basic_publish(exchange = receiving_end[0], routing_key = str(routing_key_number), body = message_string)
        else:
            for receiving_end in self.sender:
                self.channel.basic_publish(exchange = "", routing_key = receiving_end, body = message_string)

    def get_previous_stage_size(self):
        return self.previous_stage_size

    def send_line(self, line):
        kept_attributes = config[self.connection_mode]["kept_columns"]
        indexes = config[self.connection_mode]["indexes"]
        kept_attributes = list(map(lambda column: indexes[column], kept_attributes))
        kept_attributes.sort()
        sent_line = []
        for index in kept_attributes:
            sent_line.append(line[index])
        self.send(sent_line)

    def send_general(self, message):
        message_string = json.dumps(message)
        if self.sends_to_publisher:
            for receiving_end in self.sender:
                self.channel.basic_publish(exchange = receiving_end[0], routing_key = general_config["general_subscription_routing_key"], body = message_string)
        else:
            for receiving_end in self.sender:
                self.channel.basic_publish(exchange = "", routing_key = receiving_end, body = message_string)

    def start_received_messages_processing(self):
        self.channel.start_consuming()

    def close(self):
        if self.connection != None:
            self.channel.basic_cancel(self.queue_tag)
            self.connection.close()
            self.connection = None


from PIL import Image
import os

path = 'qrs/'
resize_ratio = 0.5  # where 0.5 is half size, 2 is double size

def resize_aspect_fit():
    dirs = os.listdir(path)
    for item in dirs:
        if item == '.png':
            continue
        if os.path.isfile(path+item):
            image = Image.open(path+item)
            file_path, extension = os.path.splitext(path+item)

            image = image.resize((124, 124))
            image.save(file_path + "_small" + extension, 'PNG', quality=90)

resize_aspect_fit()


from dataclasses import dataclass, InitVar, field
from typing import Any
from pygccx.protocols import ISet, number
from pygccx.enums import ESetTypes
from pygccx.auxiliary import f2s

@dataclass
class DistribuitingCoupling:
    """
    Class to apply translational loading (force or displacement)
    on a set of nodes in a global sens

    The first condition (first line under the *DISTRIBUTING COUPLING keyword) has
    to be provided to the init of this class. Further conditions can be added
    by the method add_condition()

    Args:
        elset: "Element set which should contain exacty one element of type DCOUP3D
        nid_or_set: node id or node set of first coupling condition
        weight: weight of first coupling condition
        name: Name of this instance.
        desc: A short description of this instance. This is written to the ccx input file.
    """

    elset: ISet
    """Element set which should contain exacty one element of type DCOUP3D"""
    nid_or_set:InitVar[int|ISet]
    weight:InitVar[number] = 1.
    name:str = ''
    """Name of this instance."""
    desc:str = ''
    """A short description of this instance. This is written to the ccx input file."""
    conditions:list[tuple] = field(default_factory=list, init=False)
    """List of coupling conditions in the form:\n
    [(nid_or_set, weight), ...]"""

    def __setattr__(self, name: str, value: Any) -> None:
        if name == 'elset':
            if value.type != ESetTypes.ELEMENT:
                raise ValueError(f'Set type of elset must be ELEMENT, got {value.type.name}')
            if len(value.ids) != 1:
                raise ValueError(f'elset must contain exactly one element id, but has {len(value.ids)}')
        super().__setattr__(name, value)

    def __post_init__(self, nid_or_set, weight):
        self.add_condition(nid_or_set, weight)

    def add_condition(self, nid_or_set:int|ISet, weight:number = 1.):
        """
        Adds a condition to this DistribuitingCoupling

        Args:
            nid_or_set (int | ISet): node id or node set of coupling condition
            weight (number, optional): weight of coupling condition. Defaults to 1.

        Raises:
            ValueError: Raised if nid_or_set is an int and < 1.
            ValueError: Raised if nid_or_set is an ISet and set type != NODE
        """
        if isinstance(nid_or_set, int):
            if nid_or_set < 1:
                raise ValueError(f'nid must be greater than 0, got {nid_or_set}')
        if isinstance(nid_or_set, ISet):
            if nid_or_set.type != ESetTypes.NODE:
                raise ValueError(f'Set type of nid_or_set must be NODE, got {nid_or_set.type.name}')

        self.conditions.append((nid_or_set, weight))

    def __str__(self):
        s = f'*DISTRIBUTING COUPLING,ELSET={self.elset.name}\n'

        for nid_or_set, weight in self.conditions:
            if isinstance(nid_or_set, ISet):
                s += f'{nid_or_set.name},{f2s(weight)}\n'
            else:
                s += f'{nid_or_set},{f2s(weight)}\n'

        return s


from icecream import ic
from matplotlib import pyplot as plt
import numpy as np
from mpl_toolkits.mplot3d import Axes3D
from matplotlib import animation
import time

from classes.target import Target
from classes.camera import Camera
from classes.imm import InteractingMultipleModel
from classes.plotter import Plotter
from kinetic_models.const_velocity import CV_CYPR_Model

class Main():

    def __init__(self, path = None, n_frames = 5, n_cameras = 1, sensor_accuracy = 5) -> None:
        np.set_printoptions(suppress=True, precision=20)
        np.seterr(all='raise')
        np.random.seed(0)

        self.start_time = time.monotonic()
        self.path = path
        if self.path is None:
            self.path = np.array(list(self.gen_path(n_frames))).T # (3, N)
        self.n_frames = n_frames
        if n_cameras > 1:
            self.distributed = True
        else:
            self.distributed = False
        self.cameras = self.create_cameras(n_cameras, sensor_accuracy, path[:, 0])

        self.target = Target("target", 0, 0, 0)
        self.last_timestamp = 0

        self.plotter = Plotter()

        self.start_world()

    def start_world(self):
        print("Starting world...")

        # Uncomment this to plot the path
        fig = plt.figure(figsize=(1, 1))
        ax = fig.add_subplot(projection='3d')
        line, = ax.plot(self.path[0, 0:1], self.path[1, 0:1], self.path[2, 0:1])

        # Setting the axes properties
        ax.set_xlim3d([-1.0, 500.0])
        ax.set_xlabel('X')

        ax.set_ylim3d([-1.0, 500.0])
        ax.set_ylabel('Y')

        ax.set_zlim3d([0.0, 300.0])
        ax.set_zlabel('Z')

        for i in range(0, self.n_frames):
            #self.start_time = time.monotonic()
            self.update_world(i, self.path, line)
            #duration = time.monotonic() - self.start_time
            #sleep_for = max(0,0.2 - duration)
            #time.sleep(sleep_for)

        #plt.show()

    def update_world(self, num, path, line):
        self.target.set_position(path[:, num])
        if num > 0:
            self.target.set_velocity(path[:, num] - path[:, num-1])#+ np.random.normal(0, 0.5, (3,)))
        if num > 1:
            self.target.set_acceleration(path[:, num] - 2*path[:, num-1] + path[:, num-2])

        line.set_data(path[:2, :num])
        line.set_3d_properties(path[2, :num])

        if num%5 == 0 and num != 0: # take measurement every 5 frames
            timestep = num - self.last_timestamp
            self.last_timestamp = num
            for cam in self.cameras:
                cam.take_position_measurement(self.target.get_position())
                cam.take_velocity_measurement(self.target.get_velocity())
                cam.take_acceleration_measurement(self.target.get_acceleration())

            # calculate average consensus
            if self.distributed == True:
                consensus_reached = False
                round = 0
                while consensus_reached == False:
                    print("Distributed consensus round " + str(round))
                    if round == 100:
                        print("Consensus not reached after 100 rounds")
                        exit()
                    round += 1
                    consensus_reached = True
                    for cam in self.cameras:
                        cam.send_messages(cam.avg_a, cam.avg_F)
                    for cam in self.cameras:
                        cam.calculate_average_consensus()
                    for cam in self.cameras:
                        for neighbor in cam.neighbors:
                            if not np.allclose(neighbor.avg_a, cam.avg_a, atol = 1e-08):
                                consensus_reached = False
                            if not np.allclose(neighbor.avg_F, cam.avg_F,  atol = 1e-08):
                                consensus_reached = False
                print("Consensus reached after " + str(round) + " rounds")

            for cam in self.cameras:
                filtered_pose, models = cam.imm.update_pose(timestep = timestep, distributed = self.distributed, a = cam.avg_a, F = cam.avg_F)
                cam.avg_a = None
                cam.avg_F = None

            self.plotter.update_plot(cam.get_measurements().flatten(), filtered_pose.flatten(), self.target.get_position(), self.target.get_velocity(), self.last_timestamp, models)

        plt.pause(0.01) # this updates both plots

        if num == self.n_frames-1:
            plt.close()
            exit()

    def create_cameras(self, n_cameras, sensor_accuracy, initial_pose):
        cameras = []
        for i in range(n_cameras):
            cameras.append(Camera("camera "+str(i), sensor_accuracy, np.array([0, 0, 0, 0, 0, 0]), initial_pose))
        # make following and precedenting cameras neighbors to each camera
        if n_cameras > 2:
            for index, cam in enumerate(cameras):
                if (index) == 0:
                    cam.neighbors.append(cameras[-1])
                else:
                    cam.neighbors.append(cameras[index-1])
                if (index) == n_cameras-1:
                    cam.neighbors.append(cameras[0])
                else:
                    cam.neighbors.append(cameras[index+1])
        if n_cameras == 2:
            cameras[0].neighbors.append(cameras[1])
            cameras[1].neighbors.append(cameras[0])

        return cameras

if __name__ == '__main__':
    n_cameras = 2
    path = np.zeros((3, 3000), dtype = float)
    for i in range(0, path.shape[1]):
        if i < 500:
            path[0, i] = (i/6)*i*10#x
            path[1, i] = (i/4)*i*10 #y
            path[2, i] = (i/8)*i*10 #z
        else:
            path[0, i] = (i/6)*5000 #x
            path[1, i] = (i/4)*5000 #y
            path[2, i] = (i/8)*5000 #z

    sensor_accuracy = 0.1

    Main(path = path, n_cameras = n_cameras, sensor_accuracy = sensor_accuracy, n_frames = path.shape[1])


import sqlite3

import pygame
import sys
import time
from sprites import Ground, Bird, Obstacle

FPS, WIDTH, HEIGHT = 75, 480, 800

class Game:
    def __init__(self):
        pygame.init()
        self.surface = pygame.display.set_mode((WIDTH, HEIGHT))
        pygame.display.set_caption("Don't touch the spikes")
        self.clock = pygame.time.Clock()

        self.colors = ['light blue', 'light green', 'gold2', 'orange', 'aquamarine1',
                       'pink', 'purple', 'indigo', 'springgreen', 'violet', 'red', 'cyan', 'dark green',
                       'dark orange', 'magenta', 'dark blue', 'maroon', 'darksalmon', 'orchid',
                       'black']

        self.bg_num = 0
        self.base_color = 'light gray'
        self.next_color = self.colors[self.bg_num]
        self.bg_color = 'light gray'

        self.dead_sound = pygame.mixer.Sound('data/sound effects/dead.wav')
        self.dead_sound.set_volume(0.15)

        self.highscore = None
        self.games_played = None

        self.number_of_steps = 0.8
        self.step = 0
        self.fade = False

        self.spikes_timer = 0
        self.dead_timer = 0

        self.font = pygame.font.Font('data/fonts/Blissful Thinking.otf', 33)
        self.title_font = pygame.font.Font('data/fonts/Blissful Thinking.otf', 50)
        self.score_font = pygame.font.Font('data/fonts/Sci Auralieph.otf', 120)

        self.text1 = self.font.render("CLICK", True, (255, 49, 100))
        self.text2 = self.font.render("TO JUMP", True, (255, 49, 100))
        self.title1 = self.title_font.render("DON'T TOUCH", True, 'white')
        self.title2 = self.title_font.render("THE SPIKES", True, 'white')
        self.title3 = None
        self.title4 = None
        self.title5 = self.title_font.render("GAME OVER :)", True, 'white')
        self.scoreText = self.score_font.render("0", True, self.bg_color)

        self.active = True
        self.score = "00"

        self.all_sprites = pygame.sprite.Group()
        self.collision_sprites = pygame.sprite.Group()

        bg_height = pygame.image.load('data/sprites/ground.png').get_height()
        self.scale_factor = HEIGHT / bg_height

        Ground([self.all_sprites, self.collision_sprites], self.scale_factor)

        self.spikes = []

        self.bird = None

    def run(self):

        self.bg_color = 'light gray'
        self.bg_num = 0
        self.base_color = self.bg_color
        self.next_color = self.colors[self.bg_num]

        last_time = time.time()
        text_timer = 0
        self.dead_timer = 0
        self.spikes_timer = 0

        while True:
            last_rotation = self.bird.rotation
            dt = time.time() - last_time
            last_time = time.time()

            text_timer += dt

            if self.score != self.bird.score:
                self.render_score()
            if self.score // 5 > self.bg_num:
                self.fade = True

            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    pygame.quit()
                    sys.exit()
                if event.type == pygame.MOUSEBUTTONDOWN and not self.bird.dead and event.button == 1:

                    if self.active:
                        self.bird.jump()
                    else:
                        self.bird = Bird(self.all_sprites, self.scale_factor / 3)
                        self.active = True

            if self.fade:
                dv = (5 / 8) * dt
                self.bird.velocity += dv if self.bird.velocity > 0 else -dv
                self.step += dt
                if self.step < self.number_of_steps:
                    self.bg_color = [x + (((y - x) / self.number_of_steps) * self.step) for x, y in
                                     zip(pygame.color.Color(self.base_color), pygame.color.Color(self.next_color))]
                else:
                    if self.bg_num == len(self.colors) - 1:
                        self.bg_num = 0
                    else:
                        self.bg_num += 1
                    self.step = 0
                    self.base_color = self.next_color
                    self.next_color = self.colors[self.bg_num]
                    self.fade = False
                self.render_score()

            self.surface.fill(pygame.color.Color(self.bg_color))
            self.all_sprites.update(dt)
            pygame.draw.circle(self.surface, 'white', (WIDTH / 2, HEIGHT / 2 - 20), 135)

            if text_timer < 0.8:
                self.terminate_text(text_timer)

            step1 = 55 if len(str(self.score)) == 1 else 55 * (len(str(self.score)) - 1)
            step2 = 25 * str(self.score).count('1')
            self.surface.blit(self.scoreText, (195 - step1 + step2, 320))

            if self.active:
                if last_rotation != self.bird.rotation:
                    for spike in self.spikes:
                        spike.kill()
                    for i in range(7):
                        self.spikes.append(
                            Obstacle([self.all_sprites, self.collision_sprites], self.scale_factor * 0.15, 'right'))
                    for i in range(7):
                        self.spikes.append(
                            Obstacle([self.all_sprites, self.collision_sprites], self.scale_factor * 0.15, 'left'))

                self.collisions()

                if self.spikes[0].pos.x >= 450 and self.bird.rotation == 1:
                    for spike in self.spikes:
                        spike.slide(dt, -1)

                elif self.spikes[0].pos.x < 480 and self.bird.rotation == -1:
                    for spike in self.spikes:
                        spike.slide(dt, 1)

            else:
                self.render_score()
                if self.dead_timer <= 2:
                    self.surface.blit(self.title5, (105, 150))
                    self.bird.dead_anim(self.dead_timer)
                else:
                    for spike in self.spikes:
                        spike.kill()
                    self.games_played += 1
                    if self.score > self.highscore:
                        self.highscore = self.score

                    self.make_record()

                    self.bird.kill()
                    self.starting_screen()
                self.dead_timer += dt
            self.all_sprites.draw(self.surface)
            pygame.display.update()

    def starting_screen(self):
        self.load_stats()

        for i in range(7):
            self.spikes.append(
                Obstacle([self.all_sprites, self.collision_sprites], self.scale_factor * 0.15, 'right'))
        for i in range(7):
            self.spikes.append(
                Obstacle([self.all_sprites, self.collision_sprites], self.scale_factor * 0.15, 'left'))

        self.bird = Bird(self.all_sprites, self.scale_factor / 3)
        ready = False

        self.spikes_timer = 0

        last_time = time.time()
        text_timer = 0

        while True:
            dt = time.time() - last_time
            last_time = time.time()

            text_timer += dt

            if self.bird.pos.x < 205:
                self.bird.showup(dt)
            else:
                ready = True

            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    pygame.quit()
                    sys.exit()
                if event.type == pygame.MOUSEBUTTONDOWN and ready and not self.bird.dead and event.button == 1:
                    self.active = True
                    self.bird.jump()
                    game.run()

            self.surface.fill('light gray')
            pygame.draw.circle(self.surface, 'white', (WIDTH / 2, HEIGHT / 2 - 20), 135)

            self.surface.blit(self.text1, (200, 255))
            self.surface.blit(self.text2, (182, 285))

            self.surface.blit(self.title1, (100, 65))
            self.surface.blit(self.title2, (130, 110))

            self.surface.blit(self.title3, (145, 620))
            self.surface.blit(self.title4, (130, 650))

            self.all_sprites.draw(self.surface)
            self.bird.idle(dt)

            pygame.display.update()

    def terminate_text(self, dt):
        x = ((dt * 50) ** 2 / 2)
        self.surface.blit(self.text1, (200 - x, 255))
        self.surface.blit(self.text2, (182 - x, 285))

        self.surface.blit(self.title1, (100 - x, 65))
        self.surface.blit(self.title2, (130 - x, 110))

        self.surface.blit(self.title3, (145 - x, 620))
        self.surface.blit(self.title4, (130 - x, 650))

    def render_score(self):
        self.score = self.bird.score
        self.scoreText = self.score_font.render(str(f"{self.score:02d}"), True, (pygame.color.Color(self.bg_color)))

    def collisions(self):
        if pygame.sprite.spritecollide(self.bird, self.collision_sprites, False, pygame.sprite.collide_mask):
            for sprite in self.collision_sprites.sprites():
                if sprite.sprite_type == 'obstacle':
                    self.dead_sound.play()
                    self.bird.rotation = -self.bird.rotation
                    self.base_color = 'light gray'
                    self.next_color = self.colors[0]
                    self.bg_color = 'light gray'
                    self.bg_num = 0

                    self.number_of_steps = 0.8
                    self.step = 0
                    self.fade = False

                    self.bird.dead = True
                    self.active = False
                    break

        if self.bird.rect.top <= 48 or self.bird.rect.bottom > 720:
            self.dead_sound.play()
            self.base_color = 'light gray'
            self.next_color = self.colors[0]
            self.bg_color = 'light gray'
            self.bg_num = 0

            self.number_of_steps = 0.8
            self.step = 0
            self.fade = False

            self.bird.dead = True
            self.bird.rotation = -self.bird.rotation
            self.active = False

    def load_stats(self):
        conn = sqlite3.connect('data/database.sqlite')
        c = conn.cursor()

        c.execute("""CREATE TABLE IF NOT EXISTS stats (
                    gplayed     INTEGER NOT NULL,
                    highscore   INTEGER NOT NULL
        );""")

        if len(list(c.execute("""select * from stats"""))) == 0:
            c.execute(f'''insert into stats values (0, 0)''')

        res = list(c.execute("""select * from stats"""))
        self.games_played = res[0][0]
        self.highscore = res[0][1]

        self.title3 = self.font.render(f"BEST SCORE: {self.highscore}", True, 'white')
        self.title4 = self.font.render(f"GAMES PLAYED: {self.games_played}", True, 'white')

        conn.commit()
        conn.close()

    def make_record(self):
        conn = sqlite3.connect('data/database.sqlite')
        c = conn.cursor()

        c.execute(f'''update stats set highscore = {self.highscore}, gplayed = {self.games_played}''')

        conn.commit()
        conn.close()

if __name__ == '__main__':
    game = Game()
    game.starting_screen()


from django.urls import path
from . import views

urlpatterns = [
    path('', views.index),
    path('card/', views.card, name='card'),
    path('transfer/', views.transfer, name='transfer'),
    path('success/', views.success, name='success'),
    path('fail/', views.fail, name='fail'),
    path('cancel/', views.cancel, name='cancel'),
]


'''
more about Django URLconfs,
look at the official documentation:
https://docs.djangoproject.com/en/2.2/topics/http/urls/
'''
# we're importing Django's function path and all of our views from the blogApp
from django.urls import path
from . import views

urlpatterns = [
    # assigning a view called post_list to the root URL
    # URL pattern is '' empty so resolver will match ./ homepage
    # name='post_list', is the name of the URL used to identify the view
    path('', views.post_list, name='post_list'),
    path('post/new/', views.post_new, name='post_new'),
    path('post/<int:pk>/', views.post_detail, name='post_detail'),
    path('post/<int:pk>/edit/', views.post_edit, name='post_edit'),
    path('drafts/', views.post_draft_list, name='post_draft_list'),
    path('post/<pk>/publish/', views.post_publish, name='post_publish'),
    path('post/<pk>/remove/', views.post_remove, name='post_remove'),
    path('post/<int:pk>/comment/', views.add_comment_to_post,
         name='add_comment_to_post'),
    path('comment/<int:pk>/approve/',
         views.comment_approve, name='comment_approve'),
    path('comment/<int:pk>/remove/', views.comment_remove, name='comment_remove'),

]


from pi_io_site.models import *
from pi_io import settings
import urllib2, urllib
import json

read_display_cls = ReadDisplay.__subclasses__()
write_display_cls = WriteDisplay.__subclasses__()

def push_config(rpi):
    rpi_read_ifaces = RPIReadInterface.objects.filter(rpi=rpi)
    rpi_write_ifaces = RPIWriteInterface.objects.filter(rpi=rpi)

    read_displays = ReadDisplay.objects.filter(interface__in=rpi_read_ifaces)
    write_displays = WriteDisplay.objects.filter(interface__in=rpi_write_ifaces)

    rpi_requirements = {}
    rpi_requirements['mac'] = rpi.mac_address

    def add_req(displays, type):
        rpi_requirements[type] = []
        for display in displays:
            display_configs = {
                'cls_name':display.interface.name,
                'ch_port':display.channel_port,
                'equation':display.equation
            }
            rpi_requirements[type].append(display_configs)

    add_req(read_displays, 'read')
    add_req(write_displays, 'write')

    requirements = [rpi_requirements]

    post_data = {'json':json.dumps(requirements)}
    post_data = urllib.urlencode(post_data)

    if settings.WS_SERVER_HTTP_SSL:
        proto = 'https'
    else:
        proto = 'http'

    post_addr = '%s://%s:%d' % (proto, settings.WS_SERVER_IP, settings.WS_SERVER_HTTP)

    try:
        url = urllib2.Request(post_addr, post_data)
        url_response = urllib2.urlopen(url)
        resp = url_response.read()
        if resp == 'ok':
            return True
    except:
        pass

    return False

def config_changed_signal(sender, **kwargs):
    # we need to verify that the sender is a subclass of ReadDisplay or WriteDisplay
    if sender in read_display_cls or sender in write_display_cls:
        # send update request for the relevant RPI configs
        rpi = kwargs['instance'].rpi
        if rpi.online:
            push_config(rpi)


from apispec import BasePlugin
from apispec.exceptions import DuplicateComponentNameError
from apispec.yaml_utils import load_operations_from_docstring
from schematics.contrib.enum_type import EnumType
from schematics.models import FieldDescriptor
from schematics.types import ModelType, DictType, ListType, BooleanType, EmailType, UUIDType, StringType, IntType
from schematics.undefined import UndefinedType

from registry.http.schematics.types import ArrowType, NameType

class DocStringPlugin(BasePlugin):

    def __init__(self):
        self.spec = None

    def init_spec(self, spec):
        super().init_spec(spec)
        self.spec = spec

    def operation_helper(self, path, operations, router, func, **kwargs):
        new_operations = load_operations_from_docstring(func.__doc__)

        if hasattr(func, '_cp_config') is False:
            return None

        cp_config = func._cp_config

        if new_operations is not None:
            for method, data in new_operations.items():

                if cp_config.get('tools.authentication.on', True):
                    data['security'] = [
                        {'Bearer': []}
                    ]

                if 'tools.model_in.cls' in cp_config:
                    model_cls = cp_config['tools.model_in.cls']
                    try:
                        self.spec.components.schema(model_cls.__name__, component=parse_model(self.spec, model_cls))
                    except DuplicateComponentNameError:
                        pass

                    data['requestBody']['required'] = True
                    data['requestBody']['content'] = {
                        'application/json': {
                            'schema': {'$ref': '#/components/schemas/' + model_cls.__name__}
                        }
                    }

                if 'tools.model_params.cls' in cp_config:
                    model_cls = cp_config['tools.model_params.cls']
                    data['parameters'] = data.get('parameters', [])

                    # In query vs in path
                    for key, obj in model_cls.__dict__.items():
                        inn = 'query'
                        if '{' + key + '}' in path:
                            inn = 'path'
                        if isinstance(obj, FieldDescriptor):
                            paramenters = {
                                'name': key,
                                'in': inn,
                                'required': model_cls._fields[key].required,
                                'schema': parse_model_type(self.spec, model_cls._fields[key]),
                            }
                            if isinstance(model_cls._fields[key]._default, UndefinedType) is False:
                                paramenters['schema']['default'] = model_cls._fields[key]._default
                            data['parameters'].append(paramenters)

                if 'tools.model_out.cls' in cp_config:
                    model_cls = cp_config['tools.model_out.cls']
                    try:
                        self.spec.components.schema(model_cls.__name__, component=parse_model(self.spec, model_cls))
                    except DuplicateComponentNameError:
                        pass
                    data['responses'][200]['content'] = {
                        'application/json': {
                            'schema': {'$ref': '#/components/schemas/' + model_cls.__name__}
                        }
                    }

                if 'tools.model_out_pagination.cls' in cp_config:
                    model_cls = cp_config['tools.model_out_pagination.cls']
                    try:
                        self.spec.components.schema(model_cls.__name__, component=parse_model(self.spec, model_cls))
                    except DuplicateComponentNameError:
                        pass
                    self.spec.components.schema("List" + model_cls.__name__,
                                                component={
                                                    'type': 'object',
                                                    'properties': {
                                                        path.split("/")[-1]: {
                                                            'type': 'array',
                                                            'items': {
                                                                '$ref': '#/components/schemas/' + model_cls.__name__}
                                                        },
                                                        path.split("/")[-1] + "_links": {
                                                            'type': 'array',
                                                            'items': {
                                                                'type': 'object',
                                                                'properties': {
                                                                    'href': {
                                                                        'type': 'string'
                                                                    },
                                                                    'rel': {
                                                                        'type': 'string'
                                                                    }
                                                                }
                                                            }
                                                        }
                                                    },
                                                })
                    data['responses'][200]['content'] = {
                        'application/json': {
                            'schema': {'$ref': '#/components/schemas/' + "List" + model_cls.__name__}
                        }
                    }

                if 'tools.enforce_permission.permission_name' in cp_config:
                    data['x-required-permission'] = cp_config['tools.enforce_permission.permission_name']

        operations.update(new_operations)
        return None

def parse_model(spec, model_cls):
    kwargs = {
        'properties': {},
        'type': 'object',
        'required': [],
    }
    for key, obj in model_cls.__dict__.items():
        if isinstance(obj, FieldDescriptor):
            kwargs['properties'][key] = parse_model_type(spec, model_cls._fields[key])
            if model_cls._fields[key].required:
                kwargs['required'].append(key)

    if len(kwargs['required']) == 0:
        del kwargs['required']

    return kwargs

def parse_model_type(spec, model_type):
    swagger_types = {
        StringType: 'string',
        NameType: 'string',
        UUIDType: 'string',
        EmailType: 'string',
        EnumType: 'string',
        ArrowType: 'string',
        IntType: 'integer',
        BooleanType: 'boolean',
        ListType: 'array',
        DictType: 'object',
        ModelType: 'object',
    }

    data = {
        # Find the swagger type, if not found default to string
        # It would be nice to have complex types like uuid, emails, ect...
        # But swagger doesn't support it
        "type": swagger_types.get(model_type.__class__, "string")
    }

    if model_type.__class__ == EnumType:
        data['enum'] = [x.value for x in model_type.enum_class]

    if model_type.__class__ == ListType:
        if model_type.field.__class__ == ModelType:
            try:
                spec.components.schema(model_type.field.model_class.__name__,
                                       component=parse_model(spec, model_type.field.model_class))
            except DuplicateComponentNameError:
                pass
            data['items'] = {
                '$ref': '#/components/schemas/' + model_type.field.model_class.__name__
            }
        else:
            data['items'] = parse_model_type(spec, model_type.field)

    if model_type.__class__ == DictType:
        data['additionalProperties'] = parse_model_type(spec, model_type.field)

    if model_type.__class__ == ModelType:
        try:
            spec.components.schema(model_type.model_class.__name__, component=parse_model(spec, model_type.model_class))
        except DuplicateComponentNameError:
            pass
        data['additionalProperties'] = {
            '$ref': '#/components/schemas/' + model_type.model_class.__name__
        }

    return data


import copy
import re
import string
from pprint import pprint

import awkward as ak
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import matplotlib.animation as animation
from tqdm import tqdm
from numba import njit

# %%

directions = np.loadtxt('input', dtype=object).item()
jets = np.array([1 if jet == '>' else -1 for jet in directions])

# %%

shapes = [[[0, 1, 2, 3, 3], [0, 0, 0, 0, 0]],
          [[0, 1, 1, 1, 2], [1, 0, 1, 2, 1]],
          [[0, 1, 2, 2, 2], [0, 0, 0, 1, 2]],
          [[0, 0, 0, 0, 0], [0, 1, 2, 3, 3]],
          [[0, 0, 1, 1, 1], [0, 1, 0, 1, 1]]]
shapes = np.array(shapes)

for shape in shapes:
    s = np.zeros((4, 4))
    s[tuple(shape)] = 1
    plt.imshow(s.T, origin='lower')
    plt.show()

# %%

@njit
def run_simulation(shapes, jets, stopped_rocks):
    height = 500
    width = 7
    height_thresh = 40
    height_move = 30
    grid_height = 0
    grid = np.zeros((width, height))
    grid[:, 0] = 1
    jet_i = 0
    max_ys = []
    tower_heights = []
    for i in range(stopped_rocks):
        if i % 10_000 == 0:
            print(i, 'out of', stopped_rocks)
        shape = shapes[i % len(shapes)]
        max_y = [(np.where(grid == 1)[1])[np.where(grid == 1)[0] == iter_x].max() for iter_x in range(width)]

        if (np.array(max_y) > height_thresh).all():
            grid[:, :-height_move] = grid[:, height_move:]
            grid_height += height_move
            max_y = [(np.where(grid == 1)[1])[np.where(grid == 1)[0] == iter_x].max() for iter_x in range(width)]

        tower_heights.append([i, grid_height + max(max_y)])

        rock_x = 2
        rock_y = max(max_y) + 4
        max_ys.append([i % len(shapes)] + max_y)  # before rock falls, without jet_i index
        # max_ys.append([i % len(shapes), jet_i] + max_y)  # before rock falls, with jet_i index

        # grid[np.array(shape[0]) + rock_x, np.array(shape[1]) + rock_y] = 1
        # plt.imshow(grid[:, :10].T, origin='lower')
        # plt.show()
        # grid = np.zeros((width, 10_000), dtype=int)
        # grid[:, 0] = 1

        while True:
            # jet
            rock_x += jets[jet_i % len(jets)]
            cord_x = [rock_x + x for x in shape[0]]
            if (max(cord_x) >= width) or (min(cord_x) < 0) or np.array([int(grid[rock_x + x, rock_y + y]) for x, y in shape.T]).sum() > 0:
                rock_x -= jets[jet_i % len(jets)]
            jet_i += 1

            # falling
            rock_y -= 1
            check_grid = [grid[rock_x + x, rock_y + y] for x, y in shape.T]
            if np.array(check_grid).sum() > 0:
                # hit bottom, place rock and continue with next rock
                rock_y += 1
                for x, y in shape.T:
                    grid[x + rock_x, y + rock_y] = 1
                break

        # plt.imshow(grid[:, :10].T, origin='lower')
        # plt.show()

    max_ys = np.array(max_ys)
    return grid, grid_height, max_ys, tower_heights

# %%

stopped_rocks = 50_000
grid, grid_height, max_ys, tower_heights = run_simulation(shapes, jets, stopped_rocks)
width = grid.shape[0]
max_y = [(np.where(grid == 1)[1])[np.where(grid == 1)[0] == iter_x].max() for iter_x in range(width)]
print(f'tower height : {max_y} --> {grid_height + max(max_y)}')
plt.figure(figsize=(10, 10))
# plt.imshow(grid[:, :20].T, origin='lower')
plt.imshow(grid[:, max(max_y) - 20:max(max_y) + 2].T, origin='lower')
plt.show()

# %%

def get_tower_height(stopped_rocks, max_ys, shapes, tower_heights):
    last_shape = (stopped_rocks - 1) % len(shapes)
    max_ys[:, 2:] = max_ys[:, 2:] - max_ys[:, 2:].min(axis=1)[np.newaxis].T
    max_ys_shape = max_ys[max_ys[:, 0] == last_shape]
    u, i, c = np.unique(max_ys_shape, return_counts=True, return_index=True, axis=0)
    last_unique = np.where(np.all(max_ys == max_ys_shape[i[-1]], axis=1))[0][0]
    periods = np.diff(np.where(np.all(max_ys == max_ys_shape[i[-1]], axis=1))[0])
    period = np.unique(periods).sum()
    print('start index:', last_unique)
    print('period:', period)
    init_config = last_unique + (stopped_rocks - last_unique) % period
    height_increase = tower_heights[init_config + period][1] - tower_heights[init_config][1]
    tower_height = tower_heights[init_config][1] + height_increase * (stopped_rocks - init_config) / period
    assert int(tower_height) == tower_height
    return int(tower_height)

# %%

for stopped_rocks in [2022, 1_000_000_000_000]:
    print(f'solution for {stopped_rocks} stopped rocks:', get_tower_height(stopped_rocks, max_ys, shapes, tower_heights))

# 3147
# 1532163742758
# %%


from typing import List

def intcode(phase_setting, inp, data: List[int], inp_count=0, i=0, pre_out=False) -> tuple:
    out = 0
    pos = 2
    base = 0
    memory = {}
    while not data[i] % 100 == 99:
        t_op = data[i]
        if t_op % 100 == 3:
            ind = data[i + 1] if t_op < 100 else (i + 1) if t_op < 200 else (data[i + 1] + base)
            if ind < len(data):
                data[ind] = inp if inp_count else phase_setting
            else:
                memory[ind] = inp if inp_count else phase_setting
            inp_count += 1
            i += 2
            continue
        elif t_op % 100 == 4:
            index = data[i + 1] if t_op < 100 else (i + 1) if t_op < 200 else (data[i + 1] + base)
            out = data[index] if index < len(data) else get_mem(memory, index)
            pos = 0
            i += 2
            if pre_out:
                print(out)
                #break
            continue
        elif t_op % 100 == 9:
            ind = data[i + 1] if t_op < 100 else (i + 1) if t_op < 200 else (data[i + 1] + base)
            base += data[ind] if ind < len(data) else get_mem(memory, ind)
            i += 2
            continue
        elif t_op % 100 in [5, 6]:
            dat = t_op // 100
            check = t_op % 100
            ind_1 = data[i + 1] if dat == 0 or dat % 10 == 0 else (i + 1) if dat % 10 == 1 else (data[i + 1] + base)
            ind_2 = data[i + 2] if dat == 0 or (dat // 10) % 10 == 0 else (i + 2) if (dat // 10) % 10 == 1 else (data[i + 2] + base)
            el2 = data[ind_2] if ind_2 < len(data) else get_mem(memory, ind_2)
            el1 = data[ind_1] if ind_1 < len(data) else get_mem(memory, ind_1)
            if el1 and check == 5:
                i = el2
            elif not el1 and check == 6:
                i = el2
            else:
                i += 3
            continue
        code, el1, el2, save_pos = data[i:i+4]
        if code > 99:
            opcode = code % 100
            if ((code // 100) % 10) % 2 == 0:
                ind_1 = el1 if (code // 100) % 10 == 0 else (el1 + base)
                el1 = data[el1] if ind_1 < len(data) else get_mem(memory, ind_1)

            if ((code // 1000) % 10) % 2 == 0:
                ind_2 = el2 if (code // 1000) % 10 == 0 else (el2 + base)
                el2 = data[el2] if ind_2 < len(data) else get_mem(memory, ind_2)

            if (code // 10000) % 2 == 0:
                save_pos = save_pos if code // 10000 == 0 else (save_pos + base)
        else:
            opcode = code
            el1 = data[el1] if el1 < len(data) else get_mem(memory, el1)
            el2 = data[el2] if el2 < len(data) else get_mem(memory, el2)
        if opcode in [1, 2]:
            if save_pos < len(data):
                data[save_pos] = (el1 + el2) if opcode == 1 else (el1 * el2)
            else:
                memory[save_pos] = (el1 + el2) if opcode == 1 else (el1 * el2)
        elif opcode in [7, 8]:
            if save_pos < len(data):
                data[save_pos] = int(el1 < el2) if opcode == 7 else int(el1 == el2)
            else:
                memory[save_pos] = int(el1 < el2) if opcode == 7 else int(el1 == el2)
        else:
            break
        i += 4
    return i, out, pos

def get_mem(memory, index):
    if index not in memory.keys():
        memory[index] = 0
    return memory[index]

with open("input.txt", "r") as file:
    inp = [int(x) for x in file.readline().split(",")]
    print("Part 1: ", intcode(phase_setting=1, inp=None, data=inp, pre_out=False)[1])
    print("Part 2: ", intcode(phase_setting=2, inp=None, data=inp, pre_out=False)[1])


from PIL import Image
import numpy as np
import os

def save_minmax(filename, min, max):
    file = open(filename, "wb")
    file.write("{} {}\n".format(min, max).encode('utf-8'))
    file.close()

for k in range(150):
    scan_path = os.path.join('./depths','scan%05d' % k)
    if(os.path.exists(scan_path)==False):
        continue

    for i in range(80):
        path = os.path.join('./depths','scan%05d' % k, '%03d.png' % i)
        depth_pil = Image.open(path)
        depth_image = np.array(depth_pil)
        pix = depth_image/1000.0
        min_value = 100
        max_value = pix[0,0]
        for x in range(512):
            for y in range(512):
                if(pix[x,y]>max_value):
                    max_value = pix[x,y]
                if(pix[x,y]<min_value and pix[x,y]!=0):
                    min_value = pix[x,y]

        minmax_file_path = os.path.join('./minmaxs', 'scan%05d' % k)
        os.makedirs(minmax_file_path, exist_ok=True)
        minmax_file_name = os.path.join(minmax_file_path,'minmax_map_%03d.txt' % i)
        save_minmax(minmax_file_name, min_value, max_value)


from utils import *
import sys, getopt
import os
import glob
import imageio
## tmp file
def f(inputfile, outputfile):
    # img_array, origin, spacing = load_itk(inputfile)
    # # img_array = 1 - img_array #(img_array > 0).astype(float)
    # img_array[img_array > 0.5] = 1.0
    # img_array[img_array <= 0.5] = 0.0
    # save_itk(outputfile, img_array, origin = origin, spacing = spacing)
    # nrrd2nii(inputfile, outputfile)
    img = np.asarray(imageio.imread(inputfile)).astype(float)
    print(img.shape)
    img = zoom(img, target_shape = (1250, 1250))
    # img = np.mean(img, axis=2)

    # for i in range(len(img.shape)):
    #     img[:, :, i] = zoom(img[:, :, i], target_shape = (256, 256))
    imageio.imwrite(outputfile, img)
def main(argv):
    inputfile = ''
    outputfile = ''
    opts, args = getopt.getopt(argv, "hi:o:", ['help', 'input', 'output'])
    if len(opts) == 0:
        print('unknow options, usage: batch_process.py -i <inputfile> -o <outputfile>')
        sys.exit()
    for opt, arg in opts:
        if opt in ('-h', '--help'):
            print('usage: batch_process.py -i <inputfile> -o <outputfile> ')
            sys.exit()
        elif opt in ("-i", '--input'):
            inputfile = arg
        elif opt in ("-o", '--output'):
            outputfile = arg
        else:
            print('unknow option, usage: batch_process.py -i <inputfile> -o <outputfile>')
            sys.exit()

    if os.path.isdir(inputfile):
        if not os.path.isdir(outputfile):
            os.makedirs(outputfile)
        input_files = sorted(glob.glob(os.path.join(inputfile, '*.png')))
        for ifile in input_files:
            _, filename = os.path.split(ifile)
            filename, _ = os.path.splitext(filename)
            # filename, _ = os.path.splitext(filename)
            filename = filename.split('_')[0]
            ofile = outputfile+'/'+ filename + '.png'
            print(ofile)
            f(ifile, ofile)
    else:
        f(inputfile, outputfile)
if __name__ == "__main__":
    main(sys.argv[1:])


from backend.api.sapiens import Sapiens
from fastapi import Query

s = Sapiens()

champion_id_param = Query(
    None,
    title="champion_id",
    description="Unique identifier assigned to champion in the game",
    example=1,
)
lane_param = Query(
    "default",
    title="lane",
    description="Specific lane for champion to play in. Options include: 'default', 'top', 'jungle', 'middle', 'bottom', 'support'. Default: default",
    example="support",
)
tier_param = Query(
    "platinum_plus",
    title="tier",
    description="The tier of data that you would like to use. Some options: 'gold', 'gold_plus', 'platinum_plus', 'emerald_plus', '1trick', etc. Default: platinum_plus",
    example="gold_plus",
)
queue_mode_param = Query(
    "ranked",
    title="queue_mode",
    description="Queue mode to play. Options include: 'ranked', 'aram'. Default: ranked",
    example="ranked",
)
keystone_id_param = Query(
    0,
    title="keystone_id",
    description="Unique identifier associated with keystone to play. \
        If the keystone_id is zero uses recommended keystone. Default: 0",
    example=8214,
)
spicy_param = Query(
    0,
    title="spicy_factor",
    description="Spicy factor, an int value between 0 and 4. Default: 0",
    example=1,
)
limit_param = Query(
    10,
    title="limit",
    description="The maximum number of items to return in a single request. Default: 10",
    example=12,
)
random_param = Query(
    0,
    title="random",
    description="Return a random sample of a specified size from the available results. \
        If the size is set to zero, all available results will be returned. Default: 0",
    example=5,
)


#!/usr/bin/env python

# Pylint runs from a different directory, it's fine to import this way
# pylint: disable=W0403

import os
import shutil
import sys
import tempfile
import types
import unittest

def mock(mod_path):
    name_list = mod_path.split('.')
    child_name = name_list.pop()
    child_mod = sys.modules.get(mod_path, types.ModuleType(child_name))
    if len(name_list) == 0:  # child_name is left-most basic module
        if child_name not in sys.modules:
            sys.modules[child_name] = child_mod
        return sys.modules[child_name]
    else:
        # New or existing child becomes parent
        recurse_path = ".".join(name_list)
        parent_mod = mock(recurse_path)
        if not hasattr(sys.modules[recurse_path], child_name):
            setattr(parent_mod, child_name, child_mod)
            # full-name also points at child module
            sys.modules[mod_path] = child_mod
        return sys.modules[mod_path]

class FakeCmdResult(object):

    def __init__(self, **dargs):
        for key, val in dargs.items():
            setattr(self, key, val)

RUN_CACHE = []

def get_run_cache():
    global RUN_CACHE
    return RUN_CACHE

def kill_run_cache():
    global RUN_CACHE
    RUN_CACHE = []

def run(command, *args, **dargs):
    command = "%s" % (command)
    get_run_cache().append({'command': command, 'args': args, 'dargs': dargs})
    return FakeCmdResult(command=command.strip(),
                         stdout="""
REPOSITORY                    TAG                 IMAGE ID                                                           CREATED             VIRTUAL SIZE
192.168.122.245:5000/fedora   32                  0d20aec6529d5d396b195182c0eaa82bfe014c3e82ab390203ed56a774d2c404   5 weeks ago         387 MB
fedora                        32                  0d20aec6529d5d396b195182c0eaa82bfe014c3e82ab390203ed56a774d2c404   5 weeks ago         387 MB
fedora                        rawhide             0d20aec6529d5d396b195182c0eaa82bfe014c3e82ab390203ed56a774d2c404   5 weeks ago         387 MB
192.168.122.245:5000/fedora   latest              58394af373423902a1b97f209a31e3777932d9321ef10e64feaaa7b4df609cf9   5 weeks ago         385.5 MB
fedora                        20                  58394af373423902a1b97f209a31e3777932d9321ef10e64feaaa7b4df609cf9   5 weeks ago         385.5 MB
fedora                        heisenbug           58394af373423902a1b97f209a31e3777932d9321ef10e64feaaa7b4df609cf9   5 weeks ago         385.5 MB
fedora                        latest              58394af373423902a1b97f209a31e3777932d9321ef10e64feaaa7b4df609cf9   5 weeks ago         385.5 MB
""",
                         stderr=str(dargs),
                         exit_status=len(args),
                         duration=len(dargs))

# Mock module and mock function run in one command
setattr(mock('autotest.client.utils'), 'run', run)
setattr(mock('autotest.client.utils'), 'CmdResult', FakeCmdResult)
setattr(mock('autotest.client.test'), 'test', object)
setattr(mock('autotest.client.shared.error'), 'TestFail', Exception)
setattr(mock('autotest.client.shared.error'), 'CmdError', Exception)
setattr(mock('autotest.client.shared.error'), 'TestError', Exception)
setattr(mock('autotest.client.shared.error'), 'TestNAError', Exception)
setattr(mock('autotest.client.shared.error'), 'AutotestError', Exception)
setattr(mock('autotest.client.shared.version'), 'get_version',
        lambda: version.AUTOTESTVERSION)
mock('autotest.client.shared.base_job')
mock('autotest.client.shared.job')
mock('autotest.client.shared.utils')
mock('autotest.client.job')

import version

class ImageTestBase(unittest.TestCase):

    defaults = {}
    customs = {}
    config_section = "Foo/Bar/Baz"

    def _setup_inifile(self, cfgsection, cfgdir, cfgdict):
        osfd, filename = tempfile.mkstemp(suffix='.ini',
                                          dir=cfgdir)
        os.close(osfd)
        # ConfigSection will open again
        cfgfile = open(filename, 'wb')
        cfgfile.close()
        # ConfigDict forbids writing
        cfgsect = self.config.ConfigSection(None, cfgsection)
        for key, val in cfgdict.items():
            cfgsect.set(key, val)
        cfgsect.set('__example__', '')
        cfgsect.write(cfgfile)
        return filename

    def _setup_defaults(self):
        self.config.DEFAULTSFILE = self._setup_inifile('DEFAULTS',
                                                       self.config.CONFIGDEFAULT,
                                                       self.defaults)

    def _setup_customs(self):
        self._setup_inifile(self.config_section,
                            self.config.CONFIGCUSTOMS,
                            self.customs)

    def _make_fake_subtest(self):
        class FakeSubtestException(Exception):

            def __init__(fake_self, *args, **dargs):  # pylint: disable=E0213
                # Unittest magic pylint: disable=E1003
                super(FakeSubtestException, self).__init__()
                # Unittest magic pylint: enable=E1003

        class FakeSubtest(self.subtest.Subtest):
            version = "1.2.3"
            config_section = self.config_section
            iteration = 1
            iterations = 1

            def __init__(fake_self, *args, **dargs):  # pylint: disable=E0213
                config_parser = self.config.Config()
                fake_self.config = config_parser.get(self.config_section)
                for symbol in ('execute', 'setup', 'initialize', 'run_once',
                               'postprocess_iteration', 'postprocess',
                               'cleanup', 'failif',):
                    setattr(fake_self, symbol, FakeSubtestException)
                for symbol in ('logdebug', 'loginfo', 'logwarning', 'logerror'):
                    setattr(fake_self, symbol, lambda *_a, **_d: None)

        return FakeSubtest()

    def setUp(self):
        import config
        import images
        import subtest
        self.config = config
        self.images = images
        self.subtest = subtest
        self.config.CONFIGDEFAULT = tempfile.mkdtemp(self.__class__.__name__)
        self.config.CONFIGCUSTOMS = tempfile.mkdtemp(self.__class__.__name__)
        self._setup_defaults()
        self._setup_customs()
        self.fake_subtest = self._make_fake_subtest()

    def tearDown(self):
        shutil.rmtree(self.config.CONFIGDEFAULT, ignore_errors=True)
        shutil.rmtree(self.config.CONFIGCUSTOMS, ignore_errors=True)
        self.assertFalse(os.path.isdir(self.config.CONFIGDEFAULT))
        self.assertFalse(os.path.isdir(self.config.CONFIGCUSTOMS))
        del self.config
        del self.images
        del self.subtest

class DockerImageTestBasic(ImageTestBase):

    defaults = {'docker_path': '/foo/bar', 'docker_options': '--not_exist',
                'docker_timeout': 60.0, 'docker_repo_name': 'fedora',
                'docker_repo_tag': 'latest', 'docker_registry_host': '192.168.122.245:5000',
                'docker_registry_user': '', 'preserve_fqins': 'fedora:32, fedora:heisenbug'}
    customs = {}
    config_section = "Foo/Bar/Baz"

    def test_defaults_cli(self):
        d = self.images.DockerImages(self.fake_subtest)
        all_images = d.list_imgs()
        full_name = d.list_imgs_full_name()
        self.assertEqual(full_name,
                         ['192.168.122.245:5000/fedora:32',
                          'fedora:32',
                          'fedora:rawhide',
                          '192.168.122.245:5000/fedora:latest',
                          'fedora:20',
                          'fedora:heisenbug',
                          'fedora:latest'])

        ids = d.list_imgs_ids()
        self.assertEqual(ids,
                         ['58394af373423902a1b97f209a31e3777932d9321ef10e64feaaa7b4df609cf9',
                          '0d20aec6529d5d396b195182c0eaa82bfe014c3e82ab390203ed56a774d2c404'])

        test_im = self.images.DockerImage("fedora",
                                          "latest",
                                          ("58394af373423902a1b97f209a31e3777"
                                           "932d9321ef10e64feaaa7b4df609cf9"),
                                          "5 weeks ago",
                                          "385.5 MB")
        self.assertTrue(test_im in all_images)
        self.assertEqual(all_images.index(test_im), 6)

        images = str(d.list_imgs_with_full_name(full_name[2]))
        self.assertEqual(images,
                         "[DockerImage(full_name:fedora:rawhide LONG_ID:0d20aec6529d5d396b195182c0eaa82bfe014c3e82ab390203ed56a774d2c404 CREATED:5 weeks ago SIZE:387 MB)]")

        images = str(d.list_imgs_with_full_name("fedora:latest"))
        exp = ("[DockerImage(full_name:192.168.122.245:5000/fedora:latest LONG_ID:58394af373423902a1b97f209a31e3777932d9321ef10e64feaaa7b4df609cf9 CREATED:5 weeks ago SIZE:385.5 MB),"
               " DockerImage(full_name:fedora:latest LONG_ID:58394af373423902a1b97f209a31e3777932d9321ef10e64feaaa7b4df609cf9 CREATED:5 weeks ago SIZE:385.5 MB)]")
        self.assertEqual(images, exp)

        act = self.images.DockerImages.filter_list_full_name(all_images,
                                                             "fedora:"
                                                             "latest")
        self.assertEqual(str(act), exp)

        images = str(d.list_imgs_with_full_name_components(repo_addr="192.168.122.245:5000"))
        exp = ("[DockerImage(full_name:192.168.122.245:5000/fedora:32 LONG_ID:0d20aec6529d5d396b195182c0eaa82bfe014c3e82ab390203ed56a774d2c404 CREATED:5 weeks ago SIZE:387 MB),"
               " DockerImage(full_name:192.168.122.245:5000/fedora:latest LONG_ID:58394af373423902a1b97f209a31e3777932d9321ef10e64feaaa7b4df609cf9 CREATED:5 weeks ago SIZE:385.5 MB)]")
        self.assertEqual(images, exp)
        act = self.images.DockerImages.filter_list_by_components(all_images,
                                                                 repo_addr='192.168.122.245:5000')
        self.assertEqual(str(act), exp)

        images = str(d.list_imgs_with_full_name_components(repo_addr="192.168.122.245:5000",
                                                           tag="32"))
        self.assertEqual(images,
                         "[DockerImage(full_name:192.168.122.245:5000/fedora:32 LONG_ID:0d20aec6529d5d396b195182c0eaa82bfe014c3e82ab390203ed56a774d2c404 CREATED:5 weeks ago SIZE:387 MB)]")

        images = d.list_imgs_with_image_id(all_images[2].long_id)
        self.assertEqual(str(images),
                         "[DockerImage(full_name:192.168.122.245:5000/fedora:32 LONG_ID:0d20aec6529d5d396b195182c0eaa82bfe014c3e82ab390203ed56a774d2c404 CREATED:5 weeks ago SIZE:387 MB),"
                         " DockerImage(full_name:fedora:32 LONG_ID:0d20aec6529d5d396b195182c0eaa82bfe014c3e82ab390203ed56a774d2c404 CREATED:5 weeks ago SIZE:387 MB),"
                         " DockerImage(full_name:fedora:rawhide LONG_ID:0d20aec6529d5d396b195182c0eaa82bfe014c3e82ab390203ed56a774d2c404 CREATED:5 weeks ago SIZE:387 MB)]",)

    def test_name_comparison_dockerimage(self):
        di_ref = self.images.DockerImage("fedora_repo", "last_tag",
                                         ("0d20aec6529d5d396b195182c0eaa82bfe0"
                                          "14c3e82ab390203ed56a774d2c404"),
                                         "dd",
                                         "50 MB",
                                         "fedora_addr", "user_user")

        di_ref2 = self.images.DockerImage("fedora_repo", "last_tag",
                                          ("0d20aec6529d5d396b195182c0eaa82bfe0"
                                           "14c3e82ab390203ed56a774d2c404"),
                                          "dd",
                                          "50 MB",
                                          "fedora_addr", "user_user")

        di_dif = self.images.DockerImage("fedora3_repo", "last_tag",
                                         ("0d20aec6529d5d396b195182c0eaa82bfe0"
                                          "14c3e82ab390203ed56a774d2c404"),
                                         "dd",
                                         "50 MB",
                                         "fedora_addr", "user_user")

        full_name = "fedora_addr/user_user/fedora_repo:last_tag"
        (repo, tag, repo_addr, user) = self.images.DockerImage.split_to_component(
            full_name)
        self.assertRaises(self.images.DockerFullNameFormatError,
                          self.images.DockerImage.split_to_component, ["dd/"])
        self.assertRaises(self.images.DockerFullNameFormatError,
                          self.images.DockerImage.split_to_component,
                          ["dd/aa/ss/ss"])
        self.assertRaises(self.images.DockerFullNameFormatError,
                          self.images.DockerImage.split_to_component,
                          ["dd/aa:aa/ss"])

        self.assertRaises(self.images.DockerFullNameFormatError,
                          self.images.DockerImage.split_to_component,
                          ["<none>:<none>"])

        self.assertEqual(self.images.DockerImage.full_name_from_component(
            repo, tag, repo_addr, user), full_name)

        self.assertEqual((repo, tag, repo_addr, user),
                         ("fedora_repo", "last_tag", "fedora_addr",
                          "user_user"))
        self.assertTrue(di_ref.cmp_full_name_with_component(repo, tag, repo_addr, user))
        self.assertFalse(di_ref.cmp_full_name_with_component(repo, tag, repo_addr=repo_addr))
        self.assertTrue(di_ref.cmp_greedy(repo, repo_addr=repo_addr, user=user))
        self.assertTrue(di_ref.cmp_greedy(repo))
        self.assertTrue(di_ref.cmp_greedy(repo, repo_addr=repo_addr))
        self.assertTrue(di_ref.cmp_greedy(repo, user=user))
        self.assertTrue(di_ref.cmp_greedy(repo_addr=repo_addr))
        self.assertFalse(di_ref.cmp_greedy(repo=repo_addr))
        self.assertTrue(di_ref == di_ref2)
        self.assertFalse(di_ref == di_dif)

        self.assertTrue(self.images.DockerImage(
            "fedora_addr:44/user_user/"
            "fedora_repo:last_tag", None,
            "0d20aec6529d5d396b195182c0eaa82bfe0"
            "14c3e82ab390203ed56a774d2c404",
            "dd",
            "50 MB",
            None,
            None).cmp_full_name_with_component("fedora_repo",
                                               "last_tag",
                                               "fedora_addr:44",
                                               "user_user"))

        self.assertTrue(di_ref.cmp_id(di_ref2.short_id))
        self.assertTrue(di_ref.cmp_id(di_ref2.long_id))
        self.assertFalse(di_ref.cmp_id('11111111111'))
        self.assertFalse(di_ref.cmp_id('1111111111111111111111111111111111'))

        self.assertTrue(di_ref.cmp_full_name(di_ref2.full_name))
        self.assertFalse(di_ref.cmp_full_name(di_dif.full_name))

        config = {'docker_repo_name': 'fedora', 'docker_repo_tag': '',
                  'docker_registry_user': '', 'docker_registry_host': ''}
        act = self.images.DockerImage.full_name_from_defaults(config)
        self.assertEqual(act, 'fedora')

    def test_docker_110_id_parsing(self):
        """
        Docker 1.10 image and container IDs include a "sha256:" prefix;
        make sure our parsing code strips off the prefix but still returns
        a valid short_id
        """
        id_components = ["sha256:", "0123456789ab",    # <-- 12-char short id
                         "9dcfe46a8f465344284a3538cd"  # <-- + 52 chars = 64
                         "6b0beeb18b4f249619fec4a659"]
        long_id = "".join(id_components)
        di = self.images.DockerImage("myrepo", "a", long_id, "bb", "cc", "dd")
        self.assertEqual(di.long_id, long_id)
        self.assertEqual(di.short_id, id_components[1])

    def test_bastard_repo(self):
        test = "bAsTaRd-rEPo.lOcAl_hOsT:1073741824/.b+o-F_H./a.s-d_f:F.d-S_a"
        DI = self.images.DockerImage
        repo, tag, addr, user = DI.split_to_component(test)
        di = DI(repo, tag, '0' * 64, None, None, addr, user)
        self.assertEqual(di.full_name, test)

    def test_user_no_addr(self):
        test = "user/repo:tag"
        DI = self.images.DockerImage
        repo, tag, addr, user = DI.split_to_component(test)
        self.assertEqual(repo, 'repo')
        self.assertEqual(tag, 'tag')
        self.assertEqual(user, 'user')
        self.assertEqual(addr, None)

    def test_addr_no_user(self):
        test = "address:1234/repo:tag"
        DI = self.images.DockerImage
        repo, tag, addr, user = DI.split_to_component(test)
        self.assertEqual(repo, 'repo')
        self.assertEqual(tag, 'tag')
        self.assertEqual(user, None)
        self.assertEqual(addr, "address:1234")

    def test_empty_tag(self):
        """
        Empty tag names seen in docker-1.9 output of 'docker events'
        in some tag actions. docker-1.10 seems to forbid trailing colon.
        """
        test = "myname:"   # note the trailing colon with no actual tag name
        DI = self.images.DockerImage
        repo, tag, addr, user = DI.split_to_component(test)
        self.assertEqual(repo, 'myname')
        self.assertEqual(tag, '')
        self.assertEqual(user, None)
        self.assertEqual(addr, None)

    def test_remove_cli(self):
        d = self.images.DockerImages(self.fake_subtest, 1.0, True)
        self.assertEqual(d.remove_image_by_id('123456789012').command,
                         "/foo/bar rmi 123456789012")
        self.assertEqual(d.remove_image_by_id('123456789012').command,
                         "/foo/bar rmi 123456789012")
        self.assertEqual(d.remove_image_by_full_name('fedora:latest').command,
                         "/foo/bar rmi fedora:latest")
        img_id = ("0d20aec6529d5d396b195182c0eaa82b"
                  "fe014c3e82ab390203ed56a774d2c404")
        image_obj = self.images.DockerImage("fedora_repo", "last_tag",
                                            img_id,
                                            "dd",
                                            "50 MB",
                                            None, "user_user")
        self.assertEqual(d.remove_image_by_image_obj(image_obj).command,
                         "/foo/bar rmi user_user/fedora_repo:last_tag")

        image_notag = self.images.DockerImage("fedora_repo", "<none>",
                                              img_id,
                                              "dd",
                                              "50 MB",
                                              None, "user_user")
        self.assertEqual(d.remove_image_by_image_obj(image_notag).command,
                         "/foo/bar rmi %s" % img_id)

    def test_docker_images_lowlevel(self):
        images = self.images.DockerImages(self.fake_subtest)

        self.assertEqual(images.docker_cmd("command_pass").command,
                         '/foo/bar command_pass')

    def test_clean_all(self):
        d = self.images.DockerImages(self.fake_subtest)
        names = set(d.list_imgs_full_name())
        # staticly set in fake config, REMOVE names to be preserved
        preserve = set(['fedora:heisenbug',
                        'fedora:32',
                        '192.168.122.245:5000/fedora:latest'])
        expected = names - preserve
        kill_run_cache()
        d.clean_all(names)
        pfx = '/foo/bar rmi --force '
        cutlen = len(pfx)
        cleaned_names = set()
        for item in get_run_cache():
            command = item['command']
            self.assertTrue(command.startswith(pfx))
            cleaned_names.add(command[cutlen:])
        # no preserved names should be in either list
        self.assertEqual(cleaned_names, expected)
        self.assertTrue(cleaned_names.isdisjoint(preserve))

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


from flask import Flask, request
import requests
from waitress import serve
from twilio.twiml.messaging_response import MessagingResponse
from pyngrok import ngrok

#Gunicorn
#from gunicorn.app.wsgiapp import run

#Flask app
app = Flask(__name__)

#Ngrok tunneling
#http_tunnel = ngrok.connect()
#ssh_tunnel = ngrok.connect(22, "tcp")

#Webservices
@app.route('/bot', methods=['POST'])
def bot():
    incoming_msg = request.values.get('Body', '').lower()
    resp = MessagingResponse()
    msg = resp.message()
    responded = False
    if 'quote' in incoming_msg:
        # return a quote
        r = requests.get('https://api.quotable.io/random')
        if r.status_code == 200:
            data = r.json()
            quote = f'{data["content"]} ({data["author"]})'
        else:
            quote = 'I could not retrieve a quote at this time, sorry.'
        msg.body(quote)
        responded = True
    if 'cat' in incoming_msg:
        # return a cat pic
        msg.media('https://cataas.com/cat')
        responded = True
    if not responded:
        msg.body('I only know about famous quotes and cats, sorry!')
    return str(resp)

# This is the main function
if __name__ == "__main__":
    app.run(host="127.0.0.1", port=5000, debug = True)


import torch
import esm

import numpy as np
import os
os.environ["CUDA_VISIBLE_DEVICES"] = "0"

from typing import List, Tuple, Optional, Dict, NamedTuple, Union, Callable
import string
from scipy.spatial.distance import cdist
from Bio import SeqIO

torch.set_grad_enabled(False)

class esmmsa1b(object):
    deletekeys = dict.fromkeys(string.ascii_lowercase)
    deletekeys["."] = None
    deletekeys["*"] = None
    translation = str.maketrans(deletekeys)

    def __init__(self,msa):#str->file
        self.msa=self.read_msa(msa)

    def remove_insertions(self,sequence: str) -> str:
        return sequence.translate(self.translation)

    def read_msa(self,filename: str) -> List[Tuple[str, str]]:
        return [(record.description, self.remove_insertions(str(record.seq))) for record in SeqIO.parse(filename, "fasta")]

    def greedy_select(self,msa: List[Tuple[str, str]], num_seqs: int, mode: str = "max") -> List[Tuple[str, str]]:
        assert mode in ("max", "min")

        if len(msa) <= num_seqs:
            return msa

        array = np.array([list(seq) for _, seq in msa], dtype=np.bytes_).view(np.uint8)

        optfunc = np.argmax if mode == "max" else np.argmin
        all_indices = np.arange(len(msa))
        indices = [0]
        pairwise_distances = np.zeros((0, len(msa)))
        for _ in range(num_seqs - 1):
            dist = cdist(array[indices[-1:]], array, "hamming")
            pairwise_distances = np.concatenate([pairwise_distances, dist])
            shifted_distance = np.delete(pairwise_distances, indices, axis=1).mean(0)
            shifted_index = optfunc(shifted_distance)
            index = np.delete(all_indices, indices)[shifted_index]
            indices.append(index)
        indices = sorted(indices)
        return [msa[idx] for idx in indices]

    def get_embedding(self,num_seqs=128):
        msa_transformer, msa_transformer_alphabet = esm.pretrained.esm_msa1b_t12_100M_UR50S()
        msa_transformer = msa_transformer.eval().cuda()
        msa_transformer_batch_converter = msa_transformer_alphabet.get_batch_converter()
        inputs = self.greedy_select(self.msa, num_seqs=num_seqs)
        msa_transformer_batch_labels, msa_transformer_batch_strs, msa_transformer_batch_tokens = msa_transformer_batch_converter([inputs])
        msa_transformer_batch_tokens = msa_transformer_batch_tokens.to(next(msa_transformer.parameters()).device)
        if msa_transformer_batch_tokens.shape[2]>1024:
            index=msa_transformer_batch_tokens.shape[2]-1024
            msa_transformer_batch_tokens1=msa_transformer_batch_tokens[:,:,:1024]
            msa_transformer_batch_tokens2=msa_transformer_batch_tokens[:,:,-1024:]
            results1=msa_transformer(msa_transformer_batch_tokens1, repr_layers=[12], return_contacts=False)['representations'][12]
            results2=msa_transformer(msa_transformer_batch_tokens2, repr_layers=[12], return_contacts=False)['representations'][12]
            results=torch.cat((results1[:,:,:index,:],
                              (results1[:,:,index:,:]+results2[:,:,:-index,:])/2,
                                results2[:,:,-index:,:]),dim=2)
        else:
            results=msa_transformer(msa_transformer_batch_tokens, repr_layers=[12], return_contacts=False)['representations'][12]
        results=torch.mean(results[0],dim=0)[1:,:]
        results=results.cpu().numpy()
        return results

import esm.inverse_folding
from utils.PDBfuc import PDB

class esmif(object):
    def __init__(self,pdb):#str->file
        self.pdb=PDB(pdb)

    def GetSeq(self,pdb):
        return ''.join([pdb.three_to_one[pdb.het_to_atom[x[0]]] for x in pdb.xulie])

    def GetCoords(self,pdb):
        coorddict=pdb.coord
        def fuc(res,x):
            if x in coorddict[res]:
                return list(coorddict[res][x])
            else:
                return [float('inf'),float('inf'),float('inf')]
        coords=list()
        for _,_,res in pdb.xulie:
            coords.append([fuc(res,x) for x in ['N','CA','C']])
        return np.array(coords,dtype=np.float32)

    def get_embedding(self,):
        model, alphabet = esm.pretrained.esm_if1_gvp4_t16_142M_UR50()
        model = model.eval()
        coords=self.GetCoords(self.pdb)
        result=esm.inverse_folding.util.get_encoder_output(model, alphabet, coords)
        result=result.detach().numpy()
        return result

if __name__=='__main__':
    import pickle
    feat=esmif('../demo/6chv_D.pdb').get_embedding()
    print(feat.shape)
    with open('../demo/esmif.pkl','wb') as f:
        pickle.dump(feat,f)