from flask import Flask, jsonify
from apscheduler.schedulers.background import BackgroundScheduler

app = Flask(__name__)

#Sample data not acurate
cancer_stats = {
    'Total_infected': 1000,
    'Active_cases': 500,
    'Recovered': 400,
    'Deaths': 200,
    'Critical': 50,
    'Mortality_rate': 20,
    'deceased': 100,
    'Population': 1000000
}

def update_stats():
    cancer_stats['Total_infected'] +=10
    cancer_stats['Active_cases'] +=10
    cancer_stats['Recovered'] +=10
    cancer_stats['Deaths'] +=10
    cancer_stats['Critical'] +=10
    cancer_stats['Mortality_rate'] +=10
    cancer_stats['deceased'] +=10
    cancer_stats['Population'] +=10

def get_cancer_stats():
    return jsonify(cancer_stats)

if __name__ == '__main__':
    scheduler = BackgroundScheduler()
    scheduler.add_job(update_stats, 'interval', minutes=1)
    scheduler.start()
    print('Scheduler started')
    scheduler.print_jobs()
    app.run(debug=True)


import pickle
import streamlit as st

classifier_in=open("classifier.pkl","rb")
clf=pickle.load(classifier_in)
def predict_banknote(variance,skewness,kurtosis,entropy):
    pred=clf.predict([[variance,skewness,kurtosis,entropy]])
    if(pred[0]>0.5):
        pred="Its a fake note"
    else:
        pred="It's a real banknote"

    return pred

variance=st.number_input("Enter the variance")
skewness=st.number_input("Enter the skewness")
kurtosis=st.number_input("Enter the kurtosis")
entropy=st.number_input("Enter the entropy")
if(st.button("Predict")):
    result=predict_banknote(variance,skewness,kurtosis,entropy)
    st.success(result)


from astropy.io import fits
import numpy as np

hdulist=fits.open('/Users/dhk/work/cat/NGC_IC/VII_118.fits')
tb=hdulist[1].data
for x in range(0,len(tb)/1000+1):
	f=open("sha_quarry_batch_%d.txt" % (x),"w")
	f.write("COORD_SYSTEM: Equatorial\n")
	f.write("EQUINOX: J2000\n")
	f.write("NAME-RESOLVER: NED\n")
	for y in range(x*1000,(x+1)*1000):
		if y == len(tb) :
			break
		if tb[y][1]==' Gx':
			if tb[y][0][0]=='I':
				f.write('ic'+tb[y][0][1:].strip()+'\n')
			else:
				f.write('ngc'+tb[y][0].strip()+'\n')

	f.close()


from itertools import product
# from PyMiniSolvers import minisolvers
import os

def req1(n: int, N: int, disjunctions_list):
    i_range = range(n, N + n)
    for i in i_range:
        clauses = [(f"t_{i}_0_0_" ), (f"t_{i}_0_1_" ),
                   (f"t_{i}_1_0_" ), (f"-t_{i}_1_1_" )]
        disjunctions_list.extend(clauses)

def req2(n: int, N: int, disjunctions_list):
    i_range = range(n, n + N)
    k_range = range(2)
    j_range = range(N + n)
    for (i, k) in product(i_range, k_range):
        existence_cond_variables = list((f"c_{i}_{k}_{j}_" for j in range(i)))  # range(i)))
        disjunctions_list.append(existence_cond_variables)
        for j_1 in j_range:
            for j_2 in range(n, N + n):
                if j_2 < j_1:
                    disjunction_clause = [f"-c_{i}_{k}_{j_1}_", f"-c_{i}_{k}_{j_2}_"]
                    disjunctions_list.append(disjunction_clause)

def req2_(n: int, N: int, disjunctions_list):
    i_range = range(n, n + N)
    k_range = range(2)
    j_range = range(N + n)
    for (i, k) in product(i_range, k_range):
        existence_cond_variables = list((f"c_{i}_{k}_{j}_" for j in range(i)))  # range(i)))
        disjunctions_list.append(existence_cond_variables)
        for j_1 in range(i + 1, N + n):
            for j_2 in range(i + 1, N + n):
                if j_2 == j_1:
                    continue
                disjunction_clause = [f"-c_{i}_{k}_{j_1}_", f"-c_{i}_{k}_{j_2}_"]
                disjunctions_list.append(disjunction_clause)

def req3(n: int, N: int, output_size_m: int, disjunctions_list):
    i_range = range(n, n + N)
    j_range = range(output_size_m)
    for j in j_range:
        existence_cond = list(f"o_{i}_{j}_" for i in i_range)
        disjunctions_list.append(existence_cond)
        for i_1 in i_range:
            # for i_2 in range(i_1 + 1, n + N):
            for i_2 in i_range:
                if i_1 == i_2:
                    continue
                # if i_1 < i_2:
                disjunction_clause = [f"-o_{i_1}_{j}_", f"-o_{i_2}_{j}_"]
                disjunctions_list.append(disjunction_clause)

def req4(n: int, input_sets, disjunctions_list):
    i_range = range(n)
    t_range = range(2 ** n)
    assert len(input_sets) == 2 ** n
    for (i, t) in product(i_range, t_range):
        input_value = input_sets[t][i]
        sign = '' if input_value == 1 else '-'
        clause = (f"{sign}v_{i}_{t}_")
        disjunctions_list.append(clause)

def req5(n: int, N: int, disjunctions_list):
    i_range = range(n, N + n)
    t_range = range(2 ** n)
    bit_range = range(2)
    for (i, r, i_0, i_1) in product(i_range, t_range, bit_range, bit_range):
        for j_0 in range(0, i):
        # for j_0 in i_range:
            for j_1 in range(0, i):
                i_0_sign = '-' if i_0 == 1 else ''
                i_1_sign = '-' if i_1 == 1 else ''

                clause_1 = [f"-c_{i}_{0}_{j_0}_", f"-c_{i}_{1}_{j_1}_", f"{i_0_sign}v_{j_0}_{r}_",
                            f"{i_1_sign}v_{j_1}_{r}_", f"v_{i}_{r}_", f"-t_{i}_{i_0}_{i_1}_"]
                clause_2 = [f"-c_{i}_{0}_{j_0}_",
                            f"-c_{i}_{1}_{j_1}_",
                            f"{i_0_sign}v_{j_0}_{r}_",
                            f"{i_1_sign}v_{j_1}_{r}_",
                            f"-v_{i}_{r}_",
                            f"t_{i}_{i_0}_{i_1}_"]
                disjunctions_list.append(clause_1)
                disjunctions_list.append(clause_2)

def req6(n: int, N: int, output_size_m: int, values, disjunctions_list):
    i_range = range(n, N + n)
    r_range = range(2 ** n)
    k_range = range(output_size_m)
    for (i, r, k) in product(i_range, r_range, k_range):
        value = values[r][k]
        sign = '' if value == 0 else '-'
        clause = [f"-o_{i}_{k}_", f"{sign}v_{i}_{r}_"]
        disjunctions_list.append(clause)

vectorOfValue = "0111"
quantityOfElement = 2

import math
numOfVars = int(math.log2(len(vectorOfValue)))
if 2 ** numOfVars != len(vectorOfValue):
    raise ValueError("bad length")
print(numOfVars)
vectorOfValue = vectorOfValue.replace("1", "a").replace("0", "1").replace("a", "0")
dis_list = []
req1(quantityOfElement, numOfVars, dis_list)
string_clause = ""
string_clause += "Λ".join(dis_list)
dis_list = []
req2(numOfVars, quantityOfElement, dis_list)
string_clause +=  "Λ" + "Λ".join([ "V".join(dis) for dis in dis_list])
dis_list = []
req3(numOfVars, quantityOfElement, 1, dis_list)
string_clause +=  "Λ" +  "Λ".join([ "V".join(dis) for dis in dis_list])
dis_list = []
input_sets = list(product((0, 1), repeat=numOfVars))
req4(numOfVars, input_sets, dis_list)
string_clause +=  "Λ" + "Λ".join(dis_list)
dis_list = []
req5(numOfVars, quantityOfElement, dis_list)
string_clause +=  "Λ" +  "Λ".join([ "V".join(dis) for dis in dis_list])
dis_list = []
values = [(int(value),) for value in vectorOfValue]
req6(numOfVars, quantityOfElement, 1,values,dis_list)

string_clause +=  "Λ" +  "Λ".join([ "V".join(dis) for dis in dis_list])
string_clause += f"Λo_{numOfVars + quantityOfElement - 1}_0_"
final = string_clause
fclause = [ [element for element in dis.split("V")] for dis in string_clause.split("Λ")]
# print(fclause)
variables = set()
for dis in fclause:
    for element in dis:
        if element[0]=="-":
            variables.add(element[1:])
        else:
            variables.add(element)

variables = (list(variables))
map_index_to_item = {}
map_item_to_index = {}

for i, var in enumerate(variables):
    map_index_to_item[i+1] = var
    map_item_to_index[var] = i + 1
    final = final.replace(var, str(map_item_to_index[var]))

lens = len(string_clause.split("Λ"))
for_minisat = f"p cnf {len(map_index_to_item)} {lens} \n"
for dis in string_clause.split("Λ"):
    if "V" in dis:
        for elem in dis.split("V"):
            sign = (-1 if elem[0]=="-" else 1)
            for_minisat += str(sign * map_item_to_index[elem[1:] if elem[0]=="-" else elem]) + " "
    else:
        for_minisat += str((-1 if dis[0]=="-" else 1) * map_item_to_index[dis[1:] if dis[0]=="-" else dis]) + " "
    for_minisat+="0\n"
# print(for_minisat)
file_str = for_minisat
file = open("for_minisat", 'w')
file.write(file_str)
file.close()
minisat_solution = {}
def from_minisat(output_minisat):
    output_minisat = output_minisat.split(" ")[:-1]
    print(output_minisat)
    for item in output_minisat:
        if item[0] == "-":
            minisat_solution[map_index_to_item[int(item[1:])]] = False
        else:
            minisat_solution[map_index_to_item[int(item)]] = True
os.system("minisat for_minisat output")
file = open("output", 'r')

output_minisat= file.read().split("\n")[1]
file.close()
from_minisat(output_minisat)
# print(minisat_solution)
body_string = "\n"
print(minisat_solution)
for key in minisat_solution.keys():
    if minisat_solution[key]:
        if key[0] == "c":
            c = key
            print(c)
            c = c[2:-1]
            c = c.split("_")
            from_ = ("x"+c[2]) if int(c[2]) < numOfVars else ("element"+c[2])
            to_ = ("x"+c[0]) if int(c[0]) < numOfVars else ("element"+c[0])
            body_string = body_string + """ "{}" -> "{}";\n""".format(from_, to_)

        if key[0] == "o":
            o = key
            print(o)
            o = o[2:-1]
            o = o.split("_")
            o[0] = ("x"+o[0]) if int(o[0])< numOfVars else ("element"+o[0])
            body_string = body_string + """ "{}" -> "{}";\n""".format(o[0], "end")

# os.system("rm scheme.dot")
# os.system("rm scheme.dot.png")

file_name = "scheme.dot"
file_str = """digraph G {\n""" + body_string + """\n}"""
file = open(file_name, 'w')
file.write(file_str)
file.close()
os.system("dot -T png -O " + file_name)
exit()

S = minisolvers.MinisatSolver()
for i in range(len(map_index_to_item)):
    S.new_var()

for dis in final.split("Λ"):
    clause = [ int(elem) for elem in dis.split("V")]
    S.add_clause(clause)
print(S.solve())
solution = (list(S.get_model()))
print(solution)


# -*- coding: utf-8 -*-
import requests
import json
import csv
import time
import re
from CrawlClient import Crawler
from lxml import etree
class ZOJCrawler(Crawler.Crawler):
    def __init__(self, max_try_cnt, url = 'http://acm.zju.edu.cn/onlinejudge'):
        self.try_cnt = 0
        self.max_try_cnt = max_try_cnt
        self.url = url
        self.rows = []
        self.try_second = 10

    def crawl(self):
        print("正在从 ZOJ抓取数据...")

        begin_time = time.time()
        #print("Vol 66 ".find("Vol 66 "))
        volume_cnt = 1
        while True:
            #Crawler.Crawler.progressbar(volume_cnt, 31)
            print("正在抓取ZOJ volume %d .." % volume_cnt)
            url = self.url + "/showProblems.do?contestId=1&pageNumber=%d" % volume_cnt
            while True:
                try:
                    u = requests.get(url, headers= None)
                    break
                except (requests.exceptions.RequestException, requests.exceptions.ConnectionError):
                    print("请求失败，%ds 后重试" % self.try_second)
                    time.sleep(self.try_second)
            # with open("column.html", "r", encoding="utf-8") as f:
            #     data = f.read()
            html = etree.HTML(u.text)
            vol_id = html.xpath('//*[@id="content_title"]/text()')[0]
            if vol_id.find("Vol %d" % volume_cnt) == -1:
                break
            cnt = 2
            while True:
                problem = html.xpath('//*[@id="content_body"]/form[1]/table/tr[%d]' % cnt)
                if not problem:
                    break
                #print(type(problem[0]))

                pro_id = problem[0].xpath("td[1]//font/text()")[0]
                pro_title = problem[0].xpath("td[2]//font/text()")[0]
                try:
                    ac_submission = problem[0].xpath("td[3]//a[1]/text()")[0]
                    all_submission = problem[0].xpath("td[3]//a[2]/text()")[0]
                except IndexError:
                    all_submission = ac_submission
                    ac_submission = 0
                item = []
                item.append("ZOJ")
                item.append(pro_id)
                item.append(pro_title)
                item.append("")
                item.append("")
                item.append(ac_submission)
                item.append(all_submission)
                self.rows.append(item)
                #print(pro_id, pro_title)
                cnt = cnt + 1
            volume_cnt = volume_cnt + 1
        end_time = time.time()

        print("抓取完成，耗时" ,time.strftime("%M:%S", time.localtime(end_time - begin_time)))

        return True

    def save(self, filename):
        headers = ["OJ", "Problem Number", "Problem Title", "AC Users", "Try Users", "AC Submission",
                   "All Submission"]
        with open(filename, "wt", encoding="GBK") as f:
            f_csv = csv.writer(f, lineterminator='\n')
            f_csv.writerow(headers)
            f_csv.writerows(self.rows)


from secrets import choice
from asyncio import sleep

import discord
from discord.ext import tasks, commands

from extras import constants
from utils.audio import YoutubeHelper, YTDLSource
from utils.docker import DockerLogger
from utils import decorators

class TiozaoZap(commands.Cog):
    '''
    TiozaoZap Cogs
    '''

    def __init__(self, client):
        self.client = client
        self.logger = DockerLogger(lvl=DockerLogger.INFO, prefix='TiozaoZap')

    async def _play_from_url(self, ctx, video_url, send_message=False):
        '''
        Plays the zap audio.
        '''

        voice_client = discord.utils.get(self.client.voice_clients, guild=ctx.guild)

        async with ctx.typing():
            player = await YTDLSource.from_url(video_url, loop=self.client.loop)
            voice_client.play(
                player,
                after=lambda e: print(f'Player error: %{e}') if e else None
            )

        if send_message:
            await ctx.message.channel.send(f'Se liga nesse audio... {player.title}')

    @commands.Cog.listener()
    @commands.guild_only()
    async def on_message(self, message):
        '''
        When any member sends a message inside a guild text-channel.
        '''
        # Cancels the request if the sender was a bot.
        if message.author.bot:
            return

        # bozo xingo
        if any(word in message.content.lower() for word in constants.BOZO_XINGO_TRIGGERS):
            choice(constants.RESPOSTA_XINGO)
            await message.channel.send(choice(constants.RESPOSTA_XINGO))

    @commands.command(name='audio_do_zap', aliases=['zap', 'audio', 'audio_zap'])
    @decorators.in_voice_chat_only
    @commands.guild_only()
    async def audio_do_zap(self, ctx):
        '''
        Plays a video of selection 'audios do zap' to the users channel.
        '''

        voice_channel = ctx.message.author.voice.channel

        # Só tenta conectar se não está conectado, depois reseta
        voice_client = discord.utils.get(self.client.voice_clients, guild=ctx.guild)
        if not voice_client:
            await voice_channel.connect()
            voice_client = discord.utils.get(self.client.voice_clients, guild=ctx.guild)

        await self._play_from_url(
            ctx,
            video_url=choice(YoutubeHelper.get_urls_list()),
            send_message=True
        )

        self.logger.log(
            f'{ctx.guild.id} - {ctx.message.author.id} requested ZAP_AUDIO',
            lvl=self.logger.INFO
        )

        # Disconnects after 5 seconds of audio ending
        while voice_client.is_playing():
            await sleep(5)

        await voice_client.disconnect()

    @commands.command(name='sus_sound_effect', aliases=['sus'])
    @decorators.in_voice_chat_only
    @commands.guild_only()
    async def play_sus_sound(self, ctx):
        '''
        Plays the "sus" sound effect from amongus.
        '''

        voice_channel = ctx.message.author.voice.channel

        # Só tenta conectar se não está conectado, depois reseta
        voice_client = discord.utils.get(self.client.voice_clients, guild=ctx.guild)
        if not voice_client:
            await voice_channel.connect()
            voice_client = discord.utils.get(self.client.voice_clients, guild=ctx.guild)

        await self._play_from_url(
            ctx,
            video_url=constants.SUS_VIDEO_URL,
            send_message=False
        )

        self.logger.log(
            f'{ctx.guild.id} - {ctx.message.author.id} requested ZAP_AUDIO',
            lvl=self.logger.INFO
        )

        # Disconnects after 5 seconds of audio ending
        while voice_client.is_playing():
            await sleep(5)

        await voice_client.disconnect()

def setup(client):
    '''
    Cog setup.
    '''
    client.add_cog(TiozaoZap(client))


import math

def area(r):
    """Area of a circle with radius 'r'"""
    return math.pi * (r**2)

radii = [2, 5, 7.1, 0.3, 10]

# Method 1: Direct method

areas = []
for r in radii:
    a = area(r)
    areas.append(a)

print(areas)

# Method 2: Use 'map' functions
print(list(map(area, radii)))

print("===========")

temps = [("Berlin", 29), ("Cairo", 36), ("Buenos Aires", 19),
        ("Los Angeles", 26), ("Tokyo", 27),
        ("New York", 28), ("London", 22), ("Beiking", 32)]

c_to_f = lambda data: (data[0], (9/5)*data[1] + 32)

print(list(map(c_to_f, temps)))

print("===========")

import statistics

data = [1.3, 2.7, 0.8, 4.1, 4.3, -0.1]
avg = statistics.mean(data)
print(avg)

print(list(filter(lambda x: x > avg, data)))

print("===========")

countries = ["", "Argentina", "Brazil", "Chile",
            "", "Colombia", "", "Ecuador", "", "",
            "Venezuela"]

print(list(filter(None, countries)))

print("===========")

from functools import reduce
# Multiply all numbers in a list
data = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29]

multi = lambda x, y: x * y
print(reduce(multi, data))


# Licensed under a 3-clause BSD style license - see LICENSE.rst
"""``stsynphot`` configurable items.

The default configuration heavily depends on STScI TRDS structure
but it can be easily re-configured as the user wishes via
`astropy.config`.

``PYSYN_CDBS`` must be a defined system environment variable for
directories to be configured properly. It also overwrites
``synphot`` configurable items.

"""
# STDLIB
import os

# THIRD-PARTY
import numpy as np
from astropy import log
from astropy.config import ConfigNamespace, ConfigItem

# SYNPHOT
from synphot.config import Conf as synconf
from synphot.utils import generate_wavelengths

__all__ = ['conf', 'getref', 'showref', 'overwrite_synphot_config']

class Conf(ConfigNamespace):
    """Configuration parameters."""

    # Set up default wavelength
    _wave, _wave_str = generate_wavelengths(
        minwave=500, maxwave=26000, num=10000, delta=None, log=True,
        wave_unit='angstrom')

    # Root directory
    rootdir = ConfigItem(
        os.environ.get('PYSYN_CDBS', '/grp/redcat/trds'),
        'TRDS data root directory')

    # Graph, optical component, and thermal component tables
    graphtable = ConfigItem('mtab$*_tmg.fits', 'Graph table')
    comptable = ConfigItem('mtab$*_tmc.fits', 'Component table')
    thermtable = ConfigItem('mtab$*_tmt.fits', 'Thermal table')

    # Default wavelength in Angstrom and its description
    waveset_array = ConfigItem(
        _wave.value.tolist(),
        'Default wavelength set in Angstrom', 'float_list')
    waveset = ConfigItem(_wave_str, 'Default wavelength set description')

    # Telescope primary mirror collecting area in cm^2
    area = ConfigItem(45238.93416, 'Telescope collecting area in cm^2')

    # Common filter name
    clear_filter = ConfigItem('clear', 'Name for a clear filter')

    # Wavelength catalog file
    wavecatfile = ConfigItem(
        'synphot$wavecats/wavecat.dat', 'Wavelength catalog file')

    # Detector parameters file
    detectorfile = ConfigItem(
        'synphot$detectors.dat', 'Detector parameters file')

    # IRAF shortcuts file for stsynphot.stio.irafconvert()
    irafshortcutfile = ConfigItem(
        'synphot$irafshortcuts.txt',
        'col1=shortcut_name col2=relpath_to_rootdir, has header.')

    # Clean up
    del _wave
    del _wave_str

def _get_synphot_cfgitems():
    """Iterator for ``synphot`` configuration items."""
    for c in synconf.__dict__.values():
        if isinstance(c, ConfigItem):
            yield c

def overwrite_synphot_config(root):
    """Silently overwrite ``synphot`` configurable items to point to
    given root directory.

    Parameters
    ----------
    root : str
        Root directory name.

    """
    subdir_keys = ['calspec', 'extinction', 'nonhst']

    # Need this for Windows support
    if root.startswith(('http', 'ftp')):
        sep = '/'
    else:
        sep = os.sep  # Can be / or \

    for cfgitem in _get_synphot_cfgitems():
        path, fname = os.path.split(cfgitem())

        i = np.where(list(map(path.__contains__, subdir_keys)))[0]
        if len(i) == 0:
            continue

        subdir = subdir_keys[i[0]]

        if subdir == 'nonhst':
            cfgval = sep.join([root, 'comp', subdir, fname])
        else:
            cfgval = sep.join([root, subdir, fname])

        cfgitem.set(cfgval)

conf = Conf()

# Override SYNPHOT configuration
overwrite_synphot_config(conf.rootdir)

def _get_ref_cfgitems():
    """Iterator for configuration items to be displayed."""
    from stsynphot.stio import get_latest_file, irafconvert

    for cfgitem, do_conv in (
            (Conf.graphtable, True),
            (Conf.comptable, True),
            (Conf.thermtable, True),
            (Conf.area, False),
            (Conf.waveset, False)):
        val = cfgitem()
        if do_conv:
            val = get_latest_file(irafconvert(val))
        yield cfgitem.name, val

def getref():
    """Return current values of select configurable items as a dictionary.

    Returns
    -------
    refdict : dict

    """
    return dict([x for x in _get_ref_cfgitems()])

def showref():  # pragma: no cover
    """Show the values of select configurable items."""
    info_str = '\n'
    for x in _get_ref_cfgitems():
        info_str += f'{x[0]:10s}: {x[1]}\n'
    log.info(info_str)


from flask import (
    Blueprint,
    flash,
    redirect,
    url_for,
    render_template,
    request,
    send_from_directory,
)

from filenavi import model
from .wrap import require_authentication
from .error import MalformedRequest, Unauthorized, NotAuthenticated, NotAccessible

INLINE_EXTENSIONS = ["txt", "pdf", "png", "jpg", "jpeg", "gif"]

bp = Blueprint("storage", __name__)

@bp.route("/<user:owner>/<visibility:visibility>/browse/")
@bp.route("/<user:owner>/<visibility:visibility>/browse/<path:path>")
def browse(owner, visibility, path=None):
    user = model.User.current()

    home = owner.home(visibility)
    path = (home / path) if path is not None else home
    target = model.File(path, owner, visibility)

    if visibility == model.Visibility.PRIVATE:
        if user is None:
            raise NotAuthenticated
        if not user.has_access_to(target):
            raise Unauthorized

    if not path.is_dir():
        as_attachment = True
        if any(str(target.path).lower().endswith(f".{e}") for e in INLINE_EXTENSIONS):
            as_attachment = False
        return send_from_directory(
            home, target.path.relative_to(home), as_attachment=as_attachment
        )

    if user is None or not user.has_access_to(target):
        raise Unauthorized

    if not request.path.endswith("/"):
        return redirect(f"{request.url}/")

    files = []
    try:
        for f in path.iterdir():
            f = f.relative_to(home)

            files.append(model.File(f, owner, visibility))
    except:
        raise NotAccessible

    parent = None
    if not home.samefile(path):
        parent = model.File(path.parent, owner, visibility)

    return render_template(
        "storage/browse.html",
        files=files,
        user=user,
        owner=owner,
        visibility=visibility,
        current=path.relative_to(home) if path != home else "",
        parent=parent,
    )

@bp.route("/<user:owner>/<visibility:visibility>/browse/", methods=["POST"])
@bp.route(
    "/<user:owner>/<visibility:visibility>/browse/<path:path>", methods=["POST"]
)
@require_authentication
def browse_handler(owner, visibility, path=None):
    user = model.User.current()

    if "files" not in request.files and "directory" not in request.form:
        raise MalformedRequest

    home = owner.home(visibility)
    path = (home / path) if path is not None else home
    target = model.File(path, owner, visibility)

    if not user.has_access_to(target):
        raise Unauthorized

    if "files" in request.files:
        uploads = request.files.getlist("files")
        for upload in uploads:
            if upload.filename == "":
                raise MalformedRequest
            upload.save(path / upload.filename)
    if "directory" in request.form:
        if request.form["directory"] == "":
            raise MalformedRequest
        directory = model.File(path / request.form["directory"], owner, visibility)
        directory.mkdir()
    return redirect(
        url_for(
            ".browse", visibility=visibility, path=path.relative_to(home), owner=owner
        )
    )

@bp.route("/<user:owner>/<visibility:visibility>/move/<path:path>")
@require_authentication
def move(owner, visibility, path=None):
    user = model.User.current()

    home = owner.home(visibility)
    path = (home / path) if path is not None else home

    target = model.File(path, owner, visibility)

    if not user.has_access_to(target):
        raise Unauthorized

    return render_template(
        "storage/move.html",
        file=target,
        user=user,
        owner=owner,
        visibility=visibility,
    )

@bp.route(
    "/<user:owner>/<visibility:visibility>/move/<path:path>",
    methods=["POST"],
)
@require_authentication
def move_handler(owner, visibility, path=None):
    user = model.User.current()

    home = owner.home(visibility)
    path = (home / path) if path is not None else home

    target = model.File(home / path, owner, visibility)

    if not user.has_access_to(target):
        raise Unauthorized

    rv = redirect(
        url_for(
            ".browse",
            visibility=visibility,
            path=path.relative_to(home).parents[0],
            owner=owner,
        )
    )

    if "path" not in request.form:
        raise MalformedRequest

    if not target.path.exists():
        flash("No such file or directory", "error")
        return rv

    try:
        force = "replace" in request.form
        target.move(home / request.form["move-path"], force=force)
    except ValueError:
        flash("Unable to move file", "error")
        return rv
    return rv

@bp.route("/<user:owner>/<visibility:visibility>/toggle/<path:path>")
@require_authentication
def toggle(owner, visibility, path=None):
    user = model.User.current()

    home = owner.home(visibility)
    path = (home / path) if path is not None else home

    target = model.File(path, owner, visibility)

    if not user.has_access_to(target):
        raise Unauthorized

    return render_template(
        "storage/toggle.html",
        file=target,
        user=user,
        owner=owner,
        visibility=visibility,
    )

@bp.route(
    "/<user:owner>/<visibility:visibility>/toggle/<path:path>",
    methods=["POST"],
)
@require_authentication
def toggle_handler(owner, visibility, path=None):
    user = model.User.current()

    home = owner.home(visibility)
    path = (home / path) if path is not None else home

    target = model.File(home / path, owner, visibility)

    if not user.has_access_to(target):
        raise Unauthorized

    rv = redirect(
        url_for(
            ".browse",
            visibility=visibility,
            path=path.relative_to(home).parents[0],
            owner=owner,
        )
    )

    if "path" not in request.form:
        raise MalformedRequest

    try:
        force = "replace" in request.form
        # TODO: Do not require a Path object
        from pathlib import Path

        target.toggle(Path(request.form["path"]), force=force)
    except ValueError:
        flash("Cannot toggle visibility", "error")
        return rv
    return rv

@bp.route("/<user:owner>/<visibility:visibility>/remove/<path:path>")
@require_authentication
def remove(owner, visibility, path=None):
    user = model.User.current()

    home = owner.home(visibility)
    path = (home / path) if path is not None else home

    target = model.File(path, owner, visibility)

    if not user.has_access_to(target):
        raise Unauthorized

    return render_template(
        "storage/remove.html",
        file=target,
        user=user,
        owner=owner,
        visibility=visibility,
    )

@bp.route(
    "/<user:owner>/<visibility:visibility>/remove/<path:path>",
    methods=["POST"],
)
@require_authentication
def remove_handler(owner, visibility, path=None):
    user = model.User.current()

    home = owner.home(visibility)
    path = (home / path) if path is not None else home

    target = model.File(home / path, owner, visibility)

    if not user.has_access_to(target):
        raise Unauthorized

    rv = redirect(
        url_for(
            ".browse",
            visibility=visibility,
            path=path.relative_to(home).parents[0],
            owner=owner,
        )
    )

    recursive = "recursive" in request.form
    try:
        target.remove(recursive=recursive)
    except ValueError:
        flash("No such file or directory", "error")
        return rv
    except OSError:
        flash("Cannot remove file or directory", "error")
        return rv
    return rv


import shutil
import tarfile
from collections.abc import Sequence
from pathlib import Path
from typing import Callable, Generic, TypedDict, TypeVar

import lightning.pytorch as pl
import torch
import torchaudio
from einops import rearrange
from torch import Tensor
from torch.hub import download_url_to_file
from torch.utils.data import DataLoader, Dataset
from tqdm.auto import tqdm

T = TypeVar('T')

class SequenceDataset(Dataset, Generic[T]):
    def __init__(self, entries: Sequence[T], transform: Callable[[T], T] | None = None) -> None:
        super().__init__()
        self.entries = entries
        self.transform = transform

    def __getitem__(self, index: int):
        ret = self.entries[index]
        if self.transform:
            ret = self.transform(ret)
        return ret

    def __len__(self):
        return len(self.entries)

class SignalTrainDatasetModuleParams(TypedDict):
    root: str
    batch_size: int
    training_segment_length: int
    validation_segment_length: int
    testing_segment_length: int

class SignalTrainDatasetModule(pl.LightningDataModule):
    sample_rate = 44_100

    hparams: SignalTrainDatasetModuleParams

    def __init__(
        self,
        root: str = './data/SignalTrain',
        batch_size: int = 32,
        training_segment_length: int = 2 ** 16,
        validation_segment_length: int = 2 ** 18,
        testing_segment_length: int = 2 ** 23,
    ) -> None:
        super().__init__()
        self.save_hyperparameters()

    def prepare_data(self) -> None:
        link = 'https://zenodo.org/record/3824876/files/SignalTrain_LA2A_Dataset_1.1.tgz'
        root = Path(self.hparams['root'])

        if (root / 'Train').exists():
            print('The SignalTrain dataset has been downloaded. Skipping ... ')
            return

        root.mkdir(511, True, True)

        d = root / 'temp.tgz'
        download_url_to_file(link, d)
        with tarfile.open(d, 'r') as tf:
            tf.extractall()
        d.unlink()
        shutil.move(root / 'SignalTrain_LA2A_Dataset_1.1' / 'Train', root)
        shutil.move(root / 'SignalTrain_LA2A_Dataset_1.1' / 'Test', root)
        shutil.move(root / 'SignalTrain_LA2A_Dataset_1.1' / 'Val', root)
        (root / 'SignalTrain_LA2A_Dataset_1.1').unlink()

    def train_dataloader(self):
        entries = self._read_data(
            Path(self.hparams['root']) / 'Train',
            self.hparams['training_segment_length'],
        )
        return DataLoader(
            entries,
            self.hparams['batch_size'],
            num_workers=8,
            shuffle=True,
            pin_memory=True,
            collate_fn=self._collate_fn
        )

    def val_dataloader(self):
        entries = self._read_data(
            Path(self.hparams['root']) / 'Val',
            self.hparams['validation_segment_length'],
        )
        return DataLoader(
            entries,
            self.hparams['batch_size'],
            num_workers=8,
            shuffle=False,
            pin_memory=True,
            collate_fn=self._collate_fn
        )

    def test_dataloader(self):
        entries = self._read_data(
            Path(self.hparams['root']) / 'Test',
            self.hparams['testing_segment_length'],
        )
        return DataLoader(
            entries,
            self.hparams['batch_size'],
            num_workers=8,
            shuffle=False,
            pin_memory=True,
            collate_fn=self._collate_fn
        )

    @staticmethod
    def _collate_fn(batch: list[tuple[Tensor, Tensor, Tensor]]):
        return (
            torch.stack([b[0] for b in batch]),
            torch.stack([b[1] for b in batch]),
            torch.stack([b[2] for b in batch]),
        )

    @staticmethod
    def _data_augmentation(entry: tuple[Tensor, Tensor, Tensor]):
        x, y, cond = entry
        if torch.rand([1]).item() < 0.5:
            x *= -1
            y *= -1
        return x, y, cond

    @classmethod
    def _slice_audio(cls, file: Path, segment_length: int) -> list[Tensor]:
        load_result: tuple[Tensor, int] = torchaudio.load(file)  # type: ignore
        dat, sr = load_result
        assert sr == cls.sample_rate
        dat.squeeze_(0)
        if dat.dim() != 1:
            raise ValueError(f'{file} is not a mono audio.')

        size, trill = divmod(dat.size(0), segment_length)
        if trill != 0:
            dat = dat[:-trill]
        dat = rearrange(dat, '(S L) -> S L', S=size)

        return [dat[i] for i in range(dat.size(0))]

    def _read_data(self, data_path: Path, segment_length: int):
        entries: list[tuple[Tensor, Tensor, Tensor]] = []
        all_files = sorted(data_path.glob('*.wav'))
        for file in tqdm(all_files, desc=f'Loading dataset from {data_path}.'):
            if file.name.startswith('input'):
                continue
            file_id = file.name[7:10]
            switch_value, peak_reduction_value = map(
                int, file.stem.split('__')[1:])
            input_file = file.with_name(f'input_{file_id}_.wav')

            input_datas = self._slice_audio(input_file, segment_length)
            output_datas = self._slice_audio(file, segment_length)
            for input_data, output_data in zip(input_datas, output_datas):
                assert input_data.size() == output_data.size()
                entries.append((
                    input_data,
                    output_data,
                    torch.tensor([
                        switch_value, peak_reduction_value
                    ], dtype=torch.float32)
                ))
        return SequenceDataset(entries, self._data_augmentation)


"""
Runs that functionality of the program, the flask app and the server that communicates with Walabot.
"""

from threading import Thread

from meeting_room import app
from FreeRoomsServer import FreeRoomsServer
from config import HOST, PORT

def main():
    """
    Start the server that communicates with Walabot and the flask app the communicated with Alexa.
    """
    try:
        server = FreeRoomsServer(HOST, PORT)
        free_rooms_server_thread = Thread(target=server.start)
        alexa_server_thread = Thread(target=app.run)

        free_rooms_server_thread.start()
        alexa_server_thread.start()

        free_rooms_server_thread.join()
        alexa_server_thread.join()

    except Exception:
        print("Unknown exception occurred!")
        raise

if __name__ == '__main__':
    main()


import torch.nn as nn

# define small classifier
class MlpClassifier(nn.Module):
    """ Simple classifier """

    def __init__(self, args, n_classes, pretrain_stage_config):
        super(MlpClassifier, self).__init__()
        self.input_size = int(args['pretrain_output_size'] * args['seq_length'])
        self.hidden_dim1 = 512
        self.hidden_dim2 = 256

        self.freeze = not args['finetuning']

        self.fc1 = nn.Linear(in_features=self.input_size, out_features=self.hidden_dim1)
        self.fc2 = nn.Linear(in_features=self.hidden_dim1, out_features=self.hidden_dim2)
        self.fc3 = nn.Linear(in_features=self.hidden_dim2, out_features=n_classes)

    def forward(self, src):
        batch_size = src.size(0)

        if self.freeze:
            # detach src
            src1 = src.data
        else:
            src1 = src

        src2 = src1.reshape(batch_size, -1)
        src3 = nn.functional.relu(self.fc1(src2))
        src4 = nn.functional.relu(self.fc2(src3))
        out = self.fc3(src4)

        return out


'''creating a form using flask to get username and password using html
and displaying success on submitting'''

from flask import Flask, redirect, render_template, request

app = Flask(__name__)

@app.route('/')
def home():
    return render_template("index.html")

@app.route("/success", methods = ['POST', "GET"])
def success():
    if request.method == 'POST':
        result = request.form
        uname = request.form['username']
        return render_template("success.html", result= result, username=uname)

if __name__ == '__main__':
    app.run(debug=True)


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Fri Apr 15 14:41:09 2022

@author: bas
"""
#https://instaloader.github.io/as-module.html

import instaloader
from datetime import datetime
from login import getMyUsername
import random
import pandas

def login(L, username, filename='login_session'):
    if not isinstance(L.test_login(),str):
        L.load_session_from_file(username, filename=filename)
    return L

def get_posts(L, myUsername, targetUsername, datetimeEarliest, datetimeLatest):
    L=login(L, myUsername)
    profile = instaloader.Profile.from_username(L.context, targetUsername)
    print('getting all posts...')
    posts = [post for post in profile.get_posts()]
    print('selecting posts...')
    posts_interval = [post for post in posts if (post.date_utc>datetimeEarliest and post.date_utc<datetimeLatest)]
    return posts_interval

if not 'L' in locals():
    L = instaloader.Instaloader()
if not 'posts' in locals():
    username = 'nyenrodebu'
    myUsername = getMyUsername()
    date_earliest = datetime(2020, 1, 1)
    date_latest = datetime(2022, 1, 1)
    posts = get_posts(L, myUsername, username, date_earliest, date_latest)

n = 78
posts_sampled = random.sample(posts, n)

posts_dict = {}
n_post = 0

for post in posts_sampled:
    n_post += 1
    print(f'post {n_post}/{n}')
    post_dict = {}
    post_dict['is_video'] = post.is_video
    post_dict['likes'] = post.likes
    post_dict['video_duration'] = post.video_duration
    post_dict['video_view_count'] = post.video_view_count
    post_dict['title'] = post.title
    post_dict['url'] = f'https://www.instagram.com/p/{post.shortcode}/'
    post_dict['mediacount'] = post.mediacount
    post_dict['caption'] = post.caption
    post_dict['date_utc'] = post.date_utc
    post_dict['comments'] = post.comments
    posts_dict[post.mediaid] = post_dict

df = pandas.DataFrame.from_dict(posts_dict, orient='index')
df.to_csv(f'output_files/username={username}_posts={n}.csv')


import random
from itertools import chain

import numpy as np
import pandas as pd
from cytoolz import itemmap, sliding_window, valmap
from skfusion import fusion

class DataFusionModel(object):
    def __init__(
        self, nodes, relations, init_type="random", random_state=666, n_jobs=1
    ):
        self.nodes = nodes
        self.relation_definitions = relations

        self.random_state = random_state
        self.n_jobs = n_jobs
        self.init_type = init_type

    def reconstruct(self, src, dst, idx=0, return_dataframe=True):
        relation = list(
            self.fuser.fusion_graph.get_relations(self.types[src], self.types[dst])
        )[idx]
        values = self.fuser.complete(relation)

        if return_dataframe:
            components = self.relation_definitions[(src, dst)][idx]
            return pd.DataFrame(
                values, index=components.index.values, columns=components.columns.values
            )

        return values

    def factor(self, type_name, return_dataframe=True):
        factor = self.fuser.factor(self.types[type_name])
        if not return_dataframe:
            return factor

        profile = pd.DataFrame(
            factor,
            index=self.indices[type_name],
            columns=[f"C{i:02}" for i in range(factor.shape[1])],
        )
        return profile

    def _construct_relationship(self, path, updated_factors):
        start_node = path[0]
        end_node = path[-1]

        computed_matrix = (
            self.fuser.factor(start_node)
            if not start_node.name in updated_factors
            else updated_factors[start_node.name]
        )
        print(
            type(start_node),
            start_node,
            start_node.name in updated_factors,
            computed_matrix.shape,
        )

        for src, dst in sliding_window(2, path):
            relation = list(self.fuser.fusion_graph.get_relations(src, dst))[0]
            print(relation)
            computed_matrix = np.dot(computed_matrix, self.fuser.backbone(relation))

        end_factor = (
            self.fuser.factor(end_node)
            if not end_node.name in updated_factors
            else updated_factors[end_node.name]
        )
        computed_matrix = np.dot(computed_matrix, end_factor.T)

        return computed_matrix

    def relation_profiles(self, src, dst, updated_factors=None, index=None):
        if updated_factors is None:
            updated_factors = {}
        if index is None:
            index = self.indices[src]

        paths = list(self.fuser.chain(self.types[src], self.types[dst]))

        relations = []
        for path in paths:
            rel = self._construct_relationship(path, updated_factors)
            profile = pd.DataFrame(rel, index=index, columns=self.indices[dst])
            relations.append(profile)

        return list(zip(paths, relations))

    def fit(self, method='factorization'):
        self.types = dict(
            zip(
                self.nodes.keys(),
                map(lambda x: fusion.ObjectType(*x), self.nodes.items()),
            )
        )
        print(self.types)

        self.relations = map(
            lambda x: map(
                lambda r: fusion.Relation(
                    r.values, self.types[x[0][0]], self.types[x[0][1]]
                ),
                x[1],
            ),
            self.relation_definitions.items(),
        )
        self.relations = list(chain(*self.relations))
        print(self.relations)

        self.indices = {}
        for (src, dst), dfs in self.relation_definitions.items():
            if not src in self.indices:
                self.indices[src] = list(dfs[0].index)
            if not dst in self.indices:
                self.indices[dst] = list(dfs[0].columns)

        random.seed(self.random_state)
        np.random.seed(self.random_state)

        self.fusion_graph = fusion.FusionGraph(self.relations)

        if method == 'factorization':
            fuser = fusion.Dfmf
        elif method == 'completion':
            fuser = fusion.Dfmc
        else:
            raise ValueError('method must be factorization or completion')

        self.fuser = fuser(
            init_type=self.init_type, random_state=self.random_state, n_jobs=self.n_jobs
        )

        self.fuser.fuse(self.fusion_graph)


from argparse import ArgumentParser
from ast import parse
import os

def handle_file(filename: str, blank: list[str]):
    with open(filename) as f:
        content = f.readlines()
    data = ['[']
    data.extend([f'"{x}",' for x in blank])
    data.extend(['\n'])
    skip = True
    for line in content:
        # line2 = line.replace(',', '').replace('"', '').strip()
        # print(f"{line2=}")
        # if line2 in blank:
            # continue
        if '[' in line or ']' in line:
            continue
        # print(f"{line=}")
        if line == '\n':
            skip = False
            continue
        if skip:
            continue
        data.append(line.strip())
    data.append(']\n')
    with open(filename, 'w') as f:
        f.write('\n'.join(data))

if __name__ == '__main__':
    parser = ArgumentParser(description='Update all templates based on the blank template')
    parser.add_argument(type=str, dest='filename', help='blank template')
    args = parser.parse_args()
    blank_file = args.filename
    with open(blank_file) as f:
        blank = f.read().replace('[', '').replace(']', '').replace('"', '').replace(',' , '').strip().split('\n')

    for _, _, files in os.walk('.'):
        for filename in files:
            if filename == blank_file:
                continue
            if filename.endswith('.txt'):
                print(filename)
                handle_file(filename, blank)


from django.contrib import admin
from .models import Review

# Register your models here.

class ReviewAdmin(admin.ModelAdmin):
    list_display = (
        'product',
        'user',
        'rating',
        'title',
        'description',
        'review_date',
    )
    ordering = ('product',)

admin.site.register(Review, ReviewAdmin)


import requests
import json
import sys
import os

class PR():

    def __init__(self, token, user, repo) -> None:
        self.token = token
        self.user = user
        self.repo = repo

    def raise_pr(self, title, head, base):
        url = "https://api.github.com/repos/"+ self.user +"/"+ self.repo+"/pulls"
        payload = json.dumps({
            "title": title,
            "head": head,
            "base": base
        })

        headers = {
            'Authorization': 'Bearer ' + self.token,
            'Content-Type': 'application/json'
        }

        response = requests.request("POST", url, headers=headers, data=payload)
        if response.status_code == 201:
            data = response.json()
            return data["number"]

        print(response.json())
        return -1

    def request_review(self, pr_number, reviewers):
        print("Requesting for reviewers for PR {0}".format(pr_number))
        url = "https://api.github.com/repos/" + self.user + "/" + self.repo + "/pulls/" + str(pr_number) + "/requested_reviewers"
        print(url)
        payload = {
            "reviewers": reviewers
        }
        print(payload)
        headers = {
            'Authorization': 'Bearer ' + self.token
        }

        response = requests.post(url, headers=headers, json=payload)

        if response.status_code == 201:
            return True

        return False

def workflow(token, user, repo, title, head, base, reviewers):
    pr = PR(token, user, repo)

    pr_number = pr.raise_pr(title, head, base)
    if pr_number == -1:
        print("PULL_REQUEST ERROR unable to raise a PR")

    review = pr.request_review(pr_number, reviewers)
    if not review:
        print("REVIEW_REQUEST ERROR unable to add reviewer to the PR")

if __name__ == '__main__':
    if len(sys.argv) < 8:
        print("Usage: python3 main.py <token> <user> <repo> <pull request title> <pull request head> <pull request base> <pull request reviewers>")
        sys.exit(1)

    workflow(sys.argv[1], sys.argv[2], sys.argv[3], sys.argv[4], sys.argv[5], sys.argv[6], sys.argv[7].split(","))


# Author: Joshua Jackson
# Date: 06/20/2020

# This file will contain the class which create Word2Vec file using gensim

from gensim.models import Word2Vec
from gensim.models.phrases import Phrases, Phraser
from datetime import datetime

# script to create word embeddings for Neural Network weight

class word2vec:
    def __init__(self, debug=False):
        try:
            #initiliaze init variable
            self.debug = debug

        except Exception as e:
            print(f"Something went wrong in __init__: {e}")

    #using a pre tokenized list create the word2vec traing data
    def create_bigram_embedding(self, tokens, emb_size=250, minCount=1, threshold_amount=1, workers=3, algo=0, window=5):
        try:

            #generate tri-gram using gensim
            phrases = Phrases(tokens, min_count=minCount, threshold=threshold_amount)
            #create bi-gram
            bigram = Phraser(phrases)

            #build model
            model = Word2Vec(bigram[tokens],\
                            size=emb_size,\
                            window=window,\
                            min_count=minCount,\
                            workers=workers,\
                            sg=algo)

            dateTimeObj = datetime.now()
            timestampStr = dateTimeObj.strftime("%d-%b-%Y")
            #save model to local directory as bin file

            #save both binary and non binary file
            model.save(f'bigram-model-{timestampStr}.bin', binary=True)
            model.save(f'bigram-model-{timestampStr}.txt', binary=False)

            return model
        except Exception as e:
            print(f"Something went wrong in create_training_data: {e}")


#from apiclient.discovery import build
from googleapiclient.discovery import build
from oauth2client.service_account import ServiceAccountCredentials

import httplib2
#from oauth2client import client, file, tools

import datetime
import pytz
import re
import configparser
# """
# timezone/DST correction:
# """
# def getTimeFromUTC() ):
# #get the difference between localtime and now. round to half hours
# #N.B. bad b/c daylight saving!
# secdiff=(datetime.datetime.utcnow() - datetime.datetime.now()).total_seconds()
# hourdiff=round(secdiff/60,2)
# return( datetime.timedelta(seconds=hourdiff*60) )
#DELTAFROMUTC = getTimeFromUTC()

def to_utc(dt, tzstr="America/New_York"):
    tz = pytz.timezone(tzstr)
    return(dt - tz.utcoffset(dt))
    # later when printing, will get the same time as we put in
    # utc=pytz.timezone('UTC')
    # return( tz.localize(dt).astimezone( utc ) )

# def to_tz(dt,tzstr="America/New_York"):
#  tz=pytz.timezone(tzstr)
#  utc=pytz.timezone('UTC')
#  return( utc.localize(dt).astimezone( tz ) )

def get_service(api_name, api_version, scope, key_file_location,
                service_account_email):

    credentials = ServiceAccountCredentials.from_p12_keyfile(
        service_account_email, key_file_location, scopes=scope)

    # UPMC MItM's our SSL connection: disable_ssl_certificate_validation=True
    # todo: add as config switch
    http = credentials.authorize(httplib2.Http(
        disable_ssl_certificate_validation=True))

    # Build the service object.
    service = build(api_name, api_version, http=http)

    return service

def g2time(dtstr):
    """
    google time string to datetime
    -> google gives back time in localtime
    """
    return(datetime.datetime.strptime(dtstr[0:18], '%Y-%m-%dT%H:%M:%S'))

def calInfo(e):
    """
    get calendar info from google api returned dict
    split summary into expected parts: study age sex subj_initials ra score
    """
    d = {
        'start': e['start']['dateTime'],
        'starttime': g2time(e['start']['dateTime']),
        'dur_hr': (g2time(e['end']['dateTime']) - g2time(e['start']['dateTime'])).seconds / 60 / 60,
        'creator': e['creator'].get('displayName'),
        'note': e.get('description'),
        'calid': e.get('id'),
        'summary': e.get('summary'),
        'htmlLink': e.get('htmlLink')
    }

    c = re.compile(
        r'(?P<study>[a-z/]+)[ -]*(?P<age>[0-9.]+) *yo(?P<sex>m|f) *\(?(?P<subjinit>[A-Z]{2,3})\)? *(?P<ra>[A-Z]{2,3})[ -]*(?P<score>[0-9.]+)',
        re.I)
    m = re.search(c, e['summary'])
    if m:
        md = m.groupdict()
        d = {**d, **md}

    return(d)

def time2g(dt, tzstr="America/New_York"):
    dtutc = to_utc(dt)
    return(dtutc.isoformat() + 'Z')

def time2gdict(dt,
               tzstr="America/New_York"): return({'dateTime': time2g(dt),
                                                  'timeZone': tzstr})

"""
a class containing a connection to our google calendar
"""

class LNCDcal():
    # authetenticate
    # ini: cal.ini
    # [Calendar]
    #  email = 'yyy@xxx.iam.gserviceaccount.com'
    #  p12   = '/path/to/creds.p12'
    #  calID = 'email@gmail.com'
    #  tz    = 'America/New_York'
    def __init__(self, ini):

        # Define the auth scopes to request.
        # -- read in from ini
        config = configparser.RawConfigParser()
        config.read(ini)

        service_account_email = config.get('Calendar', 'email')
        key_file_location = config.get('Calendar', 'p12')
        self.calendarId = config.get('Calendar', 'calID')
        self.backCalID = config.get('Calendar', 'backCalID', fallback=None)
        self.tzstr = config.get('Calendar', 'tz')

        scope = ['https://www.googleapis.com/auth/calendar']
        self.cal = get_service('calendar', 'v3', scope, key_file_location,
                               service_account_email)
        # might need to be updated after events are add
        self.events = self.cal.events()

    def find_in_range(self, dtmin, dtmax):
        if(isinstance(dtmin, datetime.datetime)):
            dtmin = time2g(dtmin)
        if(isinstance(dtmax, datetime.datetime)):
            dtmax = time2g(dtmax)

        events = self.events.list(
            calendarId=self.calendarId,
            singleEvents=True,
            timeMin=dtmin,
            timeMax=dtmax).execute()
        # use only events with datetime starts (remove full day events)
        items = [calInfo(i) for i in events['items']
                 if i['start'].get('dateTime')]
        # check time
        #dt.isoformat()[0:16] ==  items[0]['start']['dateTime'][0:16]
        return(items)

    def find(self, dt):
        delta = 10
        dtmin = dt - datetime.timedelta(minutes=delta)
        dtmax = dt + datetime.timedelta(minutes=delta)
        items = self.find_in_range(dtmin, dtmax)
        return(items)

    def upcoming(self, daydelta=5):
        dt = datetime.datetime.now()
        dtmin = time2g(dt, self.tzstr)
        dtmax = time2g(dt + datetime.timedelta(days=daydelta), self.tzstr)
        items = self.find_in_range(dtmin, dtmax)
        return(items)

    def insert_event(self, startdt, dur_h, summary, desc):
        endtime = startdt + datetime.timedelta(hours=dur_h)
        event = {
            'summary': summary,
            'description': desc,
            'start': time2gdict(startdt, self.tzstr),
            'end': time2gdict(endtime, self.tzstr)
        }
        eventres = self.cal.events().insert(
            calendarId=self.calendarId, body=event).execute()
        return(eventres)

    def delete_event(self, eventId):
        res = self.cal.events().delete(
            calendarId=self.calendarId,
            eventId=eventId).execute()
        return(res)

    def get_event(self, eventId):
        """ get an event: useful for testing successful delete"""
        res = self.cal.events().get(
            calendarId=self.calendarId,
            eventId=eventId).execute()
        return(res)

    def move_event(self, eventId):
        """move event to different calendar we have a 'backCalID' in config"""
        if self.backCalID is None:
            raise Exception("No backCalID in config, but trying to move")
        print("moving %s to %s" % (eventId, self.backCalID))
        res = self.cal.events().move(
                calendarId=self.calendarId,
                eventId=eventId,
                destination=self.backCalID).execute()
        return(res)


# Import packages
import cv2
import numpy as np
from PIL import Image
from pytesseract import pytesseract
from pytesseract import Output

if __name__ == "__main__":

    img = cv2.imread('shelf_for_rectangles.jpg')
    print(img.shape) # Print image shape
    cv2.imshow("original", img)

    # Cropping an image

    # cropped_image = img[35:75, 65:275] #1
    # cropped_image = img[35:75, 285:495] #2
    # cropped_image = img[35:75, 495:705] #3
    # cropped_image = img[35:75, 715:925] #4
    # cropped_image = img[175:215, 65:275] #LCD 5
    # cropped_image = img[175:215, 285:495]  # 6
    # cropped_image = img[175:215, 495:705] #7
    # cropped_image = img[175:215, 715:925] #8
    # cropped_image = img[310:345, 65:275] #9 battery
    # cropped_image = img[310:345, 285:495] #10
    # cropped_image = img[310:345, 495:705] #11
    # cropped_image = img[310:345, 715:925] #12
    # cropped_image = img[450:485, 153:300] #13 joystick
    # cropped_image = img[450:485, 395:620] #14
    # cropped_image = img[450:495, 670:910] #15
    # cropped_image = img[630:675, 420:590] #16 arduino

    #list with positions : pos (upper left corner) for all signs
    signs = [[35,65],]

    w = 210 #width sign
    h = 40 #hight sign

    # A text file is created and flushed
    file = open("signs_position_name.txt", "w+")
    file.write("")
    file.close()

    # Creating a copy of image
    im2 = img.copy()

    for pos in signs:
        y = pos[0]
        x = pos[1]
        mid_x = x + w/2
        mid_x = str(int(mid_x))
        mid_y = y + h/2
        mid_y = str(int(mid_y))

        cropped = im2[y:y + h, x:x + w]
        text = pytesseract.image_to_string(cropped)
        file = open("signs_position_name.txt", "a")
        if text == '':
            continue
        # Appending the text into file
        file.write(text + ' - ' + mid_x + ',' + mid_y + ',90')
        file.close()

    # Display cropped image
    cv2.imshow("cropped", cropped_image)

    # Save the cropped image
    cv2.imwrite("Cropped Image.jpg", cropped_image)

    cv2.waitKey(0)
    #cv2.destroyAllWindows()

    imgGray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)

    def tesseract():
        path_to_tesseract = r"C:\Program Files\Tesseract-OCR\tesseract.exe"
        image_path = 'Cropped Image.jpg'
        pytesseract.tesseract_cmd = path_to_tesseract
        text = pytesseract.image_to_string(Image.open(image_path))
        print(text[:-1])

    tesseract()


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

from __future__ import unicode_literals

"""
Support for django-reversion on models with translatable fields and django-cms
placeholder fields.
"""
from functools import partial

from django.db.models.signals import post_save

from cms.models.pluginmodel import CMSPlugin
from reversion.revisions import (
    default_revision_manager, revision_context_manager, VersionAdapter)

# We would like this to not depend on Parler, but still support if it is
# available.
try:
    from parler import cache
except:
    pass

def _add_to_context(obj, manager=None, context=None):
    if manager is None:
        manager = default_revision_manager

    if context is None:
        context = default_revision_manager._revision_context_manager

    adapter = manager.get_adapter(obj.__class__)
    version_data = adapter.get_version_data(obj)
    context.add_to_context(manager, obj, version_data)

def create_revision(obj, user=None, comment=None):
    with revision_context_manager.create_revision():
        if user:
            revision_context_manager.set_user(user)
        if comment:
            revision_context_manager.set_comment(comment)

        _add_to_context(obj)

        if hasattr(obj._meta, 'placeholder_field_names'):
            add_placeholders_to_revision(instance=obj)

def add_placeholders_to_revision(
        instance, revision_manager=None, rev_ctx=None):
    """
    Manually add plugins to the revision.

    This function is an updated version of
    http://github.com/divio/django-cms/blob/develop/cms/utils/helpers.py#L34
    but instead of working on pages, works on models with placeholder
    fields.
    """

    add_to_context = partial(
        _add_to_context,
        manager=revision_manager,
        context=rev_ctx,
    )

    # Add the placeholder to the revision
    for name in instance._meta.placeholder_field_names:
        add_to_context(getattr(instance, name))

    # Add all plugins to the revision
    ph_ids = [getattr(instance, '{0}_id'.format(name))
              for name in instance._meta.placeholder_field_names]

    for plugin in CMSPlugin.objects.filter(placeholder_id__in=ph_ids):
        plugin_instance, _ = plugin.get_plugin_instance()

        if plugin_instance:
            add_to_context(plugin_instance)
        add_to_context(plugin)

class TranslatableVersionAdapterMixin(object):
    revision_manager = None

    def __init__(self, model):
        super(TranslatableVersionAdapterMixin, self).__init__(model)

        # If the model is translated with django-parler, register the
        # translation model to be tracked as well, by following all placeholder
        # fields, if any.
        if hasattr(model, '_parler_meta'):
            root_model = model._parler_meta.root_model
            self.revision_manager.register(root_model)

            # Also add the translations to the models to follow.
            self.follow = list(self.follow) + [model._parler_meta.root_rel_name]

            # And make sure that when we revert them, we update the translations
            # cache (this is normally done in the translation `save_base`
            # method, but it is not called when reverting changes).
            post_save.connect(self._update_cache, sender=root_model)

    def _update_cache(self, sender, instance, raw, **kwargs):
        """Update the translations cache when restoring from a revision."""
        if raw:
            # Raw is set to true (only) when restoring from fixtures or,
            # django-reversion
            cache._cache_translation(instance)

class PlaceholderVersionAdapterMixin(object):
    follow_placeholders = True

    def __init__(self, model):
        super(PlaceholderVersionAdapterMixin, self).__init__(model)

        # Add cms placeholders the to the models to follow.
        placeholders = getattr(model._meta, 'placeholder_field_names', None)

        if self.follow_placeholders and placeholders:
            self.follow = list(self.follow) + placeholders
            post_save.connect(self._add_plugins_to_revision, sender=model)

    def _add_plugins_to_revision(self, sender, instance, **kwargs):
        rev_ctx = self.revision_manager._revision_context_manager

        if rev_ctx.is_active() and not rev_ctx.is_managing_manually():
            add_placeholders_to_revision(
                instance=instance,
                revision_manager=self.revision_manager,
                rev_ctx=rev_ctx,
            )

class ContentEnabledVersionAdapter(TranslatableVersionAdapterMixin,
                                   PlaceholderVersionAdapterMixin,
                                   VersionAdapter):
    pass

version_controlled_content = partial(default_revision_manager.register,
    adapter_cls=ContentEnabledVersionAdapter,
    revision_manager=default_revision_manager)


import xdg.BaseDirectory
import xdg.MenuEditor
import gtk
import gio
import uxm.adapters as adapters
from uxm.adapters import xdg_adapter

def lookup_menu_files(filename):
    return [f for f in xdg.BaseDirectory.load_config_paths('menus/' + filename)]

class MenuTreeModel(gtk.TreeStore):
    (
        COLUMN_HIDE,
        COLUMN_TYPE,
        COLUMN_ID,
        COLUMN_NAME,
        COLUMN_ICON,
        COLUMN_MENU_FILE,
        COLUMN_SYSTEM_VISIBLE,
        COLUMN_USER_VISIBLE,
        COLUMN_OBJECT
    ) = range(9)

    COLUMN_LIST_PATH = 9

    COLUMN_TYPES = (
        bool, int, str, str, gio.Icon, str, bool, bool, object
    )

    def __init__(self, menu_file):
        gtk.TreeStore.__init__(self, *self.COLUMN_TYPES)

        if not menu_file:
            menu_file = 'uxm-applications.menu'
        self.menu_editor = xdg.MenuEditor.MenuEditor(menu_file)
        root = xdg_adapter.XdgDirectoryAdapter(self.menu_editor.menu)
        self.__append_directory(root, None, False, menu_file)

        self.entries_list_iter = None

    def to_liststore(self):
        types = self.COLUMN_TYPES + (str,)
        store = gtk.ListStore(*types)
        columns = range(self.get_n_columns())

        def add(model, path, it):
            path = self.path_to_string(path)
            row = self.get_row(it, columns) + (path,)
            store.append(row)

        self.foreach(add)
        return store

    def path_to_string(self, path):
        if isinstance(path, str):
            return path
        return ':'.join((str(p) for p in path))

    def string_to_path(self, path):
        if isinstance(path, tuple):
            return path
        return tuple(path.split(':'))

    def get_row(self, iter, columns=None):
        if not columns:
            columns = range(self.get_n_columns())
        return self.get(iter, *columns)

    def update(self, data):
        t = data['type']
        # update menu
        if adapters.TYPE_ENTRY == t:
            self.menu_editor.editMenuEntry(
                data['object'].adaptee,
                name=data['name'],
                #genericname = data['name'],
                comment=data['comment'],
                command=data['command'],
                icon=data['icon'],
                terminal=data['terminal']
            )
        elif adapters.TYPE_DIRECTORY == t:
            self.menu_editor.editMenu(
                data['object'].adaptee,
                name=data['name'],
                #genericname = data['name'],
                comment=data['comment'],
                icon=data['icon'],
            )
        # update treemodel
        it = self.get_iter_from_string(data['_path'])
        obj = self.get_value(it, self.COLUMN_OBJECT)
        icon = gio.ThemedIcon(str(obj.get_icon()), True)
        self.set(
            it,
            self.COLUMN_ID, obj.get_filename(),
            self.COLUMN_NAME, obj.get_display_name(),
            self.COLUMN_ICON, icon
        )

    def create(self, data):
        t = data['type']
        parent_path = data['_parent']
        parent_iter = self.get_iter_from_string(parent_path)
        parent_entry = self.get_value(parent_iter, self.COLUMN_OBJECT)
        if adapters.TYPE_ENTRY == t:
            entry = self.menu_editor.createMenuEntry(
                parent_entry and parent_entry.adaptee or None,
                data['name'],
                #genericname = data['name'],
                comment=data['comment'],
                command=data['command'],
                icon=data['icon'],
                terminal=data['terminal']
            )
        elif adapters.TYPE_DIRECTORY == t:
            entry = self.menu_editor.createMenu(
                parent_entry and parent_entry.adaptee or None,
                data['name'],
                #genericname = data['name'],
                comment=data['comment'],
                icon=data['icon'],
            )
        obj = xdg_adapter.factory(entry)
        icon = gio.ThemedIcon(str(obj.get_icon()), True)
        #FIXME: this doesn't update the view ???
        self.append(
            parent_iter,
            (
                t == adapters.TYPE_DIRECTORY,
                obj.get_type(), obj.get_display_name(),
                obj.get_display_name(), icon,
                None, True, True,
                obj
            )
        )

    def __append_directory(self, directory, parent_iter, system, menu_file):
        if not directory:
            return
        iter = self.iter_children(parent_iter)
        while iter is not None:
            if self.get_value(iter, self.COLUMN_ID) == directory.get_name():
                break
            iter = self.iter_next(iter)

        if iter is None:
            icon = gio.ThemedIcon(str(directory.get_icon()), True)
            type = directory.get_type()
            row = (
                type == adapters.TYPE_ENTRY,
                type, directory.get_name(),
                directory.get_display_name(), icon,
                menu_file, False, False,
                directory
            )
            iter = self.append(parent_iter, row)

        if system:
            self.set_value(iter, self.COLUMN_SYSTEM_VISIBLE, True)
        else:
            self.set_value(iter, self.COLUMN_USER_VISIBLE, True)

        for entry in directory:
            current_type = entry.get_type()

            if current_type == adapters.TYPE_DIRECTORY:
                self.__append_directory(entry, iter, system, None)
            if current_type != adapters.TYPE_ENTRY:
                continue
            child_iter = self.iter_children(iter)
            while child_iter is not None:
                if self.get_value(child_iter, self.COLUMN_TYPE) == adapters.TYPE_ENTRY and (
                    self.get_value(child_iter, self.COLUMN_ID) == entry.get_filename()
                ):
                    break
                child_iter = self.iter_next(child_iter)

            if child_iter is None:
                icon = gio.ThemedIcon(str(entry.get_icon()), True)
                type = entry.get_type()
                row = (
                    type == adapters.TYPE_ENTRY,
                    type, entry.get_filename(),
                    entry.get_display_name(), icon,
                    None, False, False,
                    entry
                )
                child_iter = self.append(iter, row)

            if system:
                self.set_value(child_iter, self.COLUMN_SYSTEM_VISIBLE, entry.is_visible(), )
            else:
                self.set_value(child_iter, self.COLUMN_USER_VISIBLE, entry.is_visible(), )


#import ipdb
import logging

from typing import Optional, cast

from rest_framework import serializers
from rest_framework.exceptions import APIException, ErrorDetail, ValidationError

from rest_flex_fields.serializers import FlexFieldsSerializerMixin

from ..exception.unprocessable_entity import UnprocessableEntity

from ..models import *
from .name_and_uuid_serializer import NameAndUuidSerializer
from .embedded_id_validating_serializer_mixin import (
    EmbeddedIdValidatingSerializerMixin
)
from .group_setting_serializer_mixin import GroupSettingSerializerMixin
from .workflow_task_instance_serializer import WorkflowTaskInstanceSerializer
from .workflow_transition_serializer import WorkflowTransitionSerializer
from .workflow_execution_serializer import WorkflowExecutionSummarySerializer

logger = logging.getLogger(__name__)

COMMON_FIELDS = [
    'url', 'uuid', 'name', 'description', 'dashboard_url',
    'schedule', 'max_concurrency',
    'max_age_seconds', 'default_max_retries',
    'max_postponed_failure_count', 'max_postponed_missing_execution_count',
    'max_postponed_timeout_count',
    'min_missing_execution_delay_seconds',
    'postponed_failure_before_success_seconds',
    'postponed_missing_execution_before_start_seconds',
    'postponed_timeout_before_success_seconds',
    'scheduled_instance_count',
    'should_clear_failure_alerts_on_success',
    'should_clear_timeout_alerts_on_success',
    'latest_workflow_execution',
    'created_by_user', 'created_by_group',
    'run_environment',
    'enabled',
    'created_at', 'updated_at'
]

COMMON_READ_ONLY_FIELDS = [
    'url', 'uuid', 'dashboard_url',
    'latest_workflow_execution',
    'created_by_user', 'created_by_group',
    'created_at', 'updated_at'
]

class WorkflowSummarySerializer(GroupSettingSerializerMixin,
        serializers.HyperlinkedModelSerializer):
    """
    Selected properties of Workflows.
    """
    class Meta:
        model = Workflow
        fields = COMMON_FIELDS
        read_only_fields = COMMON_READ_ONLY_FIELDS

    latest_workflow_execution = WorkflowExecutionSummarySerializer(
            required=False, allow_null=True, read_only=True)
    url = serializers.HyperlinkedIdentityField(
            view_name='workflows-detail',
            lookup_field='uuid'
    )

class WorkflowSerializer(
        EmbeddedIdValidatingSerializerMixin,
        FlexFieldsSerializerMixin,
        WorkflowSummarySerializer):
    """
    Workflows are Tasks arranged in a directed graph. Configured Tasks
    are held by WorkflowTaskInstances, and WorkflowTransitions connect
    WorkflowTaskInstances together.
    """

    NEW_UUID_PREFIX = 'NEW_'

    class Meta:
        model = Workflow
        fields = COMMON_FIELDS + [
            'alert_methods', 'workflow_task_instances',
            'workflow_transitions',
        ]
        read_only_fields = COMMON_READ_ONLY_FIELDS

    workflow_task_instances = WorkflowTaskInstanceSerializer(
            many=True, read_only=True)

    workflow_transitions = WorkflowTransitionSerializer(many=True, read_only=True)

    alert_methods = NameAndUuidSerializer(include_name=True,
            view_name='alert_methods-detail', many=True, required=False)

    def to_internal_value(self, data):
        logger.info(f"wfs: to_internal value, data = {data}")

        workflow: Optional[Workflow] = cast(Workflow, self.instance) if self.instance else None

        data['description'] = data.get('description') or ''
        data['schedule'] = data.get('schedule') or ''
        data.pop('latest_workflow_execution', None)

        validated = super().to_internal_value(data)
        validated['workflow_task_instances'] = data.get('workflow_task_instances')
        validated['workflow_transitions'] = data.get('workflow_transitions')

        logger.debug(f"wfs: to_internal value, validated = {validated}")

        run_environment = validated.get('run_environment',
          workflow.run_environment if workflow else None)

        self.set_validated_alert_methods(data=data, validated=validated,
                run_environment=run_environment,
                allow_any_run_environment=(run_environment is None))

        return validated

    def create(self, validated_data):
        return self.create_or_update(None, validated_data)

    def update(self, instance, validated_data):
        return self.create_or_update(instance, validated_data)

    def create_or_update(self, instance, validated_data):
        defaults = validated_data
        alert_methods = defaults.pop('alert_methods', None)
        wtis = defaults.pop('workflow_task_instances', None)
        wts = defaults.pop('workflow_transitions', None)

        if instance:
            super().update(instance, defaults)
            workflow = instance
        else:
            defaults.pop('uuid', None)
            workflow = Workflow(**defaults)
            workflow.save()

        if alert_methods is not None:
            workflow.alert_methods.set(alert_methods)

        if wtis is None:
            return workflow

        old_wtis_by_uuid = {}
        old_wtis_by_name = {}
        for wti in workflow.workflow_task_instances.select_related(
                'task__run_environment').all():
            old_wtis_by_uuid[str(wti.uuid)] = wti
            old_wtis_by_name[wti.name] = wti

        new_wtis_by_uuid = {}
        new_wtis_by_name = {}

        for wti_dict in wtis:
            wti_uuid = wti_dict.get('uuid')
            if wti_uuid:
                new_wtis_by_uuid[wti_uuid] = wti_dict
            else:
                wti_name = wti_dict.get('name')

                if wti_name is None:
                    raise ValidationError({
                        'workflow_task_instances': [
                            ErrorDetail('Workflow Task Instance missing uuid and name', code='invalid')
                        ]
                    })

                new_wtis_by_name[wti_name] = wti_dict

        for wti_uuid, wti in old_wtis_by_uuid.items():
            if (wti_uuid not in new_wtis_by_uuid) and (wti.name not in new_wtis_by_name):
                wti.delete()

        logger.info(f"old_wtis_by_uuid = {old_wtis_by_uuid}")

        old_wts_by_uuid = {}
        for wt in workflow.workflow_transitions().all():
            old_wts_by_uuid[str(wt.uuid)] = wt

        for wti_dict in wtis:
            wti_uuid = wti_dict.pop('uuid', None)
            wti_name = wti_dict.get('name')

            existing_wti = None

            if wti_uuid:
                if not wti_uuid.startswith(self.NEW_UUID_PREFIX):
                    existing_wti = old_wtis_by_uuid.get(wti_uuid)
                    if existing_wti is None:
                        raise ValidationError({
                            'workflow_task_instances': [
                                ErrorDetail(f'Workflow Task Instance with UUID {wti_uuid} is not part of Workflow',
                                        code='invalid')
                            ]
                        })

                    logger.info(f"Found existing WTI with UUID {wti_uuid}")
            elif wti_name:
                existing_wti = old_wtis_by_name.get(wti_name)
                if existing_wti is None:
                    raise ValidationError({
                        'workflow_task_instances': [
                            ErrorDetail(f"Workflow Task Instance with name '{wti_name}' is not part of Workflow",
                                    code='invalid')
                        ]
                    })

            ser = WorkflowTaskInstanceSerializer(instance=existing_wti, data=wti_dict,
                    partial=True, context=self.context, workflow=workflow,
                    for_embedded_deserialization=True)

            try:
                if not ser.is_valid():
                    msg = f"Error saving Workflow Task Instance with UUID {wti_uuid or '[Empty]'}, name '{wti_name or '[Empty]'}'"
                    logger.error(msg)

                    # ser.errors results in ValueError: Too many values to unpack
                    #errors = [error_detail.string for error_detail in ser.errors]

                    raise serializers.ValidationError({
                        'workflow_task_instances': [msg]
                    })
            except serializers.ValidationError as ve:
                logger.exception('workflow serializer validation error')
                raise serializers.ValidationError({
                    'workflow_task_instances': [str(ve)]
                }) from ve
            except UnprocessableEntity as ue:
                raise UnprocessableEntity({
                    'workflow_task_instances': [str(ue)]
                }) from ue
            except APIException as api_ex:
                raise APIException({
                    'workflow_task_instances': [str(api_ex)]
                }) from api_ex

            saved_wti = ser.save(workflow=workflow)
            if wti_uuid and wti_uuid.startswith(self.NEW_UUID_PREFIX):
                new_wtis_by_uuid[wti_uuid] = saved_wti

        if wts is None:
            # FIXME: handle case when transitions are not resent
            logger.info('Workflow Transitions not set')
        else:
            for wt_dict in wts:
                wt_uuid = wt_dict.pop('uuid', None)
                existing_wt = None

                if wt_uuid and not wt_uuid.startswith(self.NEW_UUID_PREFIX):
                    existing_wt = old_wts_by_uuid.pop(wt_uuid, None)

                    if existing_wt is None:
                        raise ValidationError({
                            'workflow_task_instances': [
                                ErrorDetail(f'Workflow Transition with UUID {wt_uuid} is not part of Workflow',
                                        code='invalid')
                            ]
                        })

                from_wti_dict = wt_dict.get('from_workflow_task_instance', None)
                if from_wti_dict:
                    wti_uuid = from_wti_dict['uuid']
                    if wti_uuid.startswith(self.NEW_UUID_PREFIX):
                        from_wti_dict['uuid'] = str(new_wtis_by_uuid[wti_uuid].uuid)

                to_wti_dict = wt_dict.get('to_workflow_task_instance', None)
                if to_wti_dict:
                    wti_uuid = to_wti_dict['uuid']
                    if wti_uuid.startswith(self.NEW_UUID_PREFIX):
                        to_wti_dict['uuid'] = str(new_wtis_by_uuid[wti_uuid].uuid)

                if existing_wt:
                    ser = WorkflowTransitionSerializer(existing_wt, data=wt_dict, context=self.context)
                else:
                    ser = WorkflowTransitionSerializer(data=wt_dict, context=self.context)

                ser.is_valid(raise_exception=True)
                ser.save()

            WorkflowTransition.objects.filter(uuid__in=old_wts_by_uuid.keys()).delete()

        return workflow


import subprocess
from datetime import datetime
import tkinter as tk
from tkinter import ttk
from tkinter import messagebox
from local import my_printer, printer_list

# Ce programme imprime de petites étiquettes pour des tubes de type Eppendorf 1.5 ml
# L'utilisateur dispose de 4 champs.
# L'utilisateur peut décider d'imprimer la date d'impression ou un cinquième champ.

# Fonction pour imprimer les étiquettes
def print_labels():
    field_1 = entry_field_1.get()
    field_2 = entry_field_2.get()
    field_3 = entry_field_3.get()
    field_4 = entry_field_4.get()
    nb_labels = int(entry_nb_labels.get())  # Récupère le nombre d'étiquettes

    if add_date_var.get():
        now = datetime.now().strftime("%Y/%m/%d %H:%M")
    else:
        now = alt_field_for_date.get()

    ipl_format_for_Epp_1_5_ml = f"""
    <STX><ESC>C<ETX><STX><ESC>P<ETX><STX>E5;F5;<ETX>
    <STX>H01;o315,565;b0;f2;h01;w01;c34;d3,{field_1};<ETX>
    <STX>H02;o55,565;b1;f2;h01;w01;c31;d3,{field_2};<ETX>
    <STX>H04;o315,520;b0;f2;h01;w01;c34;d3,{field_3};<ETX>

    <STX>H05;o315,455;b0;f2;h02;w01;c2;d3,{field_4};<ETX>
    <STX>H06;o315,415;b0;f2;h01;w01;c30;d3,{now};<ETX>

    /* ligne */
    <STX>L07;o315,380;f2;l1300;w4<ETX>
    # <STX>B10;o125,115;c2;f3;h160;w03;i0;d3," + ";<ETX>

    /* afficher ALIQUOT BIO MOL   */
    <STX>H14;o315,300;b1;f2;h01;w01;c31;d3,BIOMOL;<ETX>

    /* Mini étiquette pour couvercle */
    <STX>H16;o315,100;b0;f2;h01;w01;c31;d3,{field_1};<ETX>
    <STX>H17;o315,65;b0;f2;h01;w01;c31;d3,{field_3};<ETX>
    <STX>R<ETX><STX><ESC>E5<CAN><ETX><STX><RS>{nb_labels}<ETB><ETX>
    """

    with open("etiq.txt", 'w') as f:
        f.writelines(ipl_format_for_Epp_1_5_ml)

    try:
        subprocess.check_output(["copy", ".\etiq.txt", selected_printer.get()], shell=True)
        messagebox.showinfo("Impression réussie", "Les étiquettes ont été imprimées avec succès.")
    except Exception as e:
        messagebox.showerror("Erreur d'impression", f"Une erreur est survenue lors de l'impression : {str(e)}")

# Fonction pour activer ou désactiver le champ field_5 en fonction de la case à cocher
def toggle_field_5():
    if add_date_var.get():
        alt_field_for_date.grid_remove()  # Masquer le champ field_5
    else:
        alt_field_for_date.grid(row=6, column=1)  # Afficher le champ field_5
        alt_field_for_date.configure(state ='normal')

# Création de la fenêtre principale
root = tk.Tk()
# root.geometry("600x400")
root.title("Générateur d'étiquettes")

# Sélection de l'imprimante
printer_frame = ttk.Frame(root)
printer_frame.grid(row= 0, column=0, rowspan=2, columnspan=2)

label_printer = ttk.Label(printer_frame, text="Sélectionnez l'imprimante :")
label_printer.grid(row = 0, column = 0, pady = 30, sticky='W')

# printer_list = ["Imprimante1", "Imprimante2", "Imprimante3"]  # Remplacez par vos imprimantes réelles
selected_printer = tk.StringVar(value=printer_list[0])
printer_menu = ttk.Combobox(printer_frame, textvariable=selected_printer, values=printer_list)
printer_menu.grid(row = 0, column = 1, sticky='W')

# Champs à remplir
entry_frame = ttk.Frame(root)
entry_frame.grid(pady=20, padx= 50)

label_fields = ttk.Label(entry_frame, text="Remplissez les champs :")
label_fields.grid(row=1, column=0, rowspan=3)

entry_field_1 = ttk.Entry(entry_frame, width=11)
entry_field_1.insert(0, "25121245")
entry_field_1.grid(row=1, column=1, sticky='W')

entry_field_2 = ttk.Entry(entry_frame, width=2)  # Champ 2 réduit à 2 caractères
entry_field_2.insert(0, "98")
entry_field_2.grid(row=1, column=2, sticky='W')

entry_field_3 = ttk.Entry(entry_frame, width=24)
entry_field_3.insert(0, "TEST second")
entry_field_3.grid(row=2, column=1 )

entry_field_4 = ttk.Entry(entry_frame, width=20)
entry_field_4.insert(0, "31/12/1964 M")
entry_field_4.grid(row=3, column=1, sticky='W' )

# Option pour ajouter la date du jour
add_date_var = tk.BooleanVar(value = True)
add_date_checkbox = ttk.Checkbutton(entry_frame, text="Ajouter la date du jour", variable=add_date_var,
                                    command=toggle_field_5)
add_date_checkbox.grid(row=5, column=1)

# Champ pour spécifier le champ field_5 (initialement grisé)
label_field_5 = ttk.Label(entry_frame, text="Champ libre :")
label_field_5.grid(row=6, column=0)

alt_field_for_date = ttk.Entry(entry_frame, width=20,
                               state="disabled"
                               )
alt_field_for_date.grid(row=6, column=1)

# Champ pour spécifier le nombre d'étiquettes à imprimer
last_frame = ttk.Frame(root)
last_frame.grid(pady=20)

label_nb_labels = ttk.Label(last_frame, text="Nombre d'étiquettes à imprimer :")
label_nb_labels.grid(row= 0, column= 0)

entry_nb_labels = ttk.Entry(last_frame, width=5)
entry_nb_labels.insert(0, "3")  # Valeur par défaut
entry_nb_labels.grid(row= 0, column= 1, sticky='W')

# Bouton d'impression
bottom_frame = ttk.Frame(root)
bottom_frame.grid(pady=20)
print_button = ttk.Button(bottom_frame, text="Imprimer", command=print_labels)
print_button.grid(row= 1, column = 1)

root.mainloop()

input("")


from PyQt5.QtWidgets import  QDialog, QComboBox, QPushButton, QRadioButton
from pulse.utils import error
from os.path import basename
from PyQt5.QtGui import QIcon
from PyQt5.QtCore import Qt
from PyQt5 import uic
import configparser

class ElementTypeInput(QDialog):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        uic.loadUi('pulse/uix/user_input/ui/elementTypeInput.ui', self)

        icons_path = 'pulse\\data\\icons\\'
        self.icon = QIcon(icons_path + 'pulse.png')
        self.setWindowIcon(self.icon)

        self.index = 0
        self.element_type = 'pipe_1'

        self.comboBox = self.findChild(QComboBox, 'comboBox')
        self.comboBox.currentIndexChanged.connect(self.selectionChange)
        self.index = self.comboBox.currentIndex()

        self.radioButton_all = self.findChild(QRadioButton, 'radioButton_all')
        self.radioButton_entity = self.findChild(QRadioButton, 'radioButton_entity')
        self.radioButton_all.toggled.connect(self.radioButtonEvent)
        self.radioButton_entity.toggled.connect(self.radioButtonEvent)
        self.flagAll = self.radioButton_all.isChecked()
        self.flagEntity = self.radioButton_entity.isChecked()

        self.pushButton_2 = self.findChild(QPushButton, 'pushButton_confirm')
        self.pushButton_2.clicked.connect(self.button_clicked)

        self.exec_()

    def radioButtonEvent(self):
        self.flagAll = self.radioButton_all.isChecked()
        self.flagEntity = self.radioButton_entity.isChecked()

    def keyPressEvent(self, event):
        if event.key() == Qt.Key_Enter or event.key() == Qt.Key_Return:
            self.check()
        elif event.key() == Qt.Key_Escape:
            # self.index = -1
            self.close()

    def selectionChange(self, index):
        self.index = self.comboBox.currentIndex()
        if self.index == 0:
            self.element_type = 'pipe_1'
        elif self.index == 1:
            self.element_type = 'pipe_2'
        elif self.index == 2:
            self.element_type = 'shell'

    def check(self):
        self.close()

    def button_clicked(self):
        self.check()


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

import matplotlib.pyplot as plt
import numpy as np

def approach_angle_reward(roll,pitch):
    if np.abs(roll) + np.abs(pitch) < 0.174:
        return 100*np.exp((7.0*(0.174-np.abs(roll) - np.abs(pitch)))**1)
    if (np.abs(roll) + np.abs(pitch)<=1.55)and(np.abs(roll) + np.abs(pitch) >=0.174):
        return -6.0*(np.exp((3.2*(np.abs(roll) + np.abs(pitch)-0.174))**1))
    if (np.abs(roll) + np.abs(pitch)>1.55):
        return -500.0

def flip_reward(angle,prev_angle):
    if np.abs(angle) < 0.26:
        return 0.05*np.exp(20*(0.26-np.abs(angle)))
    if (np.abs(angle)>=0.26):
        return -7.0*np.exp((2.1*(np.abs(angle)-0.26))**1)

def approach_velocity_reward(velocity):
    if velocity>1.6:
        return -20.0*np.exp((0.45*(np.abs(velocity)))**1)
    if (velocity<=1.6) and (velocity >=0.1):
        return - 12.5 * np.exp(2.1*(velocity-0.1))
    if velocity < 0.1:
        return +55.0 * np.exp(20*(0.1-velocity))

# approach angle
#roll_space = np.linspace(-1.57,1.57,300)
#pitch_space = np.linspace(-1.57,1.57,300)

#X,Y = np.meshgrid(roll_space,pitch_space)
#
#Z = np.zeros(shape = (len(roll_space),len(pitch_space)))

#for it_r,r in enumerate(roll_space):
#    for it_p,p in enumerate(pitch_space):
#        Z[it_r,it_p] = approach_angle_reward(r,p)

# calculate angle_space for flipping
#angle_space = np.linspace(-3.14,3.14,500)
#dummy_space = np.linspace(-3.14,3.14,500)
#
#
#X,Y = np.meshgrid(angle_space,dummy_space)
#Z = np.zeros(shape = (len(angle_space),len(dummy_space)))
#
#for it_a1,a1 in enumerate(angle_space):
#    for it_a2,a2 in enumerate(dummy_space):
#        Z[it_a1,it_a2] = flip_reward(a1,a2)

# approach velocity

vel_space = np.linspace(0.0,10,500)
dummy_space = np.linspace(0.0,10,500)

X,Y = np.meshgrid(vel_space,dummy_space)
Z = np.zeros(shape = (len(vel_space),len(dummy_space)))

for it_a1,a1 in enumerate(vel_space):
    for it_a2,a2 in enumerate(dummy_space):
        Z[it_a1,it_a2] = approach_velocity_reward(a1)

fig, ax = plt.subplots(figsize=(7, 7), dpi=100)

# for positive values
p = ax.pcolor(X, Y, Z, cmap=plt.cm.RdBu, vmin=(Z).min(), vmax=(Z).max())

#p = ax.pcolor(X, Y, Z, cmap=plt.cm.RdBu, vmin=Z.min(), vmax=Z.max())

cb = fig.colorbar(p)

#cnt = plt.contour(Z, cmap=plt.cm.RdBu, vmin=abs(Z).min(), vmax=abs(Z).max(), extent=[0, 1, 0, 1])