"""Provides iTrack reporting functions"""
import functools
from datetime import datetime, timedelta

import numpy as np
import pandas as pd
from pandas.tseries.offsets import BDay
import matplotlib.pyplot as plt
import seaborn as sns

from . import api
from ..utils.recipes import const, bool2int
from ..auth import BasicAuth

sns.set(style='white')
sns.set_palette(sns.color_palette("Paired"))

AUTH = BasicAuth.from_env('ITRACK')
SERVER = ('itrack.barco.com', 443)
TODAY = datetime.today().date()
LAST_YEAR = TODAY - timedelta(days=356)
BLUE, DARK_BLUE, GREEN, DARK_GREEN, RED, DARK_RED = sns.color_palette()
MARKERS = ['D', '*', 'o', 'v', '^', '<', '>', '1', '2', '3', '4', 's', 'p',
           ',', 'h', 'H', '+', 'x', '.', 'd']

def add_metadata(data, config, pqm=True, experience=True):
    """
    Adds PQM and Experience metadata to `data`.

    Parameters
    ----------
    data -- pandas.DataFrame
    config -- dict
        Mapping with the PQM configuration
    pqm, experience -- bool
        Flags indicating whether or not to add the respective column
    """
    df = data.copy()
    if pqm:
        df['PQM'] = df.project.map(lambda x: config.get(x, 'Other'))
    if experience:
        df['Experience'] = df.project.map(
            lambda x: config.get(x, 'Other-').split('-')[0]
        )
    return df

def add_measures(data):
    """
    Adds the measures columns to `data`.

    Parameters
    ----------
    data -- pandas.DataFrame
    """

    def _busday(start, end, n=1):
        def _inner(df):
            return ((df[start].fillna(TODAY) + BDay(n) >= df[end].fillna(TODAY))
                    .map(bool2int))
        return _inner

    measures = ('N', 'FRT_10', 'TRT_20')
    funcs = (const(1), _busday('created', 'investigated', n=10),
             _busday('created', 'closuredate', n=20))

    df = data.copy().assign(
        **{k: func for k, func in zip(measures, funcs)}
    )

    # these measures make no sense for the recent dates --> clear these
    for measure, n in zip(measures[1:], (10, 20)):
        df.loc[df.created >= TODAY - BDay(n), measure] = np.nan

    return df

def calculate_trend(data, start=LAST_YEAR):
    """
    Calculates trend measures for `data`.

    Parameters
    ----------
    data -- pandas.DataFrame
    """
    def _timeseries(data, x='created', y='N', agg='sum', freq='B'):
        return (data.rename(columns={x:'DT'}).set_index('DT').sort_index()
                .resample(freq)[y].agg(agg).fillna(0))

    return pd.DataFrame(dict(
        created=_timeseries(data),
        resolved=_timeseries(data, x='closuredate'),
        FRT_10=_timeseries(data, y='FRT_10', agg='mean'),
        TRT_20=_timeseries(data, y='TRT_20', agg='mean')
    ))[start:]

def load(config, start=LAST_YEAR):
    """
    Returns the active and hist aspect of the iTrack report.

    Parameters
    ----------
    config -- dict
        Mapping with a 'pqms' key with the project to PQM mapping
    """

    # load the history
    JQL = 'filter=26769 and (created > {0:%Y-%m-%d} or closed > {0:%Y-%m-%d})'
    jql = JQL.format(start)
    hist = api.search(
        jql, auth=AUTH, server=SERVER
    ).pipe(add_metadata, config['pqms']).pipe(add_measures)

    # load the active
    active = api.search(
        'filter=27347', auth=AUTH, server=SERVER
    ).pipe(add_metadata, config['pqms'])

    return active, hist

def pyplot(title=None, xlabel=None, ylabel=None, legend=True):
    """
    Decorator factory adding formatting matplotlib Axes returned from decorated
    function.

    Parameters
    ----------
    title -- Unicode
        the title to add to the Axes
    xlabel -- Unicode
        the label of the X-axis of the Axes
    ylabel -- Unicode
        the label of the Y-axis of the Axes
    legend -- bool
        whether or not to show the legend
    """
    def _decorator(func):
        @functools.wraps(func)
        def _wrapper(*args, **kwargs):
            ax = func(*args, **kwargs)
            if title is not None:
                ax.set_title(title, loc='left')
            if xlabel is not None:
                ax.set_xlabel(xlabel)
            if ylabel is not None:
                ax.set_ylabel(ylabel)
            if legend:
                ax.legend(loc='best', fancybox=True, framealpha=0.5)
            sns.despine(ax=ax)
            return ax
        return _wrapper
    return _decorator

@pyplot(
    title='Age vs. Idle (active)',
    xlabel='Age (BD)', ylabel='Idle (BD)'
)
def age_vs_idle_scatter(data, ax):
    """
    Plots Age vs. Idle of `data` on Axes `ax`.

    Parameters
    ----------
    data -- pandas.DataFrame
    ax -- matplotlib.axes.Axes
    """
    groups = data.groupby('status')
    kws = dict(alpha=0.9, ls='')
    for lbl, grp, m in zip(*zip(*groups), MARKERS):
        ax.plot(grp.age, grp.idle, label=lbl, marker=m, **kws)
    return ax

@pyplot(
    title='Priority vs. Severity (active)',
    ylabel='Tickets'
)
def priority_vs_severity_bars(data, ax):
    """
    Plots priority vs. severity of `data` on Axes `ax`.

    Parameters
    ----------
    data -- pandas.DataFrame
    ax -- matplotlib.axes.Axes
    """
    data.copy().assign(N=1).groupby(
        ['priority', 'severity']
    ).N.sum().unstack().plot.bar(stacked=True, ax=ax)
    return ax

@pyplot(
    title='Status (active)', legend=False
)
def status_pie(data, ax, n=4):
    """
    Plots status pie chart of `data` on Axes `ax`.

    Parameters
    ----------
    data -- pandas.DataFrame
    ax -- matplotlib.axes.Axes
    """
    ys = data.status.value_counts()
    selected = ys.nlargest(n)
    other = sum(v for k, v in ys.items() if k not in selected.index.tolist())
    items = list(selected.items()) + [('Other', other)] if other > 0 else list(selected.items())
    labels, sizes = zip(*items)
    ax.pie(sizes, labels=labels, autopct='%1.0f%%', shadow=True)
    return ax

@pyplot(
    title='PQM (active)', legend=False
)
def pqm_pie(data, ax, n=4):
    """
    Plots PQM pie chart of `data` on Axes `ax`.

    Parameters
    ----------
    data -- pandas.DataFrame
    ax -- matplotlib.axes.Axes
    """
    ys = data.PQM.value_counts()
    selected = ys.nlargest(n)
    other = sum(v for k, v in ys.items() if k not in selected.index.tolist())
    items = list(selected.items()) + [('Other', other)] if other > 0 else list(selected.items())
    labels, sizes = zip(*items)
    ax.pie(sizes, labels=labels, autopct='%1.0f%%', shadow=True)
    return ax

@pyplot(
    title='Created vs. Resolved (CUMUL)',
    ylabel='Tickets'
)
def created_vs_resolved_cumul(data, ax):
    """
    Plots created vs. resolved (cumulative) of `data` on Axes `ax`.

    Parameters
    ----------
    data -- pandas.DataFrame
    ax -- matplotlib.axes.Axes
    """
    columns = ('created', 'resolved')
    x = data.index
    ys = [data[col].cumsum() for col in columns]
    for y, lbl, color in zip(ys, ['Created', 'Resolved'], [RED, GREEN]):
        ax.plot(x, y, label=lbl, color=color)
    y1, y2 = ys
    ax.fill_between(x, y1, y2, where=y1 >= y2, facecolor=RED, alpha=0.1)
    ax.fill_between(x, y2, y1, where=y2 >= y1, facecolor=GREEN, alpha=0.1)
    return ax

@pyplot(
    title='Unresolved (CUMUL)',
    ylabel='Tickets'
)
def unresolved_cumul(data, ax):
    """
    Plots unresolved (cumulative) of `data` on Axes `ax`.

    Parameters
    ----------
    data -- pandas.DataFrame
    ax -- matplotlib.axes.Axes
    """
    x = data.index
    y = data.created.cumsum() - data.resolved.cumsum()
    ax.plot(x, y, label='$\Delta$ Unresolved', color=BLUE)
    return ax

@pyplot(
    title='Created vs. Resolved (7MA)',
    ylabel='Tickets'
)
def created_vs_resolved_rolling(data, ax):
    """
    Plots created vs. resolved (7MA) of `data` on Axes `ax`.

    Parameters
    ----------
    data -- pandas.DataFrame
    ax -- matplotlib.axes.Axes
    """
    columns = ('created', 'resolved')
    x = data.index
    ys = [data[col].rolling(7).mean() for col in columns]
    for y, lbl, color in zip(ys, ['Created', 'Resolved'], [RED, GREEN]):
        ax.plot(x, y, label=lbl, color=color)
    y1, y2 = ys
    ax.fill_between(x, y1, y2, where=y1 >= y2, facecolor=RED, alpha=0.1)
    ax.fill_between(x, y2, y1, where=y2 >= y1, facecolor=GREEN, alpha=0.1)
    return ax

@pyplot(
    title='Responsiveness (7MA)',
    ylabel='Percentage'
)
def responsiveness_rolling(data, ax):
    """
    Plots responsiveness (7MA) of `data` on Axes `ax`.

    Parameters
    ----------
    data -- pandas.DataFrame
    ax -- matplotlib.axes.Axes
    """
    columns = ('FRT_10', 'TRT_20', 'created')
    x = data.index
    y1, y2, total = [data[col].rolling(7).mean() for col in columns]
    y1.loc[TODAY - pd.tseries.offsets.BDay(10):] = np.nan
    y2.loc[TODAY - pd.tseries.offsets.BDay(20):] = np.nan
    ax.plot(x, y1 * 100 / total, label='% Investigated < 10BD', color=BLUE, ls='--')
    ax.plot(x, y2 * 100 / total, label='% Resolved < 20BD', color=BLUE)
    ax.set_ylim([0, 100])
    return ax

def plot(active, trend, options):

    fig = plt.figure(figsize=(11, 11))
    fig.suptitle(options['name'])

    grid_specs = [(0, 0, 3, 1), (1, 0, 3, 1), (2, 0, 3, 1), (3, 0, 3, 1),
                  (0, 3, 3, 1), (1, 3, 3, 1), (2, 3, 3, 1), (3, 3, 3, 1),]

    axes = [plt.subplot2grid((4, 5), (x, y), colspan=c, rowspan=r)
            for x, y, c, r in grid_specs]

    created_vs_resolved_cumul(trend, axes[0])
    unresolved_cumul(trend, axes[1])
    created_vs_resolved_rolling(trend, axes[2])
    responsiveness_rolling(trend, axes[3])
    age_vs_idle_scatter(active, axes[4])
    status_pie(active, axes[5])
    priority_vs_severity_bars(active, axes[6])
    pqm_pie(active, axes[7])

    plt.tight_layout()
    fig.subplots_adjust(bottom=0.1, top=0.9)

    created = int(trend.created.sum())
    resolved = int(trend.resolved.sum())
    high = len(active.query('severity == "S1" | priority == "P1"'))
    total = len(active)

    txt1 = r'Trend: {:d} created and {:d} resolved in last 356 days'.format(
        created, resolved
    )
    fig.text(0.5, 0.04, txt1, horizontalalignment='center')
    txt2 = r'Active: {:d} total and {:d} P1/S1'.format(total, high)
    fig.text(0.5, 0, txt2, horizontalalignment='center')

    return fig


from flask import Flask, request, Response
from kik import KikApi, Configuration
from kik.messages import messages_from_json, TextMessage, PictureMessage, SuggestedResponseKeyboard, TextResponse, StartChattingMessage
import pymysql
conn = pymysql.connect(host='localhost', port=3306, user='root', passwd='', db='db_kik')
curs = conn.cursor()

class KikBot(Flask):

    """ Flask kik bot application class"""

    def __init__(self, kik_api, import_name, static_path=None, static_url_path=None, static_folder="static",
                 template_folder="templates", instance_path=None, instance_relative_config=False,
                 root_path=None):

        self.kik_api = kik_api

        super(KikBot, self).__init__(import_name, static_path, static_url_path, static_folder, template_folder,
                                     instance_path, instance_relative_config, root_path)

        self.route("/incoming", methods=["POST"])(self.incoming)

    def incoming(self):
        """Handle incoming messages to the bot. All requests are authenticated using the signature in
        the 'X-Kik-Signature' header, which is built using the bot's api key (set in main() below).
        :return: Response
        """
        # verify that this is a valid request
        if not self.kik_api.verify_signature(
                request.headers.get("X-Kik-Signature"), request.get_data()):
            return Response(status=403)

        messages = messages_from_json(request.json["messages"])

        response_messages = []

        for message in messages:
            user = self.kik_api.get_user(message.from_user)
            # Check if its the user's first message. Start Chatting messages are sent only once.
            if isinstance(message, StartChattingMessage):

                response_messages.append(TextMessage(
                    to=message.from_user,
                    chat_id=message.chat_id,
                    body="haloo {}, pilihlah salah satu?".format(user.first_name),
                    # keyboards are a great way to provide a menu of options for a user to respond with!
                    keyboards=[SuggestedResponseKeyboard(responses=[TextResponse("Good"), TextResponse("ga")])]))

            # Check if the user has sent a text message.
            elif isinstance(message, TextMessage):
                user = self.kik_api.get_user(message.from_user)
                message_body = message.body.lower()
                print(message_body)
                sql = """insert into tb_inbox(user, message)
                        values ('%s','%s')""" % (user.first_name, message_body)
                print("Berhasil Menginputkan")

                curs.execute(sql)

                conn.commit()

                if message_body.split()[0] in ["hi", "hello", "hallo"]:
                    query = "SELECT in_message FROM tb_perintah"
                    curs.execute(query)
                    menu = curs.fetchall()
                    print(message_body)
                    print(menu)
                    msg = "List Menu !!\n"
                    iterasi = 1
                    for x in menu:
                        for y in x:
                            print(y)
                            msg = msg + ""+str(iterasi)+". "+y+"\n"
                        iterasi+=1
                    response_messages.append(TextMessage(
                        to=message.from_user,
                        chat_id=message.chat_id,
                        body=msg.format(user.first_name),
                        keyboards=[SuggestedResponseKeyboard(responses=[TextResponse("1"), TextResponse("2"), TextResponse("3"), TextResponse("4")])]))

                    query = "INSERT INTO tb_outbox (user,message,status) VALUES('%s','%s','1')" % (user.first_name, message_body)
                    curs.execute(query)
                    conn.commit()

                elif message_body.startswith("#"):

                    msg = message_body.split()

                    print(msg[0])

                    query = "SELECT query FROM tb_perintah WHERE marker = '%s' " % (msg[0])

                    print(query)

                    try:

                        curs.execute(query)

                    except:

                        print("ERROR")

                    menu = curs.fetchone()

                    print(menu[0])

                    if menu != None:

                        try:

                            msgProdi = msg[6] + " " + msg[7]

                            print(msgProdi)

                            qry = menu[0] % ("%" + msg[3] + "%", "%" + msgProdi + "%")

                        except:

                            print("INDEX MESSAGE TIDAK DITEMUKAN")

                            qry = menu[0]

                        print(qry)

                        curs.execute(qry)

                        data = curs.fetchall()

                        iterasi = 0

                        teks = ""

                        msgNew = ""

                        for row in data:

                            for i in curs.description:
                                print(i[0])

                                print(row[iterasi])

                                msgNew = msgNew + (i[0] + " = " + str(row[iterasi]) + "\n")

                                iterasi += 1

                                # if iterasi == i*4:

                                #     msgNew = "\n"

                                # else:

                                #     msgNew = ""

                            iterasi = 0

                    query = "INSERT INTO tb_outbox (user,message,status) VALUES('%s','%s','0')" % (

                        user.first_name, message_body)

                    print(query)

                    curs.execute(query)

                    conn.commit()

                    response_messages.append(TextMessage(

                        to=message.from_user,

                        chat_id=message.chat_id,

                        body=msgNew))

                else:
                    print(int(message_body))
                    query = "SELECT * FROM tb_perintah WHERE id_perintah = %i " %(int(message_body))
                    curs.execute(query)
                    menu = curs.fetchone()
                    print(message.from_user)
                    print(message.chat_id)
                    print(menu[2])
                    response_messages.append(TextMessage(
                        to=message.from_user,
                        chat_id=message.chat_id,
                        body=menu[2].format(user.first_name)))

                query = "INSERT INTO tb_outbox (user,message,status) VALUES('%s','%s','1')" % (user.first_name, message_body, )
                curs.execute(query)
                conn.commit()

                #query = "INSERT INTO tb_outbox (user,message) VALUES('%s','%s')" % (user.first_name, message_body)
                #curs.execute(query)
                #conn.commit()

                # elif message_body == "1":
                #     response_messages.append(TextMessage(
                #         to=message.from_user,
                #         chat_id=message.chat_id,
                #         body="masukan nama mahasiswa :",
                #         keyboards=[SuggestedResponseKeyboard(
                #             responses=[TextResponse("miftah")])]))
                #
                #
                #
                # elif message_body == "2":
                #     response_messages.append(TextMessage(
                #         to=message.from_user,
                #         chat_id=message.chat_id,
                #         body="Masukan nama dosen :",
                #         keyboards=[SuggestedResponseKeyboard(
                #             responses=[TextResponse("boleh"), TextResponse("tidak")])]))
                #
                # elif message_body == "3":
                #     response_messages.append(TextMessage(
                #         to=message.from_user,
                #         chat_id=message.chat_id,
                #         body="masukan semua mahasiswa :",
                #         keyboards=[SuggestedResponseKeyboard(
                #             responses=[TextResponse("boleh"), TextResponse("tidak")])]))
                #
                # elif message_body == "4":
                #     response_messages.append(TextMessage(
                #         to=message.from_user,
                #         chat_id=message.chat_id,
                #         body="masukan semua dosen :",
                #         keyboards=[SuggestedResponseKeyboard(
                #             responses=[TextResponse("boleh"), TextResponse("tidak")])]))
                #

                    # Send the user a response along with their profile picture (function definition is below)

            #
            #     elif message_body in ["Engga","tidak", "Gak mau"]:
            #         response_messages.append(TextMessage(
            #             to=message.from_user,
            #             chat_id=message.chat_id,
            #             body="Okedeh, {}. Semangat yaa, jangan lupa chat aku lagi :)".format(user.first_name)))
            #     else:
            #         response_messages.append(TextMessage(
            #             to=message.from_user,
            #             chat_id=message.chat_id,
            #             body="maaf om {}, saya ga ngerti yang di maksud".format(user.first_name),
            #             keyboards=[SuggestedResponseKeyboard(responses=[TextResponse("boleh"), TextResponse("Engga")])]))

            # If its not a text message, give them another chance to use the suggested responses
            else:

                response_messages.append(TextMessage(
                    to=message.from_user,
                    chat_id=message.chat_id,
                    body="maaf itu apa ya {}?".format(user.first_name),
                    keyboards=[SuggestedResponseKeyboard(responses=[TextResponse("Good"), TextResponse("Bad")])]))

            # We're sending a batch of messages. We can send up to 25 messages at a time (with a limit of
            # 5 messages per user).

            self.kik_api.send_messages(response_messages)

        return Response(status=200)

    @staticmethod
    def profile_pic_check_messages(user, message):
        """Function to check if user has a profile picture and returns appropriate messages.
        :param user: Kik User Object (used to acquire the URL the profile picture)
        :param message: Kik message received by the bot
        :return: Message
        """

        messages_to_send = []
        profile_picture = user.profile_pic_url

        if profile_picture is not None:
            messages_to_send.append(
                # Another type of message is the PictureMessage - your bot can send a pic to the user!
                PictureMessage(
                    to=message.from_user,
                    chat_id=message.chat_id,
                    pic_url=profile_picture
                ))

            profile_picture_response = "ini dia foto kamuu!"
        else:
            profile_picture_response = "ga mirip loh, yaudh lah yaa"

        messages_to_send.append(
            TextMessage(to=message.from_user, chat_id=message.chat_id, body=profile_picture_response))

        return messages_to_send

if __name__ == "__main__":
    """ Main program """
    kik = KikApi('botmca', 'fffa79e9-afe9-45e4-b2bd-6ec78732b3de')
    # For simplicity, we're going to set_configuration on startup. However, this really only needs to happen once
    # or if the configuration changes. In a production setting, you would only issue this call if you need to change
    # the configuration, and not every time the bot starts.
    kik.set_configuration(Configuration(webhook='https://c6aaa154.ngrok.io/incoming'))
    app = KikBot(kik, __name__)
    app.run(port=8080, host='127.0.0.1', debug=True)


from flask import Flask, render_template, jsonify, request

app = Flask(__name__)

import requests
from bs4 import BeautifulSoup

from pymongo import MongoClient
client = MongoClient('localhost', 27017)
db = client.dbsparta

## HTML을 주는 부분
@app.route('/')
def home():
    return render_template('index.html')

## API 역할을 하는 부분

@app.route('/listing', methods=['GET'])
def listing():
    movies = list(db.netflix.find({}, {'_id' : False}).limit(10))
    return jsonify({'all_movies' : movies})

@app.route('/saving', methods=['POST'])
def saving():

    headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36'}
    data = requests.get('https://movie.naver.com/movie/running/current.naver#', headers=headers)

    soup = BeautifulSoup(data.text, 'html.parser')

    watch = soup.select('#content > div.article > div:nth-child(1) > div.lst_wrap > ul > li')

    for movie in watch:
        url = movie.select_one('div > a')['href']
        image = movie.select_one('div > a > img')['src']
        title = movie.select_one('dl > dt > a').text
        rating = movie.select_one('dl > dd.star > dl.info_star > dd > div > a > span.num').text[0:3]
        limit = movie.select_one('span', {'class': 'ico_rating_15'}).text
        onecat = movie.select_one('span > a:nth-child(1)', {'class': 'link_txt'}).text
        twocat = movie.select_one('span > a:nth-child(2)', {'class': 'link_txt'}).text

        doc = {
            'url': url,
            'image': image,
            'title': title,
            'rating': rating,
            'limit': limit,
            'category_1': onecat,
            'category_2': twocat,
        }

        db.netflix.insert_one(doc)

if __name__ == '__main__':
    app.run('0.0.0.0', port=5000, debug=True)


"""
This module contains the top-level routines for the quasisymmetric
stellarator construction.
"""

import logging
import numpy as np
from scipy.io import netcdf
#from numba import jit

#logging.basicConfig(level=logging.DEBUG)
logger = logging.getLogger(__name__)

class Qsc():
    """
    This is the main class for representing the quasisymmetric
    stellarator construction.
    """

    # Import methods that are defined in separate files:
    from .init_axis import init_axis, convert_to_spline
    from .calculate_r1 import _residual, _jacobian, solve_sigma_equation, \
        _determine_helicity, r1_diagnostics
    from .grad_B_tensor import calculate_grad_B_tensor, calculate_grad_grad_B_tensor, \
        Bfield_cylindrical, Bfield_cartesian, grad_B_tensor_cartesian, \
        grad_grad_B_tensor_cylindrical, grad_grad_B_tensor_cartesian
    from .calculate_r2 import calculate_r2
    from .calculate_r3 import calculate_r3, calculate_shear
    from .mercier import mercier
    from .r_singularity import calculate_r_singularity
    from .plot import plot, plot_boundary, get_boundary, B_fieldline, B_contour, plot_axis, flux_tube
    from .Frenet_to_cylindrical import Frenet_to_cylindrical, to_RZ
    from .to_vmec import to_vmec
    from .util import B_mag

    def __init__(self, rc, zs, rs=[], zc=[], nfp=1, etabar=1., sigma0=0., B0=1.,
                 I2=0., sG=1, spsi=1, nphi=61, B2s=0., B2c=0., p2=0., order="r1"):
        """
        Create a quasisymmetric stellarator.
        """
        # First, force {rc, zs, rs, zc} to have the same length, for
        # simplicity.
        nfourier = np.max([len(rc), len(zs), len(rs), len(zc)])
        self.nfourier = nfourier
        self.rc = np.zeros(nfourier)
        self.zs = np.zeros(nfourier)
        self.rs = np.zeros(nfourier)
        self.zc = np.zeros(nfourier)
        self.rc[:len(rc)] = rc
        self.zs[:len(zs)] = zs
        self.rs[:len(rs)] = rs
        self.zc[:len(zc)] = zc

        # Force nphi to be odd:
        if np.mod(nphi, 2) == 0:
            nphi += 1

        if sG != 1 and sG != -1:
            raise ValueError('sG must be +1 or -1')

        if spsi != 1 and spsi != -1:
            raise ValueError('spsi must be +1 or -1')

        self.nfp = nfp
        self.etabar = etabar
        self.sigma0 = sigma0
        self.B0 = B0
        self.I2 = I2
        self.sG = sG
        self.spsi = spsi
        self.nphi = nphi
        self.B2s = B2s
        self.B2c = B2c
        self.p2 = p2
        self.order = order
        self.min_R0_threshold = 0.3
        self._set_names()

        self.calculate()

    def change_nfourier(self, nfourier_new):
        """
        Resize the arrays of Fourier amplitudes. You can either increase
        or decrease nfourier.
        """
        rc_old = self.rc
        rs_old = self.rs
        zc_old = self.zc
        zs_old = self.zs
        index = np.min((self.nfourier, nfourier_new))
        self.rc = np.zeros(nfourier_new)
        self.rs = np.zeros(nfourier_new)
        self.zc = np.zeros(nfourier_new)
        self.zs = np.zeros(nfourier_new)
        self.rc[:index] = rc_old[:index]
        self.rs[:index] = rs_old[:index]
        self.zc[:index] = zc_old[:index]
        self.zs[:index] = zs_old[:index]
        nfourier_old = self.nfourier
        self.nfourier = nfourier_new
        self._set_names()
        # No need to recalculate if we increased the Fourier
        # resolution, only if we decreased it.
        if nfourier_new < nfourier_old:
            self.calculate()

    def calculate(self):
        """
        Driver for the main calculations.
        """
        self.init_axis()
        self.solve_sigma_equation()
        self.r1_diagnostics()
        if self.order != 'r1':
            self.calculate_r2()
            if self.order == 'r3':
                self.calculate_r3()

    def get_dofs(self):
        """
        Return a 1D numpy vector of all possible optimizable
        degrees-of-freedom, for simsopt.
        """
        return np.concatenate((self.rc, self.zs, self.rs, self.zc,
                               np.array([self.etabar, self.sigma0, self.B2s, self.B2c, self.p2, self.I2, self.B0])))

    def set_dofs(self, x):
        """
        For interaction with simsopt, set the optimizable degrees of
        freedom from a 1D numpy vector.
        """
        assert len(x) == self.nfourier * 4 + 7
        self.rc = x[self.nfourier * 0 : self.nfourier * 1]
        self.zs = x[self.nfourier * 1 : self.nfourier * 2]
        self.rs = x[self.nfourier * 2 : self.nfourier * 3]
        self.zc = x[self.nfourier * 3 : self.nfourier * 4]
        self.etabar = x[self.nfourier * 4 + 0]
        self.sigma0 = x[self.nfourier * 4 + 1]
        self.B2s = x[self.nfourier * 4 + 2]
        self.B2c = x[self.nfourier * 4 + 3]
        self.p2 = x[self.nfourier * 4 + 4]
        self.I2 = x[self.nfourier * 4 + 5]
        self.B0 = x[self.nfourier * 4 + 6]
        self.calculate()
        logger.info('set_dofs called with x={}. Now iota={}, elongation={}'.format(x, self.iota, self.max_elongation))

    def _set_names(self):
        """
        For simsopt, sets the list of names for each degree of freedom.
        """
        names = []
        names += ['rc({})'.format(j) for j in range(self.nfourier)]
        names += ['zs({})'.format(j) for j in range(self.nfourier)]
        names += ['rs({})'.format(j) for j in range(self.nfourier)]
        names += ['zc({})'.format(j) for j in range(self.nfourier)]
        names += ['etabar', 'sigma0', 'B2s', 'B2c', 'p2', 'I2', 'B0']
        self.names = names

    @classmethod
    def from_paper(cls, name, **kwargs):
        """
        Get one of the configurations that has been used in our papers.
        Available values for ``name`` are
        ``"r1 section 5.1"``,
        ``"r1 section 5.2"``,
        ``"r1 section 5.3"``,
        ``"r2 section 5.1"``,
        ``"r2 section 5.2"``,
        ``"r2 section 5.3"``,
        ``"r2 section 5.4"``, and
        ``"r2 section 5.5"``.
        These last 5 configurations can also be obtained by specifying an integer 1-5 for ``name``.
        The configurations that begin with ``"r1"`` refer to sections in
        Landreman, Sengupta, and Plunk, Journal of Plasma Physics 85, 905850103 (2019).
        The configurations that begin with ``"r2"`` refer to sections in
        Landreman and Sengupta, Journal of Plasma Physics 85, 815850601 (2019).

        You can specify any other arguments of the ``Qsc`` constructor
        in ``kwargs``. You can also use ``kwargs`` to override any of
        the properties of the configurations from the papers. For
        instance, you can modify the value of ``etabar`` in the first
        example using

        .. code-block::

          q = qsc.Qsc.from_paper('r1 section 5.1', etabar=1.1)
        """

        def add_default_args(kwargs_old, **kwargs_new):
            """
            Take any key-value arguments in ``kwargs_new`` and treat them as
            defaults, adding them to the dict ``kwargs_old`` only if
            they are not specified there.
            """
            for key in kwargs_new:
                if key not in kwargs_old:
                    kwargs_old[key] = kwargs_new[key]

        if name == "r1 section 5.1":
            """ The configuration from Landreman, Sengupta, Plunk (2019), section 5.1 """
            add_default_args(kwargs, rc=[1, 0.045], zs=[0, -0.045], nfp=3, etabar=-0.9)

        elif name == "r1 section 5.2":
            """ The configuration from Landreman, Sengupta, Plunk (2019), section 5.2 """
            add_default_args(kwargs, rc=[1, 0.265], zs=[0, -0.21], nfp=4, etabar=-2.25)

        elif name == "r1 section 5.3":
            """ The configuration from Landreman, Sengupta, Plunk (2019), section 5.3 """
            add_default_args(kwargs, rc=[1, 0.042], zs=[0, -0.042], zc=[0, -0.025], nfp=3, etabar=-1.1, sigma0=-0.6)

        elif name == "r2 section 5.1" or name == '5.1' or name == 1:
            """ The configuration from Landreman & Sengupta (2019), section 5.1 """
            add_default_args(kwargs, rc=[1, 0.155, 0.0102], zs=[0, 0.154, 0.0111], nfp=2, etabar=0.64, order='r3', B2c=-0.00322)

        elif name == "r2 section 5.2" or name == '5.2' or name == 2:
            """ The configuration from Landreman & Sengupta (2019), section 5.2 """
            add_default_args(kwargs, rc=[1, 0.173, 0.0168, 0.00101], zs=[0, 0.159, 0.0165, 0.000985], nfp=2, etabar=0.632, order='r3', B2c=-0.158)

        elif name == "r2 section 5.3" or name == '5.3' or name == 3:
            """ The configuration from Landreman & Sengupta (2019), section 5.3 """
            add_default_args(kwargs, rc=[1, 0.09], zs=[0, -0.09], nfp=2, etabar=0.95, I2=0.9, order='r3', B2c=-0.7, p2=-600000.)

        elif name == "r2 section 5.4" or name == '5.4' or name == 4:
            """ The configuration from Landreman & Sengupta (2019), section 5.4 """
            add_default_args(kwargs, rc=[1, 0.17, 0.01804, 0.001409, 5.877e-05],
                       zs=[0, 0.1581, 0.01820, 0.001548, 7.772e-05], nfp=4, etabar=1.569, order='r3', B2c=0.1348)

        elif name == "r2 section 5.5" or name == '5.5' or name == 5:
            """ The configuration from Landreman & Sengupta (2019), section 5.5 """
            add_default_args(kwargs, rc=[1, 0.3], zs=[0, 0.3], nfp=5, etabar=2.5, sigma0=0.3, I2=1.6, order='r3', B2c=1., B2s=3., p2=-0.5e7)

        elif name == "LandremanPaul2021QA" or name == "precise QA":
            """
            A fit of the near-axis model to the quasi-axisymmetric
            configuration in Landreman & Paul, arXiv:2108.03711 (2021).

            The fit was performed to the boozmn data using the script
            20200621-01-Extract_B0_B1_B2_from_boozxform
            """
            add_default_args(kwargs,
                             nfp=2,
                             rc=[1.0038581971135636, 0.18400998741139907, 0.021723381370503204, 0.0025968236014410812, 0.00030601568477064874, 3.5540509760304384e-05, 4.102693907398271e-06, 5.154300428457222e-07, 4.8802742243232844e-08, 7.3011320375259876e-09],
                             zs=[0.0, -0.1581148860568176, -0.02060702320552523, -0.002558840496952667, -0.0003061368667524159, -3.600111450532304e-05, -4.174376962124085e-06, -4.557462755956434e-07, -8.173481495049928e-08, -3.732477282851326e-09],
                             B0=1.006541121335688,
                             etabar=-0.6783912804454629,
                             B2c=0.26859318908803137,
                             nphi=99,
                             order='r3')

        elif name == "precise QA+well":
            """
            A fit of the near-axis model to the precise quasi-axisymmetric
            configuration from SIMSOPT with magnetic well.

            The fit was performed to the boozmn data using the script
            20200621-01-Extract_B0_B1_B2_from_boozxform
            """
            add_default_args(kwargs,
                             nfp=2,
                             rc=[1.0145598919163676, 0.2106377247598754, 0.025469267136340394, 0.0026773601516136727, 0.00021104172568911153, 7.891887175655046e-06, -8.216044358250985e-07, -2.379942694112007e-07, -2.5495108673798585e-08, 1.1679227114962395e-08, 8.961288962248274e-09],
                             zs=[0.0, -0.14607192982551795, -0.021340448470388084, -0.002558983303282255, -0.0002355043952788449, -1.2752278964149462e-05, 3.673356209179739e-07, 9.261098628194352e-08, -7.976283362938471e-09, -4.4204430633540756e-08, -1.6019372369445714e-08],
                             B0=1.0117071561808106,
                             etabar=-0.5064143402495729,
                             B2c=-0.2749140163639202,
                             nphi=99,
                             order='r3')

        elif name == "LandremanPaul2021QH" or name == "precise QH":
            """
            A fit of the near-axis model to the quasi-helically symmetric
            configuration in Landreman & Paul, arXiv:2108.03711 (2021).

            The fit was performed to the boozmn data using the script
            20211001-02-Extract_B0_B1_B2_from_boozxform
            """
            add_default_args(kwargs,
                             nfp=4,
                             rc=[1.0033608429348413, 0.19993025252481125, 0.03142704185268144, 0.004672593645851904, 0.0005589954792333977, 3.298415996551805e-05, -7.337736061708705e-06, -2.8829857667619663e-06, -4.51059545517434e-07],
                             zs=[0.0, 0.1788824025525348, 0.028597666614604524, 0.004302393796260442, 0.0005283708386982674, 3.5146899855826326e-05, -5.907671188908183e-06, -2.3945326611145963e-06, -6.87509350019021e-07],
                             B0=1.003244143729638,
                             etabar=-1.5002839921360023,
                             B2c=0.37896407142157423,
                             nphi=99,
                             order='r3')

        elif name == "precise QH+well":
            """
            A fit of the near-axis model to the precise quasi-helically symmetric
            configuration from SIMSOPT with magnetic well.

            The fit was performed to the boozmn data using the script
            20211001-02-Extract_B0_B1_B2_from_boozxform
            """
            add_default_args(kwargs,
                             nfp=4,
                             rc=[1.000474932581454, 0.16345392520298313, 0.02176330066615466, 0.0023779201451133163, 0.00014141976024376502, -1.0595894482659743e-05, -2.9989267970578764e-06, 3.464574408947338e-08],
                             zs=[0.0, 0.12501739099323073, 0.019051257169780858, 0.0023674771227236587, 0.0001865909743321566, -2.2659053455802824e-06, -2.368335337174369e-06, -1.8521248561490157e-08],
                             B0=0.999440074325872,
                             etabar=-1.2115187546668142,
                             B2c=0.6916862277166693,
                             nphi=99,
                             order='r3')

        else:
            raise ValueError('Unrecognized configuration name')

        return cls(**kwargs)

    @classmethod
    def from_cxx(cls, filename):
        """
        Load a configuration from a ``qsc_out.<extension>.nc`` output file
        that was generated by the C++ version of QSC. Almost all the
        data will be taken from the output file, over-writing any
        calculations done in python when the new Qsc object is
        created.
        """
        def to_string(nc_str):
            """ Convert a string from the netcdf binary format to a python string. """
            temp = [c.decode('UTF-8') for c in nc_str]
            return (''.join(temp)).strip()

        f = netcdf.netcdf_file(filename, mmap=False)
        nfp = f.variables['nfp'][()]
        nphi = f.variables['nphi'][()]
        rc = f.variables['R0c'][()]
        rs = f.variables['R0s'][()]
        zc = f.variables['Z0c'][()]
        zs = f.variables['Z0s'][()]
        I2 = f.variables['I2'][()]
        B0 = f.variables['B0'][()]
        spsi = f.variables['spsi'][()]
        sG = f.variables['sG'][()]
        etabar = f.variables['eta_bar'][()]
        sigma0 = f.variables['sigma0'][()]
        order_r_option = to_string(f.variables['order_r_option'][()])
        if order_r_option == 'r2.1':
            order_r_option = 'r3'
        if order_r_option == 'r1':
            p2 = 0.0
            B2c = 0.0
            B2s = 0.0
        else:
            p2 = f.variables['p2'][()]
            B2c = f.variables['B2c'][()]
            B2s = f.variables['B2s'][()]

        q = cls(nfp=nfp, nphi=nphi, rc=rc, rs=rs, zc=zc, zs=zs,
                B0=B0, sG=sG, spsi=spsi,
                etabar=etabar, sigma0=sigma0, I2=I2, p2=p2, B2c=B2c, B2s=B2s, order=order_r_option)

        def read(name, cxx_name=None):
            if cxx_name is None: cxx_name = name
            setattr(q, name, f.variables[cxx_name][()])

        [read(v) for v in ['R0', 'Z0', 'R0p', 'Z0p', 'R0pp', 'Z0pp', 'R0ppp', 'Z0ppp',
                           'sigma', 'curvature', 'torsion', 'X1c', 'Y1c', 'Y1s', 'elongation']]
        if order_r_option != 'r1':
            [read(v) for v in ['X20', 'X2c', 'X2s', 'Y20', 'Y2c', 'Y2s', 'Z20', 'Z2c', 'Z2s', 'B20']]
            if order_r_option != 'r2':
                [read(v) for v in ['X3c1', 'Y3c1', 'Y3s1']]

        f.close()
        return q

    def min_R0_penalty(self):
        """
        This function can be used in optimization to penalize situations
        in which min(R0) < min_R0_constraint.
        """
        return np.max((0, self.min_R0_threshold - self.min_R0)) ** 2


import torch
import torch.nn.init
import torch.nn as nn
import torch.nn.functional as F
from torch.autograd import Variable
import cv2
import numpy as np

# resize image to size 32x32
cv2_scale = lambda x: cv2.resize(x, dsize=(32, 32),
                                 interpolation=cv2.INTER_LINEAR)
# reshape image
np_reshape = lambda x: np.reshape(x, (32, 32, 1))

def zeros_like(x):
    assert x.__class__.__name__.find('Variable') != -1 or x.__class__.__name__.find('Tensor') != -1, "Object is neither a Tensor nor a Variable"
    y = torch.zeros(x.size())
    if x.is_cuda:
       y = y.cuda()
    if x.__class__.__name__ == 'Variable':
        return torch.autograd.Variable(y, requires_grad=x.requires_grad)
    elif x.__class__.__name__.find('Tensor') != -1:
        return torch.zeros(y)

def ones_like(x):
    assert x.__class__.__name__.find('Variable') != -1 or x.__class__.__name__.find('Tensor') != -1, "Object is neither a Tensor nor a Variable"
    y = torch.ones(x.size())
    if x.is_cuda:
       y = y.cuda()
    if x.__class__.__name__ == 'Variable':
        return torch.autograd.Variable(y, requires_grad=x.requires_grad)
    elif x.__class__.__name__.find('Tensor') != -1:
        return torch.ones(y)

def batched_forward(model, data, batch_size, **kwargs):
    n_patches = len(data)
    if n_patches > batch_size:
        bs = batch_size
        n_batches = n_patches / bs + 1
        for batch_idx in range(n_batches):
            st = batch_idx * bs
            if batch_idx == n_batches - 1:
                if (batch_idx + 1) * bs > n_patches:
                    end = n_patches
                else:
                    end = (batch_idx + 1) * bs
            else:
                end = (batch_idx + 1) * bs
            if st >= end:
                continue
            if batch_idx == 0:
                try:
                    first_batch_out = model(data[st:end])#, kwargs)
                except:
                    first_batch_out = model(data[st:end])# kwargs)
                out_size = torch.Size([n_patches] + list(first_batch_out.size()[1:]))
                #out_size[0] = n_patches
                out = torch.zeros(out_size);
                if data.is_cuda:
                    out = out.cuda()
                out = Variable(out)
                out[st:end] = first_batch_out
            else:
                try:
                    out[st:end] = model(data[st:end])#, kwargs)
                except:
                    out[st:end] = model(data[st:end])#, kwargs)
        return out
    else:
        return model(data)#, kwargs)

class L2Norm(nn.Module):
    def __init__(self):
        super(L2Norm,self).__init__()
        self.eps = 1e-10
    def forward(self, x):
        norm = torch.sqrt(torch.sum(x * x, dim = 1) + self.eps)
        x= x / norm.unsqueeze(-1).expand_as(x)
        return x

class L1Norm(nn.Module):
    def __init__(self):
        super(L1Norm,self).__init__()
        self.eps = 1e-10
    def forward(self, x):
        norm = torch.sum(torch.abs(x), dim = 1) + self.eps
        x= x / norm.expand_as(x)
        return x

def str2bool(v):
    if v.lower() in ('yes', 'true', 't', 'y', '1'):
        return True
    elif v.lower() in ('no', 'false', 'f', 'n', '0'):
        return False

def CircularGaussKernel(kernlen=None, circ_zeros = False, sigma = None, norm = True):
    assert ((kernlen is not None) or sigma is not None)
    if kernlen is None:
        kernlen = int(2.0 * 3.0 * sigma + 1.0)
        if (kernlen % 2 == 0):
            kernlen = kernlen + 1;
        halfSize = kernlen / 2;
    halfSize = kernlen / 2;
    r2 = float(halfSize*halfSize)
    if sigma is None:
        sigma2 = 0.9 * r2;
        sigma = np.sqrt(sigma2)
    else:
        sigma2 = 2.0 * sigma * sigma
    x = np.linspace(-halfSize,halfSize,kernlen)
    xv, yv = np.meshgrid(x, x, sparse=False, indexing='xy')
    distsq = (xv)**2 + (yv)**2
    kernel = np.exp(-( distsq/ (sigma2)))
    if circ_zeros:
        kernel *= (distsq <= r2).astype(np.float32)
    if norm:
        kernel /= np.sum(kernel)
    return kernel

def generate_2dgrid(h,w, centered = True):
    if centered:
        x = torch.linspace(-w/2+1, w/2, w)
        y = torch.linspace(-h/2+1, h/2, h)
    else:
        x = torch.linspace(0, w-1, w)
        y = torch.linspace(0, h-1, h)
    grid2d = torch.stack([y.repeat(w,1).t().contiguous().view(-1), x.repeat(h)],1)
    return grid2d

def generate_3dgrid(d, h, w, centered = True):
    if type(d) is not list:
        if centered:
            z = torch.linspace(-d/2+1, d/2, d)
        else:
            z = torch.linspace(0, d-1, d)
        dl = d
    else:
        z = torch.FloatTensor(d)
        dl = len(d)
    grid2d = generate_2dgrid(h,w, centered = centered)
    grid3d = torch.cat([z.repeat(w*h,1).t().contiguous().view(-1,1), grid2d.repeat(dl,1)],dim = 1)
    return grid3d

def zero_response_at_border(x, b):
    if (b < x.size(3)) and (b < x.size(2)):
        x[:, :,  0:b, :] =  0
        x[:, :,  x.size(2) - b: , :] =  0
        x[:, :, :,  0:b] =  0
        x[:, :, :,   x.size(3) - b: ] =  0
    else:
        return x * 0
    return x

class GaussianBlur(nn.Module):
    def __init__(self, sigma=1.6):
        super(GaussianBlur, self).__init__()
        weight = self.calculate_weights(sigma)
        self.register_buffer('buf', weight)
        return
    def calculate_weights(self,  sigma):
        kernel = CircularGaussKernel(sigma = sigma, circ_zeros = False)
        h,w = kernel.shape
        halfSize = float(h) / 2.;
        self.pad = int(np.floor(halfSize))
        return torch.from_numpy(kernel.astype(np.float32)).view(1,1,h,w);
    def forward(self, x):
        w = Variable(self.buf)
        if x.is_cuda:
            w = w.cuda()
        return F.conv2d(F.pad(x, (self.pad,self.pad,self.pad,self.pad), 'replicate'), w, padding = 0)

def batch_eig2x2(A):
    trace = A[:,0,0] + A[:,1,1]
    delta1 = (trace*trace - 4 * ( A[:,0,0]*  A[:,1,1] -  A[:,1,0]* A[:,0,1]))
    mask = delta1 > 0
    delta = torch.sqrt(torch.abs(delta1))
    l1 = mask.float() * (trace + delta) / 2.0 +  1000.  * (1.0 - mask.float())
    l2 = mask.float() * (trace - delta) / 2.0 +  0.0001  * (1.0 - mask.float())
    return l1,l2

def line_prepender(filename, line):
    with open(filename, 'r+') as f:
        content = f.read()
        f.seek(0, 0)
        f.write(line.rstrip('\r\n') + '\n' + content)
    return


from flask import current_app
from . import db
from .models import Build, BuildStatus
import os

def run_builds():
    build = Build.query.filter_by(status=0).first()
    if build != None:
        build.status = BuildStatus.BUILD
        db.session.commit()
        uploads = os.path.join(current_app.config['APP_ROOT'], current_app.config['UPLOAD_FOLDER'])
        file = open(uploads + "/" + build.build_hash + ".txt", "w")
        print(uploads + "/" + build.build_hash + ".txt", "w")
        for i in range(0, 30):
            file.write("build for: " + build.build_hash + "\n")
        file.close()
        build.status = BuildStatus.SUCCESS
        db.session.commit()
    print(build)


# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.db import models, migrations

class Migration(migrations.Migration):

    dependencies = [
        ('events', '0011_auto_20150812_1138'),
    ]

    operations = [
        migrations.RenameField(
            model_name='event',
            old_name='q_num',
            new_name='refQ_num',
        ),
        migrations.AddField(
            model_name='event',
            name='sort_num',
            field=models.IntegerField(default=0, verbose_name=b'Sort Number'),
            preserve_default=True,
        ),
    ]


import logging
from settings import API_ID, API_HASH
from telethon import TelegramClient, client, events
from forwarder import _
logging.basicConfig(format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
                    level=logging.INFO)

SENT_VIA = f'\n__Sent via__ `{str(__file__)}`'

client = TelegramClient('forwarder', API_ID, API_HASH)

@client.on(events.NewMessage(outgoing=True, pattern=r'\.id'))
async def chat_id_handler(event):
    chat_id = event.chat_id
    await event.edit(str(chat_id))

@client.on(events.NewMessage(outgoing=True, pattern=r'\.info'))
async def chat_info_handler(event):
    chat_info = await event.get_chat()
    await event.edit(str(chat_info))

async def main():
    await client.send_message('me', f'''Hi!
        \n**Telegram Chat Forward** is made by @AahnikDaw.
        \nPlease star 🌟 on [GitHub](https://github.com/aahnik/telegram-chat-forward).
        \nYou can send `.id` to any chat/group/channel to get its chat id.
        \nTo get full info, send `.info`.
        \nYou may first try it here 😃
        {SENT_VIA}''', link_preview=False)

if __name__ == "__main__":
    client.start()
    client.loop.run_until_complete(main())
    print('''If this script is succesfully running,
    you will see a new message in your Saved Messages.
    Open your Telegram App and send .id to any chat, to get the chat id.
    To get all info send .info
    \nPress Ctrl + C to stop the process.''')
    client.run_until_disconnected()


#!/bin/env python

import sys, os
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("-do2016", help="do 2016", action='store_true')
parser.add_argument("-do2018", help="do 2018", action='store_true')
parser.add_argument("-add", help="add", action="store_true")
args = parser.parse_args()

# ~ csbins = ["inc", "cspos", "csneg"]
# ~ programs = ["makeFit.py", "makeGraph.py"]
programs = ["makeGraph.py"]
uncertainties = ["nominal","scaleup","scaledown","pileup","piledown","smeared","muonid"]

for unc in uncertainties:
	#cmd = "python signalYields.py -s %s"%unc
	cmd = "python signalYieldsSingleBin.py %s"%unc

	print (cmd)
	os.system(cmd)


## most up to date version of code that scans for forward and reverse binding sites
import numpy as np
import pandas as pd
from termcolor import colored
from colorama import Fore, Style
from matplotlib import pyplot
import matplotlib.patches as mpatches
import re
## imports the table of genes
dna_sequences = pd.read_csv('gstd1_thor.csv', delimiter=',')
dna_sequences
## sets the transcription factor pfm used to analyze sequence
## this is the human pfm for ATF4 (matrix id: MA0833.1)
profile = {'A': [210, 169, 639, 0, 19, 888, 2, 1, 40, 879, 888, 0, 414], 'C': [71, 117, 202, 0, 0, 0, 372, 0, 838, 21, 3, 266, 272], 'G': [442, 409, 127, 7, 1090, 0, 9, 1104, 16, 0, 1, 62, 101], 'T': [170, 213, 3, 981, 11, 25, 470, 4, 113, 3, 4, 714, 78]}
profilerevcomp = {'T': [414, 0, 888, 879, 40, 1, 2, 888, 19, 0, 639, 169, 210], 'G': [272, 266, 3, 21, 838, 0, 372, 0, 0, 0, 202, 117, 71], 'C': [101, 62, 1, 0, 16, 1104, 9, 0, 1090, 7, 127, 409, 442], 'A': [78, 714, 4, 3, 113, 4, 470, 25, 11, 981, 3, 213, 170]}
## generates maximum binding score of transcription factor
max_binding_list = []
for i in range(len(profile['A'])):
    score_list = []
    score_list.append(profile['A'][i])
    score_list.append(profile['C'][i])
    score_list.append(profile['G'][i])
    score_list.append(profile['T'][i])
    max_binding_list.append(max(score_list))
max_score = sum(max_binding_list)
## goes through DNA sequences in data frame and analyzes each
DNA_column = dna_sequences['sequence']
gene_column = dna_sequences['gene']
for i in range(len(DNA_column)):
    ## accesses sequences from spreadsheet
    DNA = DNA_column.iloc[i]
    seq = str(DNA).lower()
    gene = gene_column.iloc[i]
    print('\n' + Fore.RED + '\033[5m' + gene + Style.RESET_ALL)
    ## reads DNA sequence by creating a binding score for a segement equal to the length of the transfac binding site then shifting over one base and creating a new binding score
    def transcription_factor (seq, profile):
        width = len(profile['T'])
        bindingscore = []
        for i in range(len(seq)-width):
            score = 0
            for j in range(width):
                letter = seq[i+j]
                score += profile[letter][j]
            bindingscore.append (score)
        return bindingscore
    upperseq = seq.upper()
    bindingscores = transcription_factor(upperseq, profile)
    revcompbindingscores = transcription_factor (upperseq, profilerevcomp)
    ## generates graphs of binding sites
    pyplot.plot (revcompbindingscores)
    pyplot.ylim (0.76 * max_score, max_score)
    pyplot.plot (bindingscores, "green")
    pyplot.ylim (0.76 * max_score, max_score)
    green_patch = mpatches.Patch(color='green', label='forward strand sites')
    blue_patch = mpatches.Patch(color='blue', label='reverse strand sites')
    pyplot.legend(handles=[green_patch, blue_patch])
    pyplot.show()
    ## accesses binding site information
    forsites = []
    forpairs = []
    revsites = []
    revpairs = []
    def binding_sites (binding, sites, pairs):
        for i in range (len(binding)):
            if binding[i] > 0.76 * max_score:
                number = binding[i]
                sequence = DNA[i:i + len(profile['A'])]
                sites.append(sequence)
                percent_max_score = int(number/max_score * 100.0)
                pair = sequence.upper() + ': ' + str(percent_max_score) + " percent of the max binding score"
                pairs.append(str(pair))
        return sites, pairs
    binding_sites(bindingscores, forsites, forpairs)
    binding_sites(revcompbindingscores, revsites, revpairs)
    ## color codes sites and displays them in the DNA sequence
    def replace_all(text, sites, color):
        for i in range (len(sites)):
            visible_sites = colored(sites[i].upper(), color, attrs=['bold'])
            text = text.replace(sites[i], visible_sites)
        return text
    forDNA = replace_all(seq, forsites, 'green')
    finalDNA = replace_all(forDNA, revsites, 'blue')
    print(finalDNA)
    ##presents binding scores for both original and revcomp
    allsites = forsites + revsites
    print('\n' + Fore.RED + str(len(allsites)) + ' binding sites')
    print(Fore.BLUE + '\n'.join(revpairs) + Fore.GREEN + '\n'.join(forpairs))


from utils.dates_functions import add_months_datetime, get_calendario, get_date_to_db
from controllers.DefaultValues import DefaultValues
from django.conf import settings
from django.apps import apps

from django.db import transaction
from calendario.models import Calendario

from utils.validators import validate_string, validate_number_int
from utils.permissions import current_date, fecha_periodo
from datetime import datetime

# conexion directa a la base de datos
from django.db import connection

class CalendarioController(DefaultValues):
    def __init__(self):
        DefaultValues.__init__(self)
        self.modelo_name = 'Calendario'
        self.modelo_id = 'calendario_id'
        self.modelo_app = 'calendario'
        self.modulo_id = settings.MOD_CALENDARIO

        # variables de session
        self.modulo_session = "calendario"
        self.columnas.append('departamento')

        self.variables_filtros.append('search_departamento')
        self.variables_filtros.append('search_periodo')
        self.variables_filtros.append('search_actividad')

        self.variables_filtros_defecto['search_departamento'] = ''
        self.variables_filtros_defecto['search_actividad'] = '0'

        anio = '20' + str(datetime.now().year) if len(str(datetime.now().year)) == 2 else str(datetime.now().year)
        mes = '0' + str(datetime.now().month) if len(str(datetime.now().month)) == 1 else str(datetime.now().month)
        self.variables_filtros_defecto['search_periodo'] = anio + mes

        self.variable_page = "page"
        self.variable_page_defecto = "1"
        self.variable_order = "search_order"
        self.variable_order_value = self.columnas[0]
        self.variable_order_type = "search_order_type"
        self.variable_order_type_value = 'ASC'

        # tablas donde se debe verificar para eliminar
        self.modelos_eliminar = {}

        # control del formulario
        self.control_form = ""

    def index(self, request):
        DefaultValues.index(self, request)
        self.filtros_modulo.clear()
        #sql_add = f"AND c.status_id in ('{self.activo}','{self.inactivo}', '{self.anulado}') "
        sql_add = f"AND c.status_id in ('{self.activo}','{self.inactivo}') "
        # status
        self.filtros_modulo['status_id_id__in'] = [self.activo, self.inactivo]

        user_perfil = apps.get_model('permisos', 'UsersPerfiles').objects.get(user_id=request.user)

        # actividad
        actividad_search = self.variables_filtros_values['search_actividad'].strip()
        if actividad_search != '0':
            sql_add = f"AND c.actividad_id='{actividad_search}' "

        # periodo del calendario
        calendario = []
        # if self.variables_filtros_values['search_periodo'].strip() != "":
        periodo = self.variables_filtros_values['search_periodo'].strip()
        anio = periodo[0:4]
        mes = periodo[4:6]
        calendario = get_calendario(mes, anio)

        fecha_ini = fecha_periodo(periodo, '01')
        fecha_ini = get_date_to_db(fecha=fecha_ini, formato_ori='yyyy-mm-dd', formato='yyyy-mm-dd HH:ii:ss', tiempo='00:00:00')
        fecha_fin = add_months_datetime(fecha=fecha_ini, formato_ori='yyyy-mm-dd HH:ii:ss', meses=1, formato='yyyy-mm-dd HH:ii:ss')
        sql_add += f"AND c.fecha_actividad_ini>='{fecha_ini}' AND c.fecha_actividad_ini<'{fecha_fin}' "
        #print('sql_add: ', sql_add)

        # departamento
        depa = self.variables_filtros_values['search_departamento'].strip()
        if depa != "":
            sql_add += f"AND d.departamento LIKE '%{depa}%' "

        # lista de todos los usuarios
        users_perfiles_lista = apps.get_model('permisos', 'UsersPerfiles').objects.filter(status_id=self.status_activo)

        # lista del calendario
        sql = "SELECT c.calendario_id, c.fecha_actividad_ini, c.fecha_actividad_fin, c.fecha_reserva, c.user_perfil_id_reserva, "
        sql += "c.fecha_confirma, c.user_perfil_id_confirma, c.fecha_anula, c.user_perfil_id_anula, c.motivo_anula, "
        sql += "c.detalle, c.observacion, c.status_id, a.actividad, a.codigo, a.color_hex, d.departamento, d.codigo AS departamento_codigo, "
        sql += "d.departamento_id, a.color_txt "
        sql += "FROM calendario c INNER JOIN actividades a ON c.actividad_id=a.actividad_id "
        sql += "LEFT JOIN departamentos d ON c.departamento_id=d.departamento_id "
        sql += "WHERE c.calendario_id>0 "
        sql += sql_add

        sql += "ORDER BY a.actividad, c.fecha_actividad_ini, c.fecha_reserva "
        #print('sql: ', sql)

        retorno = []
        with connection.cursor() as cursor:
            cursor.execute(sql)
            rows = cursor.fetchall()

            # recorremos todos los dias del calendario
            semana_add = []

            for semana in calendario:
                for dia_semana in semana:
                    objeto_dia = {}
                    objeto_dia['posicion'] = dia_semana['posicion']
                    objeto_dia['dia'] = dia_semana['dia']
                    objeto_dia['nombre'] = dia_semana['nombre']
                    objeto_dia['existe'] = dia_semana['existe']

                    if objeto_dia['existe'] == 1:
                        #print('dia: ', objeto_dia['dia'])
                        # dia valido, vemos las actividades
                        para_dia = str(objeto_dia['dia'])
                        if len(para_dia) == 1:
                            para_dia = '0' + para_dia

                        fecha_dia = anio + '-' + mes + '-' + para_dia
                        lista_actividades = []
                        #print('fecha dia: ', fecha_dia)

                        for row in rows:
                            aux_fecha = get_date_to_db(fecha=row[1], formato_ori='yyyy-mm-dd HH:ii:ss', formato='yyyy-mm-dd HH:ii:ss')  # fecha actividad ini
                            div_aux = aux_fecha.split(' ')
                            fecha_calendario = div_aux[0]
                            hora_calendario = div_aux[1]
                            #print('hora calendario: ', hora_calendario)
                            # fecha fin calendario
                            aux_fecha = get_date_to_db(fecha=row[2], formato_ori='yyyy-mm-dd HH:ii:ss', formato='yyyy-mm-dd HH:ii:ss')  # fecha actividad ini
                            div_aux = aux_fecha.split(' ')
                            fecha_calendario_fin = div_aux[0]
                            hora_calendario_fin = div_aux[1]
                            #print('fecha calendario: ', fecha_calendario, ' ..fecha dia: ', fecha_dia)

                            if fecha_dia == fecha_calendario:
                                # actividad para el dia
                                actividad = {}
                                actividad['calendario_id'] = row[0]
                                actividad['hora_ini'] = hora_calendario[0:5]
                                actividad['hora_fin'] = hora_calendario_fin[0:5]
                                actividad['fecha_reserva'] = row[3]
                                actividad['user_perfil_id_reserva'] = row[4]
                                actividad['fecha_confirma'] = row[5]
                                actividad['user_perfil_id_confirma'] = row[6]
                                actividad['fecha_anula'] = row[7]
                                actividad['user_perfil_id_anula'] = row[8]
                                actividad['motivo_anula'] = row[9]
                                actividad['detalle'] = row[10]
                                actividad['observacion'] = row[11]
                                actividad['status_id'] = row[12]
                                actividad['actividad'] = row[13]
                                actividad['actividad_codigo'] = row[14]
                                actividad['color_hex'] = row[15]
                                actividad['departamento'] = row[16]
                                actividad['departamento_codigo'] = row[17]
                                actividad['departamento_id'] = row[18]
                                actividad['color_txt'] = row[19]

                                # user id del departamento
                                user_id_dpto = 0
                                for us_perfil in users_perfiles_lista:
                                    if actividad['departamento'] == us_perfil.user_id.username:
                                        user_id_dpto = us_perfil.user_id.id
                                        break
                                actividad['user_id_dpto'] = user_id_dpto

                                #print('actividad: ', actividad)
                                lista_actividades.append(actividad)

                        objeto_dia['lista_actividades'] = lista_actividades
                        semana_add.append(objeto_dia)
                    else:
                        objeto_dia['lista_actividades'] = []
                        semana_add.append(objeto_dia)

                # termina el for de semana
                retorno.append(semana_add)
                semana_add = []
            # termina el for calendario
            # retorno.append(semana_add)

        # return calendario
        #print('retorno: ', retorno)
        return retorno

    def registrar_actividad(self, periodo, request, user):
        # armamos los datos
        try:
            hora_ini = validate_string('hora inicio', request.POST['hora_ini'])
            minuto_ini = validate_string('minutos inicio', request.POST['minuto_ini'])
            hora_fin = validate_string('hora fin', request.POST['hora_fin'])
            minuto_fin = validate_string('minutos fin', request.POST['minuto_fin'])
            actividad_id = validate_number_int('actividad', request.POST['actividad'])
            aux_dia = validate_number_int('dia', request.POST['dia'])
            #departamento_id = validate_number_int('departamento', request.POST['departamento'], len_zero='yes')
            # registro directo por un usuario que no es departamento
            departamento_id = 0
            detalle = validate_string('detalle', request.POST['detalle'], len_zero='yes')

            dia = str(aux_dia)
            if len(dia) == 1:
                dia = "0" + dia

            actividad = apps.get_model('calendario', 'Actividades').objects.get(pk=actividad_id)
            # if departamento_id > 0:
            #     departamento = apps.get_model('departamentos', 'Departamento').objects.get(pk=departamento_id)

            user_perfil = apps.get_model('permisos', 'UsersPerfiles').objects.get(user_id=user)

            fecha_inicio = periodo[0:4] + '-' + periodo[4:6] + '-' + dia + ' ' + hora_ini + ':' + minuto_ini + ':00'
            fecha_fin = periodo[0:4] + '-' + periodo[4:6] + '-' + dia + ' ' + hora_fin + ':' + minuto_fin + ':00'
            # verificamos que no exista actividad confirmada en este rango
            sql = f"SELECT COUNT(*) AS cant FROM calendario WHERE fecha_actividad_ini>='{fecha_inicio}' AND fecha_actividad_ini<'{fecha_fin}' AND actividad_id='{actividad_id}' AND status_id='{self.activo}' "
            cant = 0
            with connection.cursor() as cursor:
                cursor.execute(sql)
                row = cursor.fetchone()
                cant = row[0]
                if cant == 0:
                    sql = f"SELECT COUNT(*) AS cant FROM calendario WHERE fecha_actividad_fin>'{fecha_inicio}' AND fecha_actividad_fin<='{fecha_fin}' AND actividad_id='{actividad_id}' AND status_id='{self.activo}' "
                    with connection.cursor() as cursor2:
                        cursor2.execute(sql)
                        row2 = cursor2.fetchone()
                        cant = row2[0]

            if cant > 0:
                self.error_operation = "Ya existen actividades en este rango de fecha para la actividad : " + actividad.actividad
                return False

            # guardamos en la base de datos
            calendario_add = apps.get_model('calendario', 'Calendario').objects.create(
                fecha_actividad_ini=fecha_inicio, fecha_actividad_fin=fecha_fin, departamento_id=departamento_id,
                user_perfil_id_reserva=user_perfil.user_perfil_id, fecha_reserva='now', detalle=detalle,
                user_perfil_id_confirma=user_perfil.user_perfil_id, fecha_confirma='now',
                actividad_id=actividad, status_id=self.status_activo,
                created_at='now', updated_at='now'
            )
            calendario_add.save()

            self.error_operation = ''
            return True

        except Exception as ex:
            self.error_operation = 'Error de datos, ' + str(ex)
            return False

    def solicitar_actividad(self, periodo, request, user):
        # armamos los datos
        try:
            hora_ini = validate_string('hora inicio', request.POST['hora_ini'])
            minuto_ini = validate_string('minutos inicio', request.POST['minuto_ini'])
            hora_fin = validate_string('hora fin', request.POST['hora_fin'])
            minuto_fin = validate_string('minutos fin', request.POST['minuto_fin'])
            actividad_id = validate_number_int('actividad', request.POST['actividad'])
            aux_dia = validate_number_int('dia', request.POST['dia'])
            detalle = validate_string('detalle', request.POST['detalle'], len_zero='yes')

            user_perfil = apps.get_model('permisos', 'UsersPerfiles').objects.get(user_id=user)
            departamento = apps.get_model('departamentos', 'Departamentos').objects.get(departamento=user_perfil.user_id.username)
            departamento_id = departamento.departamento_id
            actividad = apps.get_model('calendario', 'Actividades').objects.get(pk=actividad_id)

            dia = str(aux_dia)
            if len(dia) == 1:
                dia = "0" + dia

            fecha_inicio = periodo[0:4] + '-' + periodo[4:6] + '-' + dia + ' ' + hora_ini + ':' + minuto_ini + ':00'
            fecha_fin = periodo[0:4] + '-' + periodo[4:6] + '-' + dia + ' ' + hora_fin + ':' + minuto_fin + ':00'
            # verificamos que no exista actividad confirmada en este rango
            sql = f"SELECT COUNT(*) AS cant FROM calendario WHERE fecha_actividad_ini>='{fecha_inicio}' AND fecha_actividad_ini<'{fecha_fin}' AND actividad_id='{actividad_id}' AND status_id='{self.activo}' "
            cant = 0
            with connection.cursor() as cursor:
                cursor.execute(sql)
                row = cursor.fetchone()
                cant = row[0]
                if cant == 0:
                    sql = f"SELECT COUNT(*) AS cant FROM calendario WHERE fecha_actividad_fin>'{fecha_inicio}' AND fecha_actividad_fin<='{fecha_fin}' AND actividad_id='{actividad_id}' AND status_id='{self.activo}' "
                    with connection.cursor() as cursor2:
                        cursor2.execute(sql)
                        row2 = cursor2.fetchone()
                        cant = row2[0]

            if cant > 0:
                self.error_operation = "Ya existen actividades en este rango de fecha para la actividad : " + actividad.actividad
                return False

            # guardamos en la base de datos
            calendario_add = apps.get_model('calendario', 'Calendario').objects.create(
                fecha_actividad_ini=fecha_inicio, fecha_actividad_fin=fecha_fin, departamento_id=departamento_id,
                user_perfil_id_reserva=user_perfil.user_perfil_id, fecha_reserva='now', detalle=detalle,
                actividad_id=actividad, status_id=self.status_inactivo,
                created_at='now', updated_at='now'
            )
            calendario_add.save()

            self.error_operation = ''
            return True

        except Exception as ex:
            self.error_operation = 'Error de datos, ' + str(ex)
            return False

    def confirmar_actividad(self, id, user):
        # armamos los datos
        try:
            calendario_id = validate_number_int('calendario id', id)
            calendario = apps.get_model('calendario', 'Calendario').objects.get(pk=calendario_id)
            fecha_inicio = get_date_to_db(fecha=calendario.fecha_actividad_ini, formato_ori='yyyy-mm-dd HH:ii:ss', formato='yyyy-mm-dd HH:ii:ss')
            fecha_fin = get_date_to_db(fecha=calendario.fecha_actividad_fin, formato_ori='yyyy-mm-dd HH:ii:ss', formato='yyyy-mm-dd HH:ii:ss')

            user_perfil = apps.get_model('permisos', 'UsersPerfiles').objects.get(user_id=user)

            # verificamos que no exista actividad confirmada en este rango
            sql = f"SELECT COUNT(*) AS cant FROM calendario WHERE fecha_actividad_ini>='{fecha_inicio}' AND fecha_actividad_ini<'{fecha_fin}' AND actividad_id='{calendario.actividad_id.actividad_id}' AND status_id='{self.activo}' "
            cant = 0
            with connection.cursor() as cursor:
                cursor.execute(sql)
                row = cursor.fetchone()
                cant = row[0]
                if cant == 0:
                    sql = f"SELECT COUNT(*) AS cant FROM calendario WHERE fecha_actividad_fin>'{fecha_inicio}' AND fecha_actividad_fin<='{fecha_fin}' AND actividad_id='{calendario.actividad_id.actividad_id}' AND status_id='{self.activo}' "
                    with connection.cursor() as cursor2:
                        cursor2.execute(sql)
                        row2 = cursor2.fetchone()
                        cant = row2[0]

            if cant > 0:
                self.error_operation = "Ya existen actividades en este rango de fecha para la actividad : " + calendario.actividad_id.actividad
                return False

            # actualizamos en la base de datos
            calendario.user_perfil_id_confirma = user_perfil.user_perfil_id
            calendario.fecha_confirma = 'now'
            calendario.updated_at = 'now'
            calendario.status_id = self.status_activo
            calendario.save()

            self.error_operation = ''
            return True

        except Exception as ex:
            self.error_operation = 'Error de datos, ' + str(ex)
            return False

    def anular_actividad(self, id, user):
        # armamos los datos
        try:
            calendario_id = validate_number_int('calendario id', id)
            calendario = apps.get_model('calendario', 'Calendario').objects.get(pk=calendario_id)
            fecha_inicio = get_date_to_db(fecha=calendario.fecha_actividad_ini, formato_ori='yyyy-mm-dd HH:ii:ss', formato='yyyy-mm-dd HH:ii:ss')
            fecha_fin = get_date_to_db(fecha=calendario.fecha_actividad_fin, formato_ori='yyyy-mm-dd HH:ii:ss', formato='yyyy-mm-dd HH:ii:ss')

            user_perfil = apps.get_model('permisos', 'UsersPerfiles').objects.get(user_id=user)
            #self.error_operation = 'asdfa'
            # return False

            # verificamos si es usuario departamento, solo puede eliminar sus actividades
            if user_perfil.perfil_id.perfil_id == settings.PERFIL_DEPARTAMENTO:
                departamento = apps.get_model('departamentos', 'Departamentos').objects.get(pk=calendario.departamento_id)
                if user_perfil.user_id.username != departamento.departamento:
                    self.error_operation = 'Solo puede eliminar sus actividades'
                    return False

            # actualizamos en la base de datos
            calendario.user_perfil_id_anula = user_perfil.user_perfil_id
            calendario.fecha_anula = 'now'
            calendario.deleted_at = 'now'
            calendario.status_id = self.status_anulado
            calendario.motivo_anula = ''
            calendario.save()

            self.error_operation = ''
            return True

        except Exception as ex:
            self.error_operation = 'Error de datos, ' + str(ex)
            return False


# Copyright (c) 2023, NVIDIA CORPORATION.  All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import argparse
import json
import os
import uuid

def read_json(filename):
    assert os.path.isfile(filename), f"{filename} does not exist!"

    with open(filename, "r") as f:
        return json.load(f)

def write_json(data, filename):
    with open(filename, "w") as f:
        json.dump(data, f, indent=4)

def main():
    parser = argparse.ArgumentParser()
    parser.add_argument("--job", type=str, default="cifar10_fedavg", help="Path to job config.")
    parser.add_argument("--poc", action="store_true", help="Whether admin uses POC mode.")
    parser.add_argument(
        "--train_split_root", type=str, default="/tmp/cifar10_splits", help="Location where to save data splits."
    )
    parser.add_argument(
        "--alpha",
        type=float,
        default=0.0,
        help="Value controls the degree of heterogeneity. "
        "Lower values of alpha means higher heterogeneity."
        "Values of <= 0. means no data sampling. "
        "Assumes central training.",
    )
    args = parser.parse_args()

    # update alpha and split data dir
    job_name = os.path.basename(args.job)
    client_config_filename = os.path.join(args.job, job_name, "config", "config_fed_client.json")
    server_config_filename = os.path.join(args.job, job_name, "config", "config_fed_server.json")
    meta_config_filename = os.path.join(args.job, "meta.json")

    if args.alpha > 0.0:
        client_config = read_json(client_config_filename)
        server_config = read_json(server_config_filename)
        meta_config = read_json(meta_config_filename)
        print(f"Set alpha to {args.alpha}")
        token = str(uuid.uuid4())
        job_name = f"{job_name}_alpha{args.alpha}"
        server_config["alpha"] = args.alpha
        meta_config["name"] = job_name
        split_dir = os.path.join(args.train_split_root, f"{job_name}_{token}")
        print(f"Set train split root to {split_dir}")
        server_config["TRAIN_SPLIT_ROOT"] = split_dir
        client_config["TRAIN_SPLIT_ROOT"] = split_dir
        write_json(client_config, client_config_filename)
        write_json(server_config, server_config_filename)
        write_json(meta_config, meta_config_filename)
        print(f"Updated {meta_config_filename} to alpha={args.alpha}")
    else:
        print("Assuming centralized training.")

if __name__ == "__main__":
    main()


import torch
import torch.nn as nn

class Discriminator(nn.Module):

    def __init__(self):
        super(Discriminator, self).__init__()
        channels = [3, 64, 256, 512]

        self.leaky_relu = nn.LeakyReLU(0.2)
        self.sigmoid = nn.Sigmoid()
        self.conv1 = nn.Conv2d(channels[0], channels[1], kernel_size= 3, padding= 1)
        self.pool1 = nn.MaxPool2d((4, 4), (4, 4))
        self.conv2 = nn.Conv2d(channels[1], channels[2], kernel_size= 3, padding= 1)
        self.pool2 = nn.MaxPool2d((4, 4), (4, 4))
        self.conv3 = nn.Conv2d(channels[2], channels[3], kernel_size= 3, padding= 1)
        self.pool3 = nn.MaxPool2d((2, 2), (2, 2))

        self.fc1 = nn.Linear(channels[-1] * 2 * 2, 16)
        self.fc2 = nn.Linear(16, 1)

    def name(self):
        return 'd_01'

    def forward(self, x):
        x = self.leaky_relu(self.conv1(x))
        x = self.pool1(x)
        x = self.leaky_relu(self.conv2(x))
        x = self.pool2(x)
        x = self.leaky_relu(self.conv3(x))
        x = self.pool3(x)
        x = x.view(x.size(0), -1)
        x = self.leaky_relu(self.fc1(x))
        x = self.sigmoid(self.fc2(x))
        return x

def parameter_number(model):
    return sum(p.numel() for p in model.parameters() if p.requires_grad)

def unit_test():
    imgs = torch.zeros(10, 3, 64, 64)
    model = Discriminator()
    out = model(imgs)

    print('Parameter number: ',parameter_number(model))
    print('Input size: ', imgs.size())
    print('Output size:', out.size())

if __name__ == '__main__':
    unit_test()


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

from keras.datasets import mnist
from keras.models import Sequential
from keras.layers import Dense, Dropout, Activation, BatchNormalization
from keras.optimizers import SGD, Adam, RMSprop
from keras.callbacks import LearningRateScheduler
from keras.utils import np_utils
import keras.backend as K

from bnn.binary_ops import binary_tanh as binary_tanh_op
from bnn.binary_layers import BinaryDense

class DropoutNoScale(Dropout):
    '''Keras Dropout does scale the input in training phase, which is undesirable here.
    '''
    def call(self, inputs, training=None):
        if 0. < self.rate < 1.:
            noise_shape = self._get_noise_shape(inputs)

            def dropped_inputs():
                return K.dropout(inputs, self.rate, noise_shape,
                                 seed=self.seed) * (1 - self.rate)
            return K.in_train_phase(dropped_inputs, inputs,
                                    training=training)
        return inputs

def binary_tanh(x):
    return binary_tanh_op(x)

batch_size = 100
nb_epoch = 25
nb_classes = 10

H = 'Glorot'
kernel_lr_multiplier = 'Glorot'

# network
num_unit = 240
num_hidden = 3
use_bias = False

# learning rate schedule
lr_start = 1e-3
lr_end = 1e-4
lr_decay = (lr_end / lr_start)**(1. / nb_epoch)

# BN
epsilon = 1e-6
momentum = 0.9

# dropout
drop_in = 0.2
drop_hidden = 0.3

model = Sequential()
model.add(DropoutNoScale(drop_in, input_shape=(183,), name='drop0'))
for i in range(num_hidden):
    model.add(BinaryDense(num_unit, H=H, kernel_lr_multiplier=kernel_lr_multiplier, use_bias=use_bias,
              name='dense{}'.format(i+1)))
    model.add(BatchNormalization(epsilon=epsilon, momentum=momentum, name='bn{}'.format(i+1)))
    model.add(Activation(binary_tanh, name='act{}'.format(i+1)))
    model.add(DropoutNoScale(drop_hidden, name='drop{}'.format(i+1)))
model.add(BinaryDense(1, H=H, kernel_lr_multiplier=kernel_lr_multiplier, use_bias=use_bias,
          name='dense'))
model.add(BatchNormalization(epsilon=epsilon, momentum=momentum, name='bn'))

opt = Adam(lr=lr_start)
#model.compile(loss='binary_crossentropy', optimizer=opt, metrics=['acc'])
model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])

lr_scheduler = LearningRateScheduler(lambda e: lr_start * lr_decay ** e)
from . import generate_numpys
print("merged ...")
X_train = generate_numpys.X_t
Y_train = generate_numpys.Y_t
X_test = generate_numpys.X_test
Y_test = generate_numpys.Y_test
'''
history = model.fit(X_train, Y_train,
                    batch_size=batch_size, nb_epoch=nb_epoch,
                    verbose=1, validation_data=(X_test, Y_test),
                    callbacks=[lr_scheduler])
'''
history = model.fit(X_train, Y_train,
                    batch_size=batch_size, nb_epoch=nb_epoch,
                    verbose=1, validation_data=(X_test, Y_test))
score = model.evaluate(X_test, Y_test, verbose=0)
import pickle
with open('forests_history.pkl', 'wb') as f:
    pickle.dump(history, f)
print('Test score:', score[0])
print('Test accuracy:', score[1])

y_pred = score = model.predict(X_test)

log_y = Y_test
log_predicted = y_pred

from sklearn.metrics import roc_curve
from sklearn.metrics import auc
import matplotlib.pyplot as plt
import numpy as np
print(history.history.keys())

'''
#log_y = np.array([1, 1, 0, 0])
#log_predicted =  np.array([0.1, 0.4, 0.35, 0.8])
fpr, tpr, thresholds = roc_curve(log_y, log_predicted, pos_label  = 1)
roc_auc = auc(log_y, log_predicted, reorder  = True)

# Plot ROC curve
#plt.plot(fpr, tpr, label='ROC curve (area = %0.3f)' % roc_auc)
plt.plot(fpr, tpr, label='BNN ROC curve')
plt.plot([0, 1], [0, 1], 'k--')  # random predictions curve
#plt.xlim([0.0, 1.0])
#plt.ylim([0.0, 1.0])
plt.xlabel('False Positive Rate or (1 - Specifity)')
plt.ylabel('True Positive Rate or (Sensitivity)')
plt.title('Receiver Operating Characteristic')
plt.legend(loc="lower right")
plt.savefig('foo.png')

def get_labels(path = 'labels.csv'):
    with open(path) as csv:
        content = csv.readlines()[0].lower()
        content  = content.replace('","', "TARA")
        content  = content.replace(',', " ")
        content  = content.replace('"', " ")
        content  = content.replace('\n', " ")
        content  = content.replace('TARA', " , ")
        content = content.split(",")
        return content

def get_indexes (term = 'shank'):
    labels = get_labels()
    return [b for b in range(len(labels)) if term in labels[b]]
'''


#!/usr/bin/env python3
# -*- coding: utf-8 -*-

# file: postprocess_prediction.py
# description:
# code for postprocessing model outputs for SQuAD.

import json
import math
import collections
import numpy as np

from transformers.tokenization_bert import BasicTokenizer

def _numpy_sigmoid(x):
    return 1/(1 + np.exp(-x))

def _get_best_indexes(logits, n_best_size):
    """Get the n-best logits from a list."""
    index_and_score = sorted(enumerate(logits), key=lambda x: x[1], reverse=True)
    best_indexes = []
    for i in range(len(index_and_score)):
        if i >= n_best_size:
            break
        best_indexes.append(index_and_score[i][0])
    return best_indexes

def _compute_softmax(scores):
    """Compute softmax probability over raw logits."""
    if not scores:
        return []

    max_score = None
    for score in scores:
        if max_score is None or score > max_score:
            max_score = score

    exp_scores = []
    total_sum = 0.0
    for score in scores:
        x = math.exp(score - max_score)
        exp_scores.append(x)
        total_sum += x

    probs = []
    for score in exp_scores:
        probs.append(score / total_sum)
    return probs

def compute_predictions_logits(
    all_examples,
    all_features,
    all_results,
    n_best_size,
    max_answer_length,
    do_lower_case,
    output_prediction_file,
    output_nbest_file,
    output_null_log_odds_file,
    verbose_logging,
    version_2_with_negative,
    null_score_diff_threshold,
    tokenizer,
    sigmoid=True
):
    """Write final predictions to the json file and log-odds of null if needed."""

    example_index_to_features = collections.defaultdict(list)
    for feature in all_features:
        example_index_to_features[feature.example_index].append(feature)

    unique_id_to_result = {}
    for result in all_results:
        unique_id_to_result[result['unique_id']] = result

    feature_lst = [tmp.unique_id for tmp in all_features]

    _PrelimPrediction = collections.namedtuple(  # pylint: disable=invalid-name
        "PrelimPrediction", ["feature_index", "start_index", "end_index", "start_logit", "end_logit"]
    )

    all_predictions = collections.OrderedDict()
    all_nbest_json = collections.OrderedDict()
    scores_diff_json = collections.OrderedDict()

    for (example_index, example) in enumerate(all_examples):
        features = example_index_to_features[example_index]

        prelim_predictions = []
        # keep track of the minimum score of null start+end of position 0
        score_null = 1000000  # large and positive
        min_null_feature_index = 0  # the paragraph slice with min null score
        null_start_logit = 0  # the start logit at the slice with min null score
        null_end_logit = 0  # the end logit at the slice with min null score
        for (feature_index, feature) in enumerate(features):
            if feature.unique_id in unique_id_to_result.keys():
                result = unique_id_to_result[feature.unique_id]
                if sigmoid:
                    result["start_logits"] = _numpy_sigmoid(result["start_logits"].to("cpu").numpy()).tolist()[0]
                    result["end_logits"] = _numpy_sigmoid(result["end_logits"].to("cpu").numpy()).tolist()[0]
                else:
                    result["start_logits"] = _compute_softmax(result["start_logits"].to("cpu").numpy().tolist()[0])
                    result["end_logits"] = _compute_softmax(result["end_logits"].to("cpu").numpy().tolist()[0])

                start_indexes = _get_best_indexes(result["start_logits"], n_best_size)
                end_indexes = _get_best_indexes(result["end_logits"], n_best_size)

                # if we could have irrelevant answers, get the min score of irrelevant
                if version_2_with_negative:
                    feature_null_score = result["start_logits"][0] + result["end_logits"][0]
                    if feature_null_score < score_null:
                        score_null = feature_null_score
                        min_null_feature_index = feature_index
                        null_start_logit = result["start_logits"][0]
                        null_end_logit = result["end_logits"][0]
                for start_index in start_indexes:
                    for end_index in end_indexes:
                        # We could hypothetically create invalid predictions, e.g., predict
                        # that the start of the span is in the question. We throw out all
                        # invalid predictions.
                        if start_index >= len(feature.tokens):
                            continue
                        if end_index >= len(feature.tokens):
                            continue
                        if start_index not in feature.token_to_orig_map:
                            continue
                        if end_index not in feature.token_to_orig_map:
                            continue
                        if not feature.token_is_max_context.get(start_index, False):
                            continue
                        if end_index < start_index:
                            continue
                        length = end_index - start_index + 1
                        if length > max_answer_length:
                            continue
                        prelim_predictions.append(
                            _PrelimPrediction(
                                feature_index=feature_index,
                                start_index=start_index,
                                end_index=end_index,
                                start_logit=result["start_logits"][start_index],
                                end_logit=result["end_logits"][end_index],
                            )
                        )
        if version_2_with_negative:
            prelim_predictions.append(
                _PrelimPrediction(
                    feature_index=min_null_feature_index,
                    start_index=0,
                    end_index=0,
                    start_logit=null_start_logit,
                    end_logit=null_end_logit,
                )
            )
        prelim_predictions = sorted(prelim_predictions, key=lambda x: (x.start_logit + x.end_logit), reverse=True)

        _NbestPrediction = collections.namedtuple(  # pylint: disable=invalid-name
            "NbestPrediction", ["text", "start_logit", "end_logit"]
        )

        seen_predictions = {}
        nbest = []
        for pred in prelim_predictions:
            if len(nbest) >= n_best_size:
                break
            feature = features[pred.feature_index]
            if pred.start_index > 0:  # this is a non-null prediction
                tok_tokens = feature.tokens[pred.start_index : (pred.end_index + 1)]
                orig_doc_start = feature.token_to_orig_map[pred.start_index]
                orig_doc_end = feature.token_to_orig_map[pred.end_index]
                orig_tokens = example.doc_tokens[orig_doc_start : (orig_doc_end + 1)]

                tok_text = tokenizer.convert_tokens_to_string(tok_tokens)

                # tok_text = " ".join(tok_tokens)
                #
                # # De-tokenize WordPieces that have been split off.
                # tok_text = tok_text.replace(" ##", "")
                # tok_text = tok_text.replace("##", "")

                # Clean whitespace
                tok_text = tok_text.strip()
                tok_text = " ".join(tok_text.split())
                orig_text = " ".join(orig_tokens)

                final_text = get_final_text(tok_text, orig_text, do_lower_case, verbose_logging)
                if final_text in seen_predictions:
                    continue

                seen_predictions[final_text] = True
            else:
                final_text = ""
                seen_predictions[final_text] = True

            nbest.append(_NbestPrediction(text=final_text, start_logit=pred.start_logit, end_logit=pred.end_logit))
        # if we didn't include the empty option in the n-best, include it
        if version_2_with_negative:
            if "" not in seen_predictions:
                nbest.append(_NbestPrediction(text="", start_logit=null_start_logit, end_logit=null_end_logit))

            # In very rare edge cases we could only have single null prediction.
            # So we just create a nonce prediction in this case to avoid failure.
            if len(nbest) == 1:
                nbest.insert(0, _NbestPrediction(text="empty", start_logit=0.0, end_logit=0.0))

        # In very rare edge cases we could have no valid predictions. So we
        # just create a nonce prediction in this case to avoid failure.
        if not nbest:
            nbest.append(_NbestPrediction(text="empty", start_logit=0.0, end_logit=0.0))

        assert len(nbest) >= 1, "No valid predictions"

        total_scores = []
        best_non_null_entry = None
        for entry in nbest:
            total_scores.append(entry.start_logit + entry.end_logit)
            if not best_non_null_entry:
                if entry.text:
                    best_non_null_entry = entry

        probs = _compute_softmax(total_scores)

        nbest_json = []
        for (i, entry) in enumerate(nbest):
            output = collections.OrderedDict()
            output["text"] = entry.text
            output["probability"] = probs[i]
            output["start_logit"] = entry.start_logit
            output["end_logit"] = entry.end_logit
            nbest_json.append(output)

        assert len(nbest_json) >= 1, "No valid predictions"

        if not version_2_with_negative:
            all_predictions[example.qas_id] = nbest_json[0]["text"]
        else:
            # predict "" iff the null score - the score of best non-null > threshold
            score_diff = score_null - best_non_null_entry.start_logit - (best_non_null_entry.end_logit)
            scores_diff_json[example.qas_id] = score_diff
            if score_diff > null_score_diff_threshold:
                all_predictions[example.qas_id] = ""
            else:
                all_predictions[example.qas_id] = best_non_null_entry.text
        all_nbest_json[example.qas_id] = nbest_json

    if output_prediction_file:
        with open(output_prediction_file, "w") as writer:
            writer.write(json.dumps(all_predictions, indent=4) + "\n")

    if output_nbest_file:
        with open(output_nbest_file, "w") as writer:
            writer.write(json.dumps(all_nbest_json, indent=4) + "\n")

    if output_null_log_odds_file and version_2_with_negative:
        with open(output_null_log_odds_file, "w") as writer:
            writer.write(json.dumps(scores_diff_json, indent=4) + "\n")

    return all_predictions

def get_final_text(pred_text, orig_text, do_lower_case, verbose_logging=False):
    """Project the tokenized prediction back to the original text."""

    # When we created the data, we kept track of the alignment between original
    # (whitespace tokenized) tokens and our WordPiece tokenized tokens. So
    # now `orig_text` contains the span of our original text corresponding to the
    # span that we predicted.
    #
    # However, `orig_text` may contain extra characters that we don't want in
    # our prediction.
    #
    # For example, let's say:
    #   pred_text = steve smith
    #   orig_text = Steve Smith's
    #
    # We don't want to return `orig_text` because it contains the extra "'s".
    #
    # We don't want to return `pred_text` because it's already been normalized
    # (the SQuAD eval script also does punctuation stripping/lower casing but
    # our tokenizer does additional normalization like stripping accent
    # characters).
    #
    # What we really want to return is "Steve Smith".
    #
    # Therefore, we have to apply a semi-complicated alignment heuristic between
    # `pred_text` and `orig_text` to get a character-to-character alignment. This
    # can fail in certain cases in which case we just return `orig_text`.

    def _strip_spaces(text):
        ns_chars = []
        ns_to_s_map = collections.OrderedDict()
        for (i, c) in enumerate(text):
            if c == " ":
                continue
            ns_to_s_map[len(ns_chars)] = i
            ns_chars.append(c)
        ns_text = "".join(ns_chars)
        return (ns_text, ns_to_s_map)

    # We first tokenize `orig_text`, strip whitespace from the result
    # and `pred_text`, and check if they are the same length. If they are
    # NOT the same length, the heuristic has failed. If they are the same
    # length, we assume the characters are one-to-one aligned.
    tokenizer = BasicTokenizer(do_lower_case=do_lower_case)

    tok_text = " ".join(tokenizer.tokenize(orig_text))

    start_position = tok_text.find(pred_text)
    if start_position == -1:
        return orig_text
    end_position = start_position + len(pred_text) - 1

    (orig_ns_text, orig_ns_to_s_map) = _strip_spaces(orig_text)
    (tok_ns_text, tok_ns_to_s_map) = _strip_spaces(tok_text)

    if len(orig_ns_text) != len(tok_ns_text):
        return orig_text

    # We then project the characters in `pred_text` back to `orig_text` using
    # the character-to-character alignment.
    tok_s_to_ns_map = {}
    for (i, tok_index) in tok_ns_to_s_map.items():
        tok_s_to_ns_map[tok_index] = i

    orig_start_position = None
    if start_position in tok_s_to_ns_map:
        ns_start_position = tok_s_to_ns_map[start_position]
        if ns_start_position in orig_ns_to_s_map:
            orig_start_position = orig_ns_to_s_map[ns_start_position]

    if orig_start_position is None:
        return orig_text

    orig_end_position = None
    if end_position in tok_s_to_ns_map:
        ns_end_position = tok_s_to_ns_map[end_position]
        if ns_end_position in orig_ns_to_s_map:
            orig_end_position = orig_ns_to_s_map[ns_end_position]

    if orig_end_position is None:
        return orig_text

    output_text = orig_text[orig_start_position : (orig_end_position + 1)]
    return output_text


import json
from utils import get_tfpath
from flask import Flask, render_template, request, redirect

app = Flask(__name__, template_folder=".")
app.config["SECRET_KEY"] = "dQw4w9WgXcQ"

_HOST = "127.0.0.1"
_PORT = "9982"

@app.route("/")
def index():
    global ujson
    return render_template("get_sanitized.html", ujson=ujson)

def save_json(fdata):
    global ujson
    for key, value in fdata.items():
        item = ujson.get(key)
        if all([not item.get("is_answered"), value == "1"]):
            value = "0"
        elif value == "-3":
            ujson.pop(key)
            continue

        ujson.get(key).update({"type": value})

    path = get_tfpath("s_")
    with open(path, "w") as fp:
        json.dump(ujson, fp, indent=4)
        print("[info] Saved sanitized json to", path)

@app.route("/save", methods=["POST"])
def save():
    global ujson
    save_json(request.form.to_dict())
    return redirect("/")

def _run_server(data):
    global ujson
    ujson = data
    print(
        "\033[35m",
        "[info] PRESS CTRL-C WHEN YOU ARE DONE WITH SANITIZATION AND HAVE SUBMITTED.",
        "\033[0m",
        sep="",
    )
    app.run(host=_HOST, port=_PORT, debug=False)

def _get_sjson():
    global ujson
    app.do_teardown_appcontext()
    return ujson

def sanitize(ujson):
    _run_server(ujson)
    input(
        "\n[input] Sanitize questions and submit. Press to start converting sanitized result to docx.. "
    )
    return _get_sjson()


from django.contrib import admin
from django.urls import path, include
from home import views
urlpatterns = [
    path('', views.home, name='home'),
    path('about', views.about, name='about'),
    path('projects', views.projects, name='projects'),
    path('contact', views.contact, name='contact'),
    # path('login', views.login, name='login'),
    path('register', views.register, name='register'),
]