from datetime import date

cities = ['Alcalá', 'Andalucía', 'Ansermanuevo', 'Argelia', 'Bolívar',
          'Buenaventura',	'Bugalagrande',	'Caicedonia', 'Cali', 'Calima - El Darién',
          'Candelaria', 'Cartago', 'Dagua', 'El Águila', 'El Cairo', 'El Cerrito',
          'El Dovio',	'Florida',	'Ginebra',	'Guacarí', 'Guadalajara de Buga', 'Jamundí',
          'La Cumbre', 'La Unión', 'La Victoria',	'Obando', 'Palmira', 'Pradera',
          'Restrepo', 'Riofrío', 'Roldanillo', 'San Pedro', 'Sevilla', 'Toro', 'Trujillo',
          'Tuluá', 'Ulloa', 'Versalles', 'Vijes',	'Yotoco', 'Yumbo', 'Zarzal']  # Ciudades Valle del Cauca
citiesLength = 42  # Número de ciudades
days = 20  # Proyección en días del modelo

epsilon = 12  # LOSS promedio
gompertzParamsLength = 6

citiesIndex = range(citiesLength)  # Indices de ciudades
daysIndex = range(days)  # Indices de días

sigmasPath = "./assets/sigmas.csv"
thetasPath = "./assets/thetas.csv"
gompertzPath = "./assets/gompertz.csv"
costsPath = "./assets/costs.csv"

startDate = date(2020, 3, 15)

def getElapsedDays():
    return abs((date.today() - startDate).days)


"""Setup module for gios."""
from pathlib import Path

from setuptools import setup

PROJECT_DIR = Path(__file__).parent.resolve()
README_FILE = PROJECT_DIR / "README.md"
VERSION = "3.1.0"

with open("requirements.txt", encoding="utf-8") as file:
    requirements = file.read().splitlines()

setup(
    name="gios",
    version=VERSION,
    author="Maciej Bieniek",
    description="Python wrapper for getting air quality data from GIOŚ servers.",
    long_description=README_FILE.read_text(encoding="utf-8"),
    long_description_content_type="text/markdown",
    include_package_data=True,
    url="https://github.com/bieniu/gios",
    license="Apache-2.0 License",
    packages=["gios"],
    package_data={"gios": ["py.typed"]},
    python_requires=">=3.10",
    install_requires=requirements,
    classifiers=[
        "Development Status :: 5 - Production/Stable",
        "License :: OSI Approved :: Apache Software License",
        "Operating System :: OS Independent",
        "Programming Language :: Python",
        "Programming Language :: Python :: 3",
        "Programming Language :: Python :: 3.10",
        "Programming Language :: Python :: 3.11",
        "Programming Language :: Python :: 3 :: Only",
        "Typing :: Typed",
    ],
)


from flask import Flask, render_template, redirect, request
import os

app = Flask(__name__)

tasks = {
    1 :{
        'id': 1,
     'Name': "Vacuum",
     'Description': '10am',
     "urgent": True,
     "done": True

    },
    2: {
        'id': 2,
     'Name': "Wash floor",
     'Description': '11am',
     "urgent": True,
     "done": True
    }
    }

next_id = 3

@app.route("/add", methods=["GET", "POST"])
def add_items():
    global next_id
    if request.method == "GET":
        return render_template("todoform.html")
    else:

        name_add = request.form["name"]
        description_add = request.form["description"]

        new_item = {
            "id": next_id,
            "Name": name_add,
            "Description": description_add,
            "urgent": "urgent" in request.form,
            "done": "done" in request.form
        }

        tasks[next_id]= new_item

        next_id += 1
        return redirect("/")

@app.route("/")
def showHi():
    return render_template("index.html", tasks=tasks.values())

@app.route("/add", methods = ["POST", "GET"])
def getID():
    id = request.args.get("next_id")
    return redirect("/edit/" + id)

@app.route("/edit/<int:id>", methods = ["POST", "GET"])
def showEdit(id):
    if request.method == "POST":
        changed_item = {
            "id": id,
            "Name": request.form["name"] ,
            "Description": request.form["description"],
            "urgent": "urgent" in request.form,
            "done": "done" in request.form
        }
        tasks[id] = changed_item
        return redirect("/")

    else:
        return render_template("edit_task_form.html", task= tasks[id])

if __name__ == "__main__":
    app.run(host=os.getenv('IP', '0.0.0.0'), port=int(os.getenv('PORT', 8080)))


from django.contrib.auth.models import AbstractUser
from django.db import models
from django.utils.translation import gettext_lazy as _

from user.validators import validate_phone

class User(AbstractUser):
    """Пользователь"""

    middle_name = models.CharField(
        'Отчество',
        max_length=100,
        null=True,
        blank=True
    )
    phone = models.CharField(
        'Номер мобильного телефона',
        max_length=10,
        null=True,
        blank=True,
        validators=[validate_phone],
        unique=True
    )
    is_verify_phone = models.BooleanField(
        'Телефон подтвержден',
        default=False
    )
    is_verify_email = models.BooleanField(
        'Почта подтверждена',
        default=False
    )
    department = models.ForeignKey(
        'user.Department',
        verbose_name='Отдел',
        null=True,
        blank=True,
        on_delete=models.CASCADE,
        related_name='users'
    )

    def get_full_name(self):
        return '{0}{1}{2}'.format(
            '%s ' % self.last_name if self.last_name else '',
            '%s ' % self.first_name if self.first_name else '',
            '%s' % self.middle_name if self.middle_name else ''
        )

    def __str__(self):
        return self.get_full_name()

    class Meta:
        verbose_name = _('Пользователь')
        verbose_name_plural = _('Пользователи')

class Department(models.Model):
    """Отдел"""

    name = models.CharField(
        max_length=100,
        verbose_name='Название',
        unique=True
    )
    director = models.ForeignKey(
        'user.User',
        verbose_name='Создатель комментария',
        on_delete=models.CASCADE,
        related_name='departments'
    )

    def __str__(self):
        return self.name

    class Meta:
        verbose_name = _('Отдел')
        verbose_name_plural = _('Отделы')

class Invite(models.Model):
    """Приглашение"""

    invite_from = models.ForeignKey(
        'user.User',
        verbose_name='Кто пригласил',
        on_delete=models.CASCADE,
        related_name='invites'
    )
    invite_to = models.OneToOneField(
        'user.User',
        verbose_name='Кого пригласили',
        on_delete=models.CASCADE,
        unique=True
    )
    invite_date = models.DateTimeField(
        auto_now_add=True,
        verbose_name='Дата и время приглашения'
    )
    code = models.CharField(
        max_length=32,
        verbose_name='Код приглашения',
        unique=True
    )

    def __str__(self):
        return self.invite_to.email

    class Meta:
        verbose_name = _('Приглашение')
        verbose_name_plural = _('Приглашения')

class VisitHistory(models.Model):
    """История посещений"""

    user = models.ForeignKey(
        'user.User',
        verbose_name='Пользователь',
        on_delete=models.CASCADE,
        related_name='visit_histories'
    )
    visit_date = models.DateTimeField(
        auto_now_add=True,
        verbose_name='Дата и время посещения'
    )
    ip_address = models.CharField(
        max_length=100,
        verbose_name='IP адрес'
    )

    def __str__(self):
        return '{0} {1}'.format(self.visit_date, self.user.email)

    class Meta:
        verbose_name = _('История посещений')
        verbose_name_plural = _('История посещений')


# coding: utf-8

import numpy as np
import matplotlib.pyplot as plt
from multiprocessing import Pool
import os

def draw_dual(i, top, bottom):
    fig = plt.figure(figsize=(4.56, 1.44))
    # ax = fig.add_subplot(111)
    ax = fig.add_axes([0, 0, 1, 1])
    ax.patch.set_facecolor('k')
    ax.plot(top[:, 0], top[:, 1], color='r', linewidth=0.5, zorder=10)
    ax.plot(bottom[:, 0], bottom[:, 1], color='c', linewidth=0.5, zorder=10)
    ax.scatter(top[i, 0], top[i, 1], color='r', linewidth=1, zorder=20)
    ax.scatter(bottom[i, 0], bottom[i, 1], color='c', linewidth=1, zorder=20)
    ylim = ax.get_ylim()
    ylim = max(map(abs, ylim))
    ax.set_ylim(-1.1 * ylim, 1.1 * ylim)
    xlim = ax.get_xlim()
    ax.set_xlim(-3, xlim[1])
    ax.set_xticks([])
    ax.set_yticks([])
    ax.spines['top'].set_color('none')
    ax.spines['right'].set_color('none')
    ax.spines['left'].set_position(('data', 0))
    ax.spines['left'].set_linewidth(0.5)
    ax.spines['left'].set_color('w')
    ax.spines['bottom'].set_position(('data', 0))
    ax.spines['bottom'].set_linewidth(0.5)
    ax.spines['bottom'].set_color('w')
    plt.savefig('./series/time_history' + str(i), dpi=600, facecolor='none')
    plt.clf()
    plt.close()

def draw_single(i, eq):
    fig = plt.figure(figsize=(4.56, 1.44))
    # ax = fig.add_subplot(111)
    ax = fig.add_axes([0, 0, 1, 1])
    ax.patch.set_facecolor('k')
    ax.plot(eq[:, 0], eq[:, 1], color='c', linewidth=0.5, zorder=10)
    ax.scatter(eq[i, 0], eq[i, 1], color='r', linewidth=1, zorder=20)
    ylim = ax.get_ylim()
    ylim = max(map(abs, ylim))
    ax.set_ylim(-1.1 * ylim, 1.1 * ylim)
    xlim = ax.get_xlim()
    ax.set_xlim(-3, xlim[1])
    ax.set_xticks([])
    ax.set_yticks([])
    ax.spines['top'].set_color('none')
    ax.spines['right'].set_color('none')
    ax.spines['left'].set_position(('data', 0))
    ax.spines['left'].set_linewidth(0.5)
    ax.spines['left'].set_color('w')
    ax.spines['bottom'].set_position(('data', 0))
    ax.spines['bottom'].set_linewidth(0.5)
    ax.spines['bottom'].set_color('w')
    plt.savefig('./series/time_history' + str(i), dpi=600, facecolor='none')
    plt.clf()
    plt.close()

def read_config():
    with open('config.txt', 'r', encoding='utf-8') as fConfig:
        temp = fConfig.readline()
        threads = int(fConfig.readline().strip())
        temp = fConfig.readline()
        gms = int(fConfig.readline().strip())
        if gms != 1 and gms != 2:
            return (threads, gms, False)
        else:
            return (threads, gms, True)

def main():
    config = read_config()
    if not config[2]:
        print('Number of GMs should be 1 or 2!')
        return
    threads = config[0]
    gms = config[1]

    if not os.path.exists('./series'):
        os.makedirs('./series')

    print('Parent process %s. ' % os.getpid())
    p = Pool(threads)  # 多进程数

    if gms == 1:
        # draw_single
        eq = np.loadtxt('./EW.txt', skiprows=1)
        cj = eq[:, 0].size
        cj = 1  # for testing
        for i in range(cj):
            p.apply_async(draw_single, args=(i, eq))

    elif gms == 2:
        # draw_dual
        top = np.loadtxt('./top.txt', skiprows=0)
        bottom = np.loadtxt('./bottom.txt', skiprows=0)
        cj = max(top[:, 0].size, bottom[:, 0].size)
        cj = 1  # For testing
        for i in range(cj):
            p.apply_async(draw_dual, args=(i, top, bottom))

    p.close()
    p.join()
    print('Done!')

if __name__ == '__main__':
    main()


'''Interactions that leverage the Empirical Interpolation Method (EIM) to allow
the emulation of parameters in which the coordinate-space potential is not
affine.
'''

from typing import Callable
import numpy as np
from scipy.stats import qmc

from .interaction import Interaction, InteractionSpace, couplings
from .constants import HBARC, DEFAULT_RHO_MESH
from .spin_orbit import SpinOrbitTerm

def max_vol(basis, indxGuess):
    r'''basis looks like a long matrix, the columns are the "pillars" V_i(x):
        [   V_1(x)
            V_2(x)
            .
            .
            .
        ]
        indxGuess is a first guess of where we should "measure", or ask the questions

    '''
    nbases = basis.shape[1]
    interpBasis = np.copy(basis)

    for ij in range(len(indxGuess)):
        interpBasis[[ij,indxGuess[ij]],:] = interpBasis[[indxGuess[ij],ij],:]
    indexing = np.array(range(len(interpBasis)))

    for ij in range(len(indxGuess)):
        indexing[[ ij,indxGuess[ij] ]] = indexing[[ indxGuess[ij],ij ]]

    for iIn in range(1, 100):
        B = np.dot(interpBasis, np.linalg.inv(interpBasis[:nbases]))
        b = np.max(B)
        if b > 1:

            p1, p2 = np.where(B == b)[0][0], np.where(B == b)[1][0]
            interpBasis[[p1,p2],:] = interpBasis[[p2,p1],:]
            indexing[[p1,p2]] = indexing[[p2,p1]]
        else:
            break
        #this thing returns the indexes of where we should measure
    return np.sort(indexing[:nbases])

class InteractionEIM(Interaction):
    def __init__(self,
        coordinate_space_potential: Callable[[float, np.array], float], # V(r, theta)
        n_theta: int, # How many parameters does the interaction have?
        mu: float, # reduced mass (MeV)
        energy: float, # E_{c.m.}
        ell: int,
        training_info: np.array,
        Z_1: int = 0, # atomic number of particle 1
        Z_2: int = 0, # atomic number of particle 2
        R_C: float = 0.0, # Coulomb "cutoff"
        is_complex: bool = False,
        spin_orbit_term: SpinOrbitTerm = None,
        n_basis: int = None,
        explicit_training: bool = False,
        n_train: int = 1000,
        rho_mesh: np.array = DEFAULT_RHO_MESH,
        match_points: np.array = None
    ):
        r'''
        Parameters:
            coordinate_space_potential (Callable[[float,ndarray],float]): V(r,
                theta) where theta are the interaction parameters
            n_theta (int): number of interaction parameters
            mu (float): reduced mass (MeV); converted to 1/fm
            energy (float): center-of-mass scattering energy
            ell (int): angular momentum
            training_info (ndarray): Either (1) parameters bounds or (2)
                explicit training points

                If (1):
                    This is a 2-column matrix. The first column are the lower
                    bounds. The second are the upper bounds. Each row maps to a
                    single parameter.

                If (2):
                    This is an MxN matrix. N is the number of parameters. M is
                    the number of samples.
            Z_1 (int): charge of particle 1
            Z_2 (int): charge of particle 2
            R_C (float): Coulomb "cutoff" radius
            is_complex (bool): Is the interaction complex (e.g. optical
                potentials)?
            spin_orbit_term (SpinOrbitTerm): spin-orbit part of the interaction
            n_basis (int): number of basis states, or "pillars" in $\hat{U}$ approximation
            explicit_training (bool): Is training_info (1) or (2)? (1) is
                default
            n_train (int): How many snapshots to generate? Ignored if
                explicit_training is True.
            rho_mesh (ndarray): coordinate-space points at which the interaction
                is generated (used for training)
            match_points (ndarray): $\rho$ points where agreement with the true
                potential is enforced

        Attributes:
            s_mesh (ndarray): $s$ points
            singular_values (ndarray): `S` in `U, S, Vt = numpy.linalg.svd(...)`
            snapshots (ndarray): pillars, columns of `U`
            match_indices (ndarray): indices of points in $\rho$ mesh that are
                matched to the true potential
            match_points (ndarray): points in $\rho$ mesh that are matched to
                the true potential
            r_i (ndarray): copy of `match_points` (???)
            Ainv (ndarray): inverse of A matrix (Ax = b)
        '''

        super().__init__(coordinate_space_potential, n_theta, mu, energy, ell,
            Z_1=Z_1, Z_2=Z_2, R_C=R_C, is_complex=is_complex, spin_orbit_term=spin_orbit_term)

        self.s_mesh = rho_mesh.copy()
        # Generate a basis used to approximate the potential.
        # Did the user specify the training points?
        if explicit_training:
            snapshots = np.array([self.tilde(rho_mesh, theta) for theta in training_info]).T
        else:
            # Generate training points using the user-provided bounds.
            sampler = qmc.LatinHypercube(d=len(training_info))
            sample = sampler.random(n_train)
            train = qmc.scale(sample, training_info[:, 0], training_info[:, 1])
            snapshots = np.array([self.tilde(rho_mesh, theta) for theta in train]).T

        U, S, _ = np.linalg.svd(snapshots, full_matrices=False)
        self.singular_values = np.copy(S)

        if match_points is None:
            if n_basis is None:
                n_basis = n_theta
            self.snapshots = np.copy(U[:, :n_basis])
            # random r points between 0 and 2π fm
            i_max = self.snapshots.shape[0] // 2
            di = i_max // (n_basis - 1)
            i_init = np.arange(0, i_max + 1, di)
            self.match_indices = max_vol(self.snapshots, i_init)
                # np.random.randint(0, self.snapshots.shape[0], size=self.snapshots.shape[1]))
            self.match_points = rho_mesh[self.match_indices]
            self.r_i = np.copy(self.match_points)
        else:
            n_basis = match_points.size
            self.snapshots = np.copy(U[:, :n_basis])
            self.match_points = np.copy(match_points)
            self.match_indices = np.array([np.argmin(np.abs(rho_mesh - ri)) for ri in self.match_points])
            self.r_i = rho_mesh[self.match_indices]

        self.Ainv = np.linalg.inv(self.snapshots[self.match_indices])

    def coefficients(self,
        alpha: np.array
    ):
        r'''Computes the EIM expansion coefficients.

        Parameters:
            alpha (ndarray): interaction parameters

        Returns:
            coefficients (ndarray): EIM expansion coefficients

        '''
        u_true = self.tilde(self.r_i, alpha)
        return 1/self.k, self.Ainv @ u_true

    def tilde_emu(self,
        alpha: np.array
    ):
        r'''Emulated interaction = $\hat{U}(s, \alpha, E)$

        Parameters:
            alpha (ndarray): interaction parameters

        Returns:
            u_hat (ndarray): emulated interaction

        '''
        _, x = self.coefficients(alpha)
        emu = np.sum(x * self.snapshots, axis=1)
        return emu

    def basis_functions(self, s_mesh: np.array):
        r'''$u_j$ in $\tilde{U} \approx \hat{U} \equiv \sum_j \beta_j(\alpha) u_j$

        Parameters:
            s_mesh (ndarray): $s$ mesh points

        Returns:
            u_j (ndarray): "pillars" (MxN matrix; M = number of mesh points; N = number of pillars)

        '''
        return np.copy(self.snapshots)

class InteractionEIMSpace(InteractionSpace):
    def __init__(self,
        coordinate_space_potential: Callable[[float, np.array], float], # V(r, theta)
        n_theta: int, # How many parameters does the interaction have?
        mu: float, # reduced mass (MeV)
        energy: float, # E_{c.m.}
        l_max: int,
        training_info: np.array,
        Z_1: int = 0, # atomic number of particle 1
        Z_2: int = 0, # atomic number of particle 2
        R_C: float = 0.0, # Coulomb "cutoff"
        is_complex: bool = False,
        spin_orbit_potential: Callable[[float, np.array, float], float] = None, #V_{SO}(r, theta, l•s)
        n_basis: int = None,
        explicit_training: bool = False,
        n_train: int = 1000,
        rho_mesh: np.array = DEFAULT_RHO_MESH,
        match_points: np.array = None
    ):
        r'''Generates a list of $\ell$-specific, EIMed interactions.

        Parameters:
            coordinate_space_potential (Callable[[float,ndarray],float]): V(r, theta)
            n_theta (int): number of parameters
            mu (float): reduced mass
            energy (float): center-of-mass, scattering energy
            l_max (int): maximum angular momentum
            training_info (ndarray): See `InteractionEIM` documentation.
            Z_1 (int): charge of particle 1
            Z_2 (int): charge of particle 2
            R_C (float): Coulomb "cutoff" radius
            is_complex (bool): Is the interaction complex?
            spin_orbit_potential (Callable[[float, np.array, float], float]):
                used to create a `SpinOrbitTerm`
            n_basis (int): number of pillars --- basis states in $\hat{U}$ expansion
            explicit_training (bool): See `InteractionEIM` documentation.
            n_train (int): number of training samples
            rho_mesh (ndarray): discrete $\rho$ points
            match_points (ndarray): $\rho$ points where agreement with the true
                potential is enforced

        Returns:
            instance (InteractionEIMSpace): instance of InteractionEIMSpace

        Attributes:
            interactions (list): list of `InteractionEIM`s
        '''
        self.interactions = []
        if spin_orbit_potential is None:
            for l in range(l_max+1):
                self.interactions.append(
                    [InteractionEIM(coordinate_space_potential, n_theta, mu,
                        energy, l, training_info, Z_1=Z_1, Z_2=Z_2, R_C=R_C,
                        is_complex=is_complex, n_basis=n_basis, explicit_training=explicit_training,
                        n_train=n_train, rho_mesh=rho_mesh, match_points=match_points)]
                )
        else:
            for l in range(l_max+1):
                self.interactions.append(
                    [InteractionEIM(coordinate_space_potential, n_theta, mu,
                        energy, l, training_info, Z_1=Z_1, Z_2=Z_2, R_C=R_C,
                        is_complex=is_complex,
                        spin_orbit_term=SpinOrbitTerm(spin_orbit_potential,
                        lds), n_basis=n_basis,
                        explicit_training=explicit_training, n_train=n_train,
                        rho_mesh=rho_mesh, match_points=match_points) for lds in
                        couplings(l)]
                )


from flask import redirect, render_template, request, url_for, session, abort
from flaskps.models.user import User
from flaskps.models.rol import RolModel
from flaskps.models.entities.mappers.user_mapper import to_usuario
from flaskps.helpers.auth import authenticated, requiere_permiso
from flaskps.helpers.config import sitio_habilitado

@sitio_habilitado()
@requiere_permiso("usuario_index")
def index():
    users = User.all()
    return render_template('user/index.html', users=users.items)

@sitio_habilitado()
@requiere_permiso("usuario_new")
def new():
    roles = RolModel.all()
    return render_template('user/new.html', roles=roles)

@sitio_habilitado()
@requiere_permiso("usuario_new")
def create():
    if not authenticated(session):
        abort(401)

    new_user = to_usuario(request.form)
    user = User.find_by_username(new_user.username)
    if user is None:
        User.save(new_user, request.form.getlist("rol"))
        return redirect(url_for('user_index'))
    else:
        mensaje = "El usuario ya existe"
        return render_template('user/new.html', mensaje = mensaje, roles = RolModel.all(), nombre = new_user.first_name, apellido = new_user.last_name, usuario = new_user.username, correo = new_user.email)

@sitio_habilitado()
@requiere_permiso("usuario_update")
def edit(id):
    aUser = User.find_by_id(id)
    roles = RolModel.all()
    return render_template('user/edit.html',aUser=aUser,roles=roles)

@sitio_habilitado()
@requiere_permiso("usuario_update")
def save():
    id = request.form["id"]
    edit_user = to_usuario(request.form)
    user = User.find_by_username(edit_user.username)
    user_same = User.find_by_id(id)
    if user is None:
        User.update(edit_user, request.form.getlist("rol"), id)
        return redirect(url_for('user_index'))
    elif (user_same.username == edit_user.username or user_same.email == edit_user.email) and user is None:
        User.update(edit_user, request.form.getlist("rol"), edit_user.id)
        return redirect(url_for('user_index'))
    else:
        mensaje = "El usuario ya existe"
        return render_template('user/index.html', mensaje = mensaje)

@sitio_habilitado()
@requiere_permiso("usuario_destroy")
def delete(id):
    User.delete_by_id(id)
    return redirect(url_for('user_index'))

@sitio_habilitado()
def inactivos():
    users = User.find_blocked()
    return render_template('user/inactivos.html', users=users.items)

@sitio_habilitado()
def activar(id):
    User.activate_by_id(id)
    return redirect(url_for('user_index'))

@sitio_habilitado()
def activar_todos():
    User.activate_all()
    return redirect(url_for('user_index'))


#Takes a particular file structure (described below) and counts number of events that pass particular
#BF, deltaPSI, and read count fiters for each comparison in the file structure.
#These filters can be easily changed in the code.

#Usage: python MISOcompare.py --help

import sys
import os
import argparse

#Read count filters.  Change if necessary.
readcountfilters = {} #{eventtype : [inclusion_counts (1,0), exclusion_counts (0,1), total_counts ((1,0) + (0,1))]}
readcountfilters['AFE'] = [50, 50, 100]
readcountfilters['ALE'] = [50, 50, 100]
readcountfilters['MXE'] = [1, 1, 10]
readcountfilters['RI'] = [1, 1, 10]
readcountfilters['SE'] = [10, 10, 25]
readcountfilters['TandemUTR'] = [50, 0, 100]

def MISOcompare(MISOdirectory):
    #Main MISO Output directory. Contains subdirectories for all event types.  These
    #subdirectories contains directories called "comparisons" which themselves contain
    #directories for each pairwise comparison (e.g. CADAxon1.psi_vs_CADAxon2.psi)
    #which themselves contain a directory called bayes-factors.
    eventtypes = ['AFE', 'ALE', 'MXE', 'RI', 'SE', 'TandemUTR']
    eventtypedirs = [] #list of all <eventtype>/comparisons directories in MISOdirectory
    outlists = []

    #Get eventtype dirs
    for eventtype in eventtypes:
        eventtypedir = os.path.join(os.path.abspath(MISOdirectory), eventtype, 'comparisons')
        if os.path.exists(eventtypedir):
            eventtypedirs.append(eventtypedir)

    for eventtypedir in eventtypedirs:
        #eventtypedir = <MISOdirectory>/<eventtype>/comparisons
        #One directory up would be the <eventtype> directory
        eventtype = os.path.basename(os.path.abspath(os.path.join(eventtypedir, '..')))
        #eventtype = 'AFE', 'ALE', etc.
        comparisons = []
        #Get list of comparisons to consider
        for directory, dirnames, filenames in os.walk(eventtypedir):
            for dirname in dirnames:
                if '_vs_' in dirname:
                    comparisons.append(dirname)

        for comparison in comparisons:
            comparison_results = [] #[sample1, sample2, eventtype, #events, percent events that are sig.]
            eventcounter = 0
            sigeventcounter = 0
            sample1 = comparison.split('.')[0]
            sample2 = comparison.split('.')[1].split('_')[2]
            comparisontype = ''

            if 'Soma' in sample1 and 'Axon' in sample2:
                comparisontype = 'compartment'
            if 'Axon' in sample1 and 'Soma' in sample2:
                comparisontype = 'compartment'
            if 'CADSoma' in sample1 and 'CADSoma' in sample2:
                comparisontype = 'replicate'
            if 'CADAxon' in sample1 and 'CADAxon' in sample2:
                comparisontype = 'replicate'
            if 'N2ASoma' in sample1 and 'N2ASoma' in sample2:
                comparisontype = 'replicate'
            if 'N2AAxon' in sample1 and 'N2AAxon' in sample2:
                comparisontype = 'replicate'
            if 'CADSoma' in sample1 and 'N2ASoma' in sample2:
                comparisontype = 'celltype'
            if 'CADAxon' in sample1 and 'N2AAxon' in sample2:
                comparisontype = 'celltype'
            if 'N2ASoma' in sample1 and 'CADSoma' in sample2:
                comparisontype = 'celltype'
            if 'N2AAxon' in sample1 and 'CADAxon' in sample2:
                comparisontype = 'celltype'

            #if comparisontype == 'replicate' or comparisontype == 'celltype':
            #comparisontype = 'other'

            #Get bayes factor file
            bffile = os.path.join(os.path.abspath(eventtypedir), comparison, 'bayes-factors', comparison + '.miso_bf')
            bffh = open(bffile, 'r')
            for line in bffh:
                line = line.strip().split('\t')
                if line[0] == 'event_name': #skip header
                    continue
                numberofisoforms = len(line[1].split(',')) + 1
                sample1countspass = False
                sample2countspass = False #reset these values
                #Only consider events with 2 isoforms
                if numberofisoforms == 2:
                    eventcounter +=1
                    inclusionindex = None
                    exclusionindex = None #reset these values
                    deltapsi = float(line[7])
                    bayesfactor = float(line[8])
                    sample1counts = line[10]
                    sample1counts = sample1counts.replace(',(', ';(') #replace comma between classes with semicolon
                    sample1countsd = dict(item.split(':') for item in sample1counts.split(';'))
                    sample2counts = line[12]
                    sample2counts = sample2counts.replace(',(', ';(')
                    sample2countsd = dict(item.split(':') for item in sample2counts.split(';'))
                    for countclass in sample1countsd:
                        sample1countsd[countclass] = int(sample1countsd[countclass]) #change read counts to integers
                    for countclass in sample2countsd:
                        sample2countsd[countclass] = int(sample2countsd[countclass])
                    if '(1,0)' not in sample1countsd:
                        sample1countsd['(1,0)'] = 0
                    if '(0,1)' not in sample1countsd:
                        sample1countsd['(0,1)'] = 0
                    if '(1,0)' not in sample2countsd:
                        sample2countsd['(1,0)'] = 0
                    if '(0,1)' not in sample2countsd:
                        sample2countsd['(0,1)'] = 0
                    combinedsample1counts = sample1countsd['(1,0)'] + sample1countsd['(0,1)']
                    combinedsample2counts = sample2countsd['(1,0)'] + sample2countsd['(0,1)']
                    readfilters = readcountfilters[eventtype] #get read coverage filters

                    if (sample1countsd['(1,0)'] >= readfilters[0] and sample1countsd['(0,1)'] >= readfilters[1]
                        and combinedsample1counts >= readfilters[2]):
                        sample1countspass = True

                    if (sample2countsd['(1,0)'] >= readfilters[0] and sample2countsd['(0,1)'] >= readfilters[1]
                        and combinedsample2counts >= readfilters[2]):
                        sample2countspass = True

                    #Does it pass all filters?
                    if abs(deltapsi) >= 0.1 and bayesfactor >= 10 and sample1countspass and sample2countspass:
                        sigeventcounter +=1

            if sample1 != 'N2AAxon1' and sample2 != 'N2AAxon1' and sample1 != sample2: #had always removed N2AAxon1
                comparison_results = [sample1, sample2, eventtype, comparisontype, str(eventcounter), str(sigeventcounter/float(eventcounter))]
                outlists.append(comparison_results)

            bffh.close()

    return outlists

if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument('--MISOdirectory', type = str, help = 'Main MISO Output directory. Contains subdirectories for all event types.  These subdirectories contains directories called "comparisons" which themselves contain directories for each pairwise comparison (e.g. CADAxon1.psi_vs_CADAxon2.psi) which themselves contain a directory called bayes-factors. Required.')
    parser.add_argument('--outfile', type = str, help = 'Output file. Required.')
    args = parser.parse_args()

    outlists = MISOcompare(args.MISOdirectory)
    outfh = open(args.outfile, 'w')
    outfh.write('Sample1' + '\t' + 'Sample2' + '\t' + 'EventType' + '\t' + 'ComparisonType' + '\t' + 'Events' + '\t' + 'SigEvents' + '\n')
    for entry in outlists:
        outfh.write(('\t').join(entry) + '\n')
    outfh.close()


from abc import ABC, abstractmethod
from io import BytesIO
from typing import TYPE_CHECKING, Callable, Optional, Union

import aiofiles

from vkbottle.exception_factory.base_exceptions import VKAPIError
from vkbottle.modules import json

if TYPE_CHECKING:
    from vkbottle.api import ABCAPI

    Bytes = Union[bytes, BytesIO]

class BaseUploader(ABC):
    def __init__(
        self,
        api: Optional["ABCAPI"] = None,
        api_getter: Optional[Callable[[], "ABCAPI"]] = None,
        generate_attachment_strings: bool = True,
        with_name: Optional[str] = None,
    ):
        assert api_getter is not None or api is not None, "api or api_getter should be set"
        self._get_api = api_getter or (lambda: api)  # type: ignore
        self.generate_attachment_strings = generate_attachment_strings
        self.with_name = with_name

    @abstractmethod
    async def get_server(self, **kwargs) -> dict:
        pass

    @property
    @abstractmethod
    def attachment_name(self) -> str:
        pass

    @property
    def api(self) -> "ABCAPI":
        return self._get_api()  # type: ignore

    async def upload_files(self, upload_url: str, files: dict) -> dict:
        raw_response = await self.api.http_client.request_text(
            upload_url, method="POST", data=files
        )
        return json.loads(raw_response)

    def get_bytes_io(self, data: "Bytes", name: str = None) -> BytesIO:
        bytes_io = data if isinstance(data, BytesIO) else BytesIO(data)
        bytes_io.seek(0)  # To avoid errors with image generators (such as pillow)
        bytes_io.name = (
            name or self.attachment_name
        )  # To guarantee VK API file extension recognition
        return bytes_io

    async def get_owner_id(self, upload_params: dict) -> int:
        if "group_id" in upload_params:
            return upload_params["group_id"]
        if "user_id" in upload_params:
            return upload_params["user_id"]
        if "owner_id" in upload_params:
            return upload_params["owner_id"]
        try:
            return (await self.api.request("groups.getById", {}))["response"][0]["id"]
        except VKAPIError:
            return (await self.api.request("users.get", {}))["response"][0]["id"]

    @staticmethod
    def generate_attachment_string(
        attachment_type: str, owner_id: int, item_id: int, access_key: Optional[str] = None
    ) -> str:
        return f"{attachment_type}{owner_id}_{item_id}{('_' + access_key) if access_key else ''}"

    @staticmethod
    async def read(file_source: Union[str, "Bytes"]) -> "Bytes":
        if isinstance(file_source, str):
            async with aiofiles.open(file_source, "rb") as file:
                return await file.read()
        return file_source

    def __repr__(self) -> str:
        return f"<Uploader {self.__class__.__name__} with api {self.api!r}"


import ebooklib
from ebooklib import epub
from bs4 import BeautifulSoup
import re
import tiktoken

book = epub.read_epub("Ego_Is_the_Enemy_Ryan_Holiday_Z-Library.epub")

items = list(book.get_items_of_type(ebooklib.ITEM_DOCUMENT))

chapters = []

items=book.get_items_of_type(ebooklib.ITEM_DOCUMENT)
for item in items:
    if 'GlobalBackad' in item.get_name() or "navDoc" in item.get_name() or "Cover" in item.get_name():
        continue
    else:
        chapters.append(item)

def chapter_to_str(chapter):
    soup = BeautifulSoup(chapter.get_body_content(), 'html.parser')
    text = [para.get_text() for para in soup.find_all('p')]
    chapter = ''.join(text)
    chapter_word_size = len(re.findall(r'\w+', chapter))
    chapter_token_size = num_tokens_from_string(chapter, "gpt-3.5-turbo")
    return chapter, chapter_word_size, chapter_token_size

def num_tokens_from_string(string: str, model: str) -> int:
    """Returns the number of tokens in a text string."""
    encoding = tiktoken.encoding_for_model(model)
    num_tokens = len(encoding.encode(string))
    return num_tokens

texts = {}
for c in chapters:
    texts[c.get_name()] = chapter_to_str(c)

sum_of_tokens = 0

for text in texts:

    sum_of_tokens = sum_of_tokens + texts[text][2]

max_input_length = 4096  # The maximum length of input that GPT-3.5-turbo can handle

chunks = []
current_chunk = ""

for text in texts:

    chunk_size = num_tokens_from_string(current_chunk, "gpt-3.5-turbo")

    # Check if the current chapter would cause the current chunk to exceed the maximum input length
    if chunk_size + texts[text][2] > max_input_length:
        # If so, add the current chunk to the list of chunks and start a new chunk
        chunks.append(current_chunk)
        current_chunk = ""

    # Add the current chapter to the current chunk
    current_chunk += texts[text][0] + "\n"

# Add the final chunk to the list of chunks
if current_chunk:
    chunks.append(current_chunk)

for chunk in chunks:
    print(num_tokens_from_string(chunk, "gpt-3.5-turbo"))


from unittest import load_tests
import pyglet
from pyglet.gl import *
from random import randrange
from pathlib import Path  # proč je Path velkým ? - is Class
import time

#  konstanty - nastavitelné
speed = 0.6  # rychlost hada - menší číslo zvyšuje rychlost - 0.6
tile_size = 64  # pixelu - članek hada, jablko - 64 x 64
area_size_x = 16  # velikost hřiště šířka - 16
area_size_y = 9  # velikost hřiště výška - 9
number_of_moves_for_add_apple = 8  # počet tahů, po kterých se přidá ovoce - 8
max_number = 10  # hra s čísly - největší číslo

class Snake():
    def __init__(self):
        self.direction = (1,0)
        self.enjoy = False
        self.alive = True
        self.coordinates = (0, 0)
        self.speed = speed
        self.snake_tiles = {}

    def move_snake_number(self):
        x, y = self.coordinates[-1]
        x2, y2 = self.direction
        new_coordinates = (x + x2, y + y2)
        # je had mimo hřiště ? , tak vyleze naproti
        if new_coordinates[1] == - 1:
            new_coordinates = new_coordinates[0] , game.area_size_y - 1
        elif new_coordinates[1] == game.area_size_y:
            new_coordinates = new_coordinates[0] , 0
        elif new_coordinates[0] == - 1:
            new_coordinates = game.area_size_x - 1, new_coordinates[1]
        elif new_coordinates[0] == game.area_size_x:
            new_coordinates = 0, new_coordinates[1]
        self.coordinates.append(new_coordinates)  # had se posunuje, pridani nove souradnice - hlava
        # co kdyby se kousl ?
        if self.coordinates[-1] in self.coordinates[:-2]:
            print(' Had se kousl a je ponim.')
            self.alive = False
            return
        if self.coordinates[-1] in game.coordinates_number.keys():  # je had na čísle ?
            if game.result ==  game.coordinates_number[self.coordinates[-1]]:  # je na správném čísle ?
                game.attempts_good += 1
                self.enjoy = True  # vyplázene jazyk
                self.speed *= 0.98  # zvýší rychlost hada po potravě
                self.coordinates.insert(0, self.coordinates[0])  # had vyroste - ocas
                del game.coordinates_number[self.coordinates[-1]]  # vyjme číslo ze slovníku
                game.new_number()
            else:
                game.attempts_bad += 1
        self.coordinates.pop(0)  # had se posunuje, takže odstranime poslední souřadnici

    def move_snake(self):
        if not self.alive:
            print('už je ponim > move_snake')
            return
        x, y = self.coordinates[-1]
        x2, y2 = self.direction
        new_coordinates = (x + x2, y + y2)

        # je had mimo hřiště ? , tak vyleze naproti
        if new_coordinates[1] == - 1:
            new_coordinates = new_coordinates[0] , game.area_size_y - 1
        elif new_coordinates[1] == game.area_size_y:
            new_coordinates = new_coordinates[0] , 0
        elif new_coordinates[0] == - 1:
            new_coordinates = game.area_size_x - 1, new_coordinates[1]
        elif new_coordinates[0] == game.area_size_x:
            new_coordinates = 0, new_coordinates[1]

        # co kdyby se kousl ?
        if self.coordinates[-1] in self.coordinates[:-2]:
            print(' Had se kousl a je ponim.')
            self.alive = False
            return
        self.coordinates.append(new_coordinates)  # had se posunuje, přidání nové souřadnice - hlava
        # a co jablko ?
        if self.coordinates[-1] in game.coordinates_fruit:  # Snědl jablko ?
            self.enjoy = True  # vyplázene jazyk
            self.speed *= 0.9  # zvýší rychlost hada po potravě
            self.coordinates.insert(0, self.coordinates[0])  # had vyroste - ocas
            game.coordinates_fruit.pop(game.coordinates_fruit.index(self.coordinates[-1]))  # vyjme snězené jablko ze seznamu
        self.coordinates.pop(0)  # had se posunuje, takže odstranime poslední souřadnici

    def draw_snake_number(self):
        # vypis zadání
        v = game.label_task
        label_task = pyglet.text.Label(f' dobře:  {game.attempts_good}    špatně:  {game.attempts_bad}       >    {v}  =  ?', font_name = 'Arial', font_size = 24, x = 20, y = window.height - 40)
        label_task.draw()
        # line under score
        '''
        #pyglet.gl.glColor4f(1.0, 1.0, 1.0);  # nastaveni barvy pro kresleni
        pyglet.gl.glClearColor(1.0, 1.0, 1.0, 1.0) # - - - - - - - - - - - - - - - - - - -    takle je to po novém verze pyglet 2.0
        # pyglet.gl.glBegin(pyglet.gl.GL_LINES);         # nyni zacneme vykreslovat body
        pyglet.gl.glBeginConditionalRender( 0, window.height - 60);
        # pyglet.gl.glVertex2i( 0, window.height - 60);
        pyglet.gl.glVertexAttribI2i( 0, window.height - 60);
        # pyglet.gl.glVertex2i(window.width,  window.height - 60);
        pyglet.gl.glVertexAttribI2i(window.width,  window.height - 60);
        #pyglet.gl.glEnd();
        ###pyglet.gl.glDisableVertexAttribArray
        # draw snake
        pyglet.gl.glEnable(pyglet.gl.GL_BLEND)
        pyglet.gl.glBlendFunc(pyglet.gl.GL_SRC_ALPHA, pyglet.gl.GL_ONE_MINUS_SRC_ALPHA)
        '''
        for a, b, c in zip(['tail'] + self.coordinates, self.coordinates, self.coordinates[1:] + ['head']):
            x, y = b
            move_from = snake_article_calculation(a, b)
            move_to = snake_article_calculation(c, b)
            if move_to == 'head' and not self.alive:
                move_to = 'dead'
            if move_to == 'head' and self.enjoy:
                move_to = 'tongue'
                self.enjoy = False
            self.snake_tiles[move_from + '-' + move_to].blit(x * game.tile_size, y * game.tile_size, width = game.tile_size, height = game.tile_size)
        # vypiš čísla
        for key, value in game.coordinates_number.items():
            x_center = 0
            x, y = key
            if value < 10:
                x_center = (x + game.tile_size) / 4
            label_number = pyglet.text.Label(f'{value}', font_name = 'Arial', font_size = game.tile_size / 1.6, x = x * game.tile_size + x_center, y = 10 + y * game.tile_size)
            label_number.draw()

    def draw_snake(self):
        if game.state == 'game_over':
            window.pop_handlers()
            # pyglet.clock.unschedule(movement_snake)
        # line under score
        '''
        pyglet.gl.glColor4f(1.0, 1.0, 1.0);  # nastaveni barvy pro kresleni # pyglet.gl.glColor3f(1.0, 1.0, 1.0);
        pyglet.gl.glBegin(pyglet.gl.GL_LINES);  # nyni zacneme vykreslovat body
        pyglet.gl.glVertex2i( 0, window.height - 60);
        pyglet.gl.glVertex2i(window.width,  window.height - 60);
        pyglet.gl.glEnd();
        # draw snake
        pyglet.gl.glEnable(pyglet.gl.GL_BLEND)
        pyglet.gl.glBlendFunc(pyglet.gl.GL_SRC_ALPHA, pyglet.gl.GL_ONE_MINUS_SRC_ALPHA)
        '''
        for a, b, c in zip(['tail'] + self.coordinates, self.coordinates, self.coordinates[1:] + ['head']):
            x, y = b
            move_from = snake_article_calculation(a, b)
            move_to = snake_article_calculation(c, b)
            if move_to == 'head' and not self.alive:
                move_to = 'dead'
            if move_to == 'head' and self.enjoy:
                move_to = 'tongue'
                self.enjoy = False
            self.snake_tiles[move_from + '-' + move_to].blit(x * game.tile_size, y * game.tile_size, width = game.tile_size, height = game.tile_size)
        # draw fruit
        for x, y in game.coordinates_fruit:
            apple_2.blit(x * game.tile_size, y * game.tile_size, width = game.tile_size, height = game.tile_size)

class Game_state(Snake):
    def initialize(self):
        self.tile_size = tile_size  # x * x pixelu - članek hada, jablko
        self.area_size_x = area_size_x  # velikost hřiště
        self.area_size_y = area_size_y
        self.number_of_moves_for_add_apple = number_of_moves_for_add_apple  # po krerych se prida ovoce
        self.current_numbers_of_moves = 0  # celkový počet tahů
        self.state = 'main_screen'  # game_snake, game_snake_2, game_number, game_over, main_screen
        self.coordinates_fruit = [(1, 1)]
        self.coordinates_number = {}
        self.result = None  # integer, výsledek ke hře s čísly
        self.max_number = max_number
        self.label_task = ''
        self.attempts_good = 0
        self.attempts_bad = 0
        self.score = 0
        self.time = time.time()

    def new_number(self):  # výběr příkladů pro hru s čísly
        operator_rand = randrange(1, 5)  # vybere náhodně operátor 1 až 4 pro + - * /
        if operator_rand == 1:  # +
            operator = ' + '
            game.result = randrange(2, game.max_number + 1)
            n1 = game.result - randrange(1, game.result)
            n2 = game.result - n1
        elif operator_rand == 2:  # -
            operator = ' - '
            n1 = randrange(1, game.max_number + 1)
            game.result = n1 - randrange(0, n1 + 1)
            n2 = n1 - game.result
        elif operator_rand == 3:  # *
            operator = ' * '
            while True:
                n1 = randrange(1, game.max_number + 1)
                n2 = randrange(0, game.max_number + 1)
                if (n1 * n2) < game.max_number + 1:
                    break
            game.result = n1 * n2
        elif operator_rand == 4:  # /
            operator = ' / '
            while True:
                n1 = randrange(0, game.max_number + 1)
                n2 = randrange(1, game.max_number + 1)
                if (n1 / n2) < (game.max_number + 1) and (n1 % n2) == 0:
                    break
            game.result = round(n1 / n2)

        self.label_task = str(n1) +  operator + str(n2)
        # přidání čísel k výběru
        game.coordinates_number.clear()
        n = 5  # počet čísel na hrací ploše
        for i in range(n):
            while True:
                x = randrange(0, game.area_size_x)
                y = randrange(0, game.area_size_y)
                if (x, y) not in snake.coordinates:
                    break
            game.coordinates_number[x, y] = randrange(0, game.max_number + 1)
            if i == n - 1:
                game.coordinates_number[x, y] = game.result

    def add_fruit(self):
# zde je použito snake.coordinates na misto self.coordinates - co s tím ???
        if (self.area_size_x * self.area_size_y) - (len(snake.coordinates) + len(snake2.coordinates) + len(self.coordinates_fruit)) > 5:  # je misto pro ovoce ?
            i = 0
            while True:
                i += 1
                if i > 100:  # ať to tady dlouho netrvá - plynulost hry při hledání posledích míst
                    print('                    Nestihl najít, pokusů při hledání místa pro ovoce:', i)
                    break
                n, m = (randrange(0, game.area_size_x), randrange(0, game.area_size_y))
# zde je použito snake.coordinates na misto self.coordinates - co s tím ???
                if (n, m) not in snake.coordinates and (n, m) not in snake2.coordinates and (n, m) not in self.coordinates_fruit:
                    self.coordinates_fruit.append((n, m))
                    break

    def draw_game_over(self):
        label_game_over = pyglet.text.Label(' game over - G pro novou hru', font_name = 'Arial', font_size = 20, x = 2, y = 5)
        label_game_over.draw()

game = Game_state()
game.initialize()

snake = Snake()
snake.direction = (1, 0)
snake.enjoy = False
snake.alive = True
snake.coordinates = [(0, 0), (1, 0), (2, 0)]
snake.speed = speed
TILES_DIRECTORY = Path('snake-tiles')  # načtení souboru s obrázy části hada
for path in TILES_DIRECTORY.glob('*.png'):
    snake.snake_tiles[path.stem] = pyglet.image.load(path)

snake2 = Snake()
snake2.direction = (1, 0)
snake2.enjoy = False
snake2.alive = True
snake2.coordinates = [(0, 3), (1, 3), (2, 3)]
snake2.speed = speed
TILES_DIRECTORY = Path('snake-tiles-2')  # načtení souboru s obrázy části druhého hada
for path in TILES_DIRECTORY.glob('*.png'):
    snake2.snake_tiles[path.stem] = pyglet.image.load(path)

apple_2 = pyglet.image.load('apple.png')

def snake_article_calculation(a, b):
    if a == 'tail' or a == 'head' or a == 'dead': return a
    x, y = a
    x2, y2 = b
    if x == x2 - 1: return 'left'
    elif x == x2 + 1: return 'right'
    elif y == y2 - 1: return 'bottom'
    elif y == y2 + 1: return 'top'

    # x pro kam při pohybu mimo hřiště
    elif x + game.area_size_x - 1 == x2: return 'right'
    # x odkud při pohybu mimo hřiště
    elif x == x2 + game.area_size_x - 1: return 'left'

    # y pro kam při pohybu mimo hřiště
    elif y + game.area_size_y - 1 == y2: return 'top'
    # y odkud při pohybu mimo hřiště
    elif y == y2 + game.area_size_y - 1: return 'bottom'
    return 'error'

def best_score():
    pass

def draw():  # main_screen, game_snake, game_snake_2, game_number, game_over
    # window.set_location(100, 34)
    if game.state == 'main_screen':
        window.clear()
        label_snake.draw()
        label_score = pyglet.text.Label(f' J - hra had', font_name = 'Arial', font_size = 20, x = 20, y = window.height - 40) # Arial
        label_score.draw()
        label_score = pyglet.text.Label(f' D - hra pro dva hráče', font_name = 'Arial', font_size = 20, x = 20, y = window.height - 80)
        label_score.draw()
        label_score = pyglet.text.Label(f' N - hra s čísly', font_name = 'Arial', font_size = 20, x = 20, y = window.height - 120)
        label_score.draw()
    elif game.state == 'game_snake':
        window.clear()
        label_snake.draw()
        snake.draw_snake()
        at = time.time() - game.time
        score = round(300 * (len(snake.coordinates) - 3) / at)
        label_score = pyglet.text.Label(f'Score hada:  {score}', font_name = 'Arial', font_size = 24, x = 20, y = window.height - 40)
        label_score.draw()
    elif game.state == 'game_snake_2':
        window.clear()
        label_snake.draw()
        snake.draw_snake()
        at = time.time() - game.time
        score = round(300 * (len(snake.coordinates) - 3) / at)
        score_2 = round(300 * (len(snake2.coordinates) - 3) / at)
        label_score = pyglet.text.Label(f'Score had1: {score}            had2: {score_2}', font_name = 'Arial', font_size = 24, x = 20, y = window.height - 40)
        label_score.draw()
        snake2.draw_snake()
    elif game.state == 'game_number':
        if not game.result :  # první vytvoření zadání
            game.new_number()
        window.clear()
        snake.draw_snake_number()
    elif game.state == 'game_over':
        game.draw_game_over()
        # window.pop_handlers()

def movement_snake_number(t):
    if not snake.alive:
        game.state = 'game_over'
        pyglet.clock.unschedule(movement_snake_number)
        return
    snake.move_snake_number()
    pyglet.clock.schedule_once(movement_snake_number, snake.speed)

def movement_snake(t):  # hra jeden had
    if not snake.alive:
        game.state = 'game_over'
        pyglet.clock.unschedule(movement_snake)
        return
    pyglet.clock.schedule_once(movement_snake, snake.speed)
    snake.move_snake()
    # přidání ovoce po počtu_tahu
    if game.current_numbers_of_moves % game.number_of_moves_for_add_apple == 0:
        game.add_fruit()
    game.current_numbers_of_moves += 1

def movement_snake_1(t):  # hra dva hadi - had 1
    if not snake.alive or not snake2.alive:
        game.state = 'game_over'
        pyglet.clock.unschedule(movement_snake_1)
        pyglet.clock.unschedule(movement_snake_2)
        return
    snake.move_snake()
    pyglet.clock.schedule_once(movement_snake_1, snake.speed)
    if snake.coordinates[-1] in snake2.coordinates:
        print('První Had kousl do druhého a je ponich.')
        snake.alive = False
    # přidání ovoce po počtu_tahu
    if game.current_numbers_of_moves % game.number_of_moves_for_add_apple == 0:
        game.add_fruit()
    game.current_numbers_of_moves += 1

def movement_snake_2(t):  # hra dva hadi - had 2
    if not snake.alive or not snake2.alive:
        game.state = 'game_over'
        pyglet.clock.unschedule(movement_snake_1)
        pyglet.clock.unschedule(movement_snake_2)
        return
    snake2.move_snake()
    pyglet.clock.schedule_once(movement_snake_2, snake2.speed)
    if snake2.coordinates[-1] in snake.coordinates:
        print('Druhý Had kousl do prvního a je ponich.')
        snake2.alive = False
    # přidání ovoce po počtu_tahu
    if game.current_numbers_of_moves % game.number_of_moves_for_add_apple == 0:
        game.add_fruit()
    game.current_numbers_of_moves += 1

def movement(t):
    if game.state == 'main_screen':
        pass
    if game.state == 'game_snake':
        pyglet.clock.unschedule(movement)
        snake2.coordinates = []
        movement_snake(0.1)
    if game.state == 'game_snake_2':
        pyglet.clock.unschedule(movement)
        movement_snake_1(0.1)
        movement_snake_2(0.1)
    if game.state == 'game_number':
        pyglet.clock.unschedule(movement)
        movement_snake_number(0.5)
    if game.state == 'game_over':
        #window.pop_handlers()
        #pyglet.clock.unschedule(movement_snake)
        #pyglet.clock.unschedule(movement_snake_1)
        #pyglet.clock.unschedule(movement_snake_2)
        pass

def key_press(symbol, modifiers):
    if symbol == pyglet.window.key.UP:
        if snake.direction != (0, -1):
            snake.direction = (0, 1)
    elif symbol == pyglet.window.key.DOWN:
        if snake.direction != (0, 1):
            snake.direction = (0, -1)
    elif symbol == pyglet.window.key.LEFT:
        if snake.direction != (1, 0):
            snake.direction = (-1, 0)
    elif symbol == pyglet.window.key.RIGHT:
        if snake.direction != (-1, 0):
            snake.direction = (1, 0)
    # ovladani pro druheho hada - w, s, a, d - nahoru, dolu, vlevo, vpravo
    if symbol == pyglet.window.key.W:
        if snake2.direction != (0, -1):
            snake2.direction = (0, 1)
    elif symbol == pyglet.window.key.S:
        if snake2.direction != (0, 1):
            snake2.direction = (0, -1)
    elif symbol == pyglet.window.key.A:
        if snake2.direction != (1, 0):
            snake2.direction = (-1, 0)
    elif symbol == pyglet.window.key.D:
        if snake2.direction != (-1, 0):
            snake2.direction = (1, 0)

    if symbol == pyglet.window.key.G and game.state == 'game_over':
        # nastavení na novou hru
        game.state = 'main_screen'
        game.initialize()
        snake.direction = (1, 0)
        snake.enjoy = False
        snake.alive = True
        snake.coordinates = [(0, 0), (1, 0), (2, 0)]
        snake.speed = speed
        snake2.direction = (1, 0)
        snake2.enjoy = False
        snake2.alive = True
        snake2.coordinates = [(0, 3), (1, 3), (2, 3)]
        snake2.speed = speed
        pyglet.clock.schedule_interval(movement, 0.2)

    if symbol == pyglet.window.key.J and game.state == 'main_screen':
        game.state = 'game_snake'
    if symbol == pyglet.window.key.D and game.state == 'main_screen':
        game.state = 'game_snake_2'
    if symbol == pyglet.window.key.N and game.state == 'main_screen':
        game.state = 'game_number'

window = pyglet.window.Window(width = game.area_size_x * game.tile_size, height = game.area_size_y * game.tile_size + 60, caption = 'Snake 2D')
label_snake = pyglet.text.Label(' Snake, neboli Had', font_name = 'Segoe UI', font_size = 50, x = window.width / 5, y = window.height / 2.5) # 'Arial' 'Arial'

window.push_handlers(
    on_draw = draw,  # na vykresleni okna pouzij funkci vykresli
    on_key_press = key_press,  # po stisknuti klavesy zavolej stisk_klavesy
    )

pyglet.clock.schedule_interval(movement, 0.2)

pyglet.app.run()


import cv2
import numpy as np
import matplotlib.pyplot as plt

def find_matches(im1,im2):
    # sift = cv2.SIFT_create()
    # surf = cv2.xfeatures2d.SURF_create()
    sift = cv2.xfeatures2d.SIFT_create()

    kp1, des1 = sift.detectAndCompute(cv2.cvtColor(im1,cv2.COLOR_RGB2GRAY),None)
    kp2, des2 = sift.detectAndCompute(cv2.cvtColor(im2,cv2.COLOR_RGB2GRAY),None)

    # matching features
    BF_Matcher = cv2.BFMatcher()
    initial_matches = BF_Matcher.knnMatch(des1,des2,k=2)

    # ratio test
    good_matches = []
    for m,n in initial_matches:
        if m.distance < 0.75 * n.distance:
            good_matches.append([m])

    return good_matches,kp1,kp2

def find_homography(matches,kp1,kp2):
    if len(matches) < 4:
        exit(0)

    pts1 = []
    pts2 = []

    for match in matches:
        # get matched points from both images
        pts1.append(kp1[match[0].queryIdx].pt)
        pts2.append(kp2[match[0].trainIdx].pt)

    pts1 = np.float32(pts1)
    pts2 = np.float32(pts2)

    (H,status) = cv2.findHomography(pts1,pts2,cv2.RANSAC,4.0)

    return H,status

def update_frame_matrix(H,im1,im2):
    h,w = im2.shape[:2]

    # 1.corners of secondary image:
    # 12
    # 43
    # [[x1,x2,x3,x4],
    # [y1,y2,y3,y4],
    # [1,1,1,1]]

    init_matrix = np.array([[0,w-1,w-1,0],
                            [0,0,h-1,h-1],
                            [1,1,1,1]])

    # 2.finding resulting corners(after transformation)
    # transforming every column by H matrix final_matrix[:,i] = H*init_matrix[:,i]
    final_matrix = np.dot(H,init_matrix)

    [x,y,c] = final_matrix
    x = np.divide(x,c)
    y = np.divide(y,c)

    # find dimensions of transformed corners
    min_x, max_x = int(round(min(x))), int(round(max(x)))
    min_y, max_y = int(round(min(y))), int(round(max(y)))

    new_w = max_x
    new_h = max_y
    correction = [0,0]
    if min_x < 0:
        new_w -= min_x
        correction[0] = abs(min_x)
    if min_y < 0:
        new_h -= min_y
        correction[1] = abs(min_y)

    # finding height and width
    h_base,w_base = im2.shape[:2]
    if new_w < w_base + correction[0]:
        new_w = w_base + correction[0]
    if new_h < h_base + correction[1]:
        new_h = h_base + correction[1]

    x = np.add(x, correction[0])
    y = np.add(y, correction[1])

    old_initial_points = np.float32([[0,0],
                                     [w-1,0],
                                     [w-1,h-1],
                                     [0,h-1]])

    # final points after correction()
    new_final_points = np.float32(np.array([x,y]).transpose())

    homography_matrix = cv2.getPerspectiveTransform(old_initial_points,new_final_points)

    print(homography_matrix)

im1 = cv2.cvtColor(cv2.imread("img/1.jpg"),cv2.COLOR_BGR2RGB)
im2 = cv2.cvtColor(cv2.imread("img/2.jpg"),cv2.COLOR_BGR2RGB)

good_matches, kp1, kp2 = find_matches(im1,im2)
print(f"n good matches:{len(good_matches)}")

H,status = find_homography(good_matches,kp1,kp2)

print(H)

update_frame_matrix(H,im1,im2)


from multiprocessing.sharedctypes import Value
import torch
from generalframeworks.utils import class2one_hot
import numpy as np

class Meter(object):

    def reset(self):
        # Reset the Meter to default settings
        pass

    def add(self, pred_logits, label):
        # Log a new value to the meter
        pass

    def value(self):
        # Get the value of the meter in the current state
        pass

    def summary(self) -> dict:
        raise NotImplementedError

    def detailed_summary(self) -> dict:
        raise NotImplementedError

class ConfMatrix(object):
    def __init__(self, num_classes):
        self.num_classes = num_classes
        self.mat = None

    def update(self, pred, target):
        n = self.num_classes
        if self.mat is None:
            self.mat = torch.zeros((n, n), dtype=torch.int64, device=pred.device)
        with torch.no_grad():
            k = (target >= 0) & (target < n)
            inds = n * target[k].to(torch.int64) + pred[k]
            self.mat += torch.bincount(inds, minlength=n**2).reshape(n, n)

    def get_metrics(self):
        h = self.mat.float()
        acc = torch.diag(h).sum() / h.sum()
        up = torch.diag(h)
        down = h.sum(1) + h.sum(0) - torch.diag(h)
        iu = torch.diag(h) / (h.sum(1) + h.sum(0) - torch.diag(h) + 1e-6)
        return torch.mean(iu).item(), acc.item()

    def get_valid_metrics(self):
        h = self.mat.float()
        acc = torch.diag(h).sum() / h.sum()
        up = torch.diag(h)
        down = h.sum(1) + h.sum(0) - torch.diag(h)
        iu = torch.diag(h) / (h.sum(1) + h.sum(0) - torch.diag(h) + 1e-6)
        num_no_zero = (iu == 0).sum()
        return iu.sum() / (len(iu) - num_no_zero).item(), acc.item()

class My_ConfMatrix(Meter):
    def __init__(self, num_classes):
        super(ConfMatrix, self).__init__()
        self.num_classes = num_classes
        self.mat = None
        self.reset()
        self.mIOU = []
        self.Acc = []

    def add(self, pred_logits, label):
        pred_logits = pred_logits.argmax(1).flatten()
        label = label.flatten()
        n = self.num_classes
        if self.mat is None:
            self.mat = torch.zeros((n, n), dtype=torch.int64, device=pred_logits.device)
        with torch.no_grad():
            k = (label >= 0) & (label < n)
            inds = n * label[k].to(torch.int64) + pred_logits[k]
            self.mat += torch.bincount(inds, minlength=n ** 2).reshape(n, n)

    def value(self, mode='mean'):
        h = self.mat.float()
        self.acc = torch.diag(h).sum() / h.sum()
        self.iu = torch.diag(h) / (h.sum(1) + h.sum(0) - torch.diag(h))
        if mode == 'mean':
            return torch.mean(self.iu).item(), self.acc.item()
        else:
            raise ValueError("mode must be in (mean)")

    def reset(self):
        self.mIOU = []
        self.Acc = []

    def summary(self) -> dict:
        mIOU_dct: dict = {}
        Acc_dct: dict = {}
        for c in range(self.num_classes):
            if c != 0:
                mIOU_dct['mIOU_{}'.format(c)] = np.array([self.value(i, mode='all')[0] for i in range(len(self.mIOU))])[
                                                :, c].mean()
                Acc_dct['Acc_{}'.format(c)] = np.array([self.value(i, mode='all')[1] for i in range(len(self.mIOU))])[:,
                                              c].mean()
        return mIOU_dct, Acc_dct


"""
Takes an apache log file and converts it to a dataframe (msgpack) for reporting.

Author: Thomas Johns @t0mj
"""
import argparse
import pandas as pd
import os
import re

# Read Chunk Function - Convert chunk to msg
def parse_log_file(log_file, chunks):
    path, input_file = os.path.split(log_file)
    # Safely create the output file
    if '.log' in input_file:
        output_file = path + input_file.replace('.log', '.msg')
    else:
        output_file = path + input_file + '.msg'
    data_list = []
    with open(input_file) as f:
        for line in f:
            # Get a tuple of the cleaned up record
            clean_line = parse_line(line)
            # Add it to the list in memory for converting to msgpack
            data_list.append(clean_line)
            if len(data_list) == chunks:
                # Once we reach our chunk limit, convert to msgpack
                convert_chunk_to_msgpack(data_list, output_file)
                data_list = []
        if data_list:
            # Get the final chunk if there is one
            convert_chunk_to_msgpack(data_list, output_file)

    print(f'Dataframe created and located at {output_file}')

# Convert chunk to msgpack
def convert_chunk_to_msgpack(data_list, output_file):
    # Our dataframe labels
    labels = ['ip', 'unused', 'user_id', 'datetime', 'request_method', 'resource', 'protocol',
              'status', 'return_size']
    df = pd.DataFrame.from_records(data_list, columns=labels)
    # Remove unused column
    df.drop('unused', axis=1, inplace=True)
    # Change data types
    df[['status', 'return_size']] = df[['status', 'return_size']].apply(pd.to_numeric)
    df.to_msgpack(output_file, append=True)

# Parsing function - clean up lines
def parse_line(line):
    regex = '^(\S+) (\S+) (\S+) \[([\w:/]+\s[+\-]\d{4})\] "(\S+)\s?(\S+)?\s?(\S+)?" (\d{3}|-) (\d+|-)\s?'
    return re.match(regex, line).groups()

if __name__ == "__main__":
    parser = argparse.ArgumentParser(description='Takes an apache access log file and creates'
                                                 'a dataframe for reports.')
    parser.add_argument('log_file', help='The apache log file.')
    parser.add_argument('--chunks', default=2000, type=int,
                        help='The number of lines to chunk during dataframe creation.')
    args = vars(parser.parse_args())
    if not any(args.values()):
        parser.error('No arguments provided.')

    parse_log_file(**args)


from itertools import cycle
from typing import Tuple, List, Optional, Union, Any, Sequence

import numpy as np
import torch
import torch.utils.data
import torchvision
from torch import nn
from torchvision import transforms

"""
Датасеты могут быть двух типов:
1. Элемент - число или тензор. В этом случае элемент рассматривается как x в GAN
2. Элемент - tuple длины 2. В этом случае 1-ый элемент tuple - x, 2-й - y (условие)
y - либо число, либо тензор, либо tuple с числами/тензорами

Обёртка в виде UnifiedDatasetWrapper приводит оба типа датасетов ко 2-му (для датасета 1-го типа y = None).
Обёртку следует использовать пользователю.
"""

class RandomDataloader(torch.utils.data.DataLoader):
    def __init__(self, dataset: torch.utils.data.Dataset, batch_size: int, *args, **kwargs):
        sampler = torch.utils.data.sampler.RandomSampler(dataset, replacement=True)
        random_sampler = torch.utils.data.sampler.BatchSampler(sampler, batch_size=batch_size,
                                                               drop_last=False)

        super().__init__(dataset, batch_sampler=random_sampler, *args, **kwargs)

def get_random_infinite_dataloader(dataset: torch.utils.data.Dataset, batch_size: int, *args, **kwargs):
    return cycle(RandomDataloader(dataset, batch_size=batch_size, *args, **kwargs))

def collate_fn(els_list: Sequence[Union[Tuple, int, torch.Tensor]]):
    if isinstance(els_list[0], tuple):
        return tuple(collate_fn(list(a)) for a in zip(*els_list))
    elif isinstance(els_list[0], int):
        return torch.Tensor(els_list)
    elif isinstance(els_list[0], torch.Tensor):
        return torch.stack(tuple(els_list))
    elif els_list[0] is None:
        return None
    else:
        raise RuntimeError

def stack_batches(batches_list):
    if isinstance(batches_list[0], tuple):
        return tuple(stack_batches(list(a)) for a in zip(*batches_list))
    elif isinstance(batches_list[0], torch.Tensor):
        return torch.concat(batches_list, dim=0)
    elif batches_list[0] is None:
        return None

def move_batch_to(batch, device):
    if isinstance(batch, tuple):
        return tuple(move_batch_to(subbatch, device) for subbatch in batch)
    elif batch is None:
        return None
    else:
        return batch.to(device)

class LinearTransform(nn.Module):
    def __init__(self, min_to: float, max_to: float, dim: int) -> None:
        super().__init__()
        self.min_to = min_to
        self.max_to = max_to
        self.dim = dim

    def forward(self, X) -> torch.Tensor:
        mins = X.min(dim=self.dim).values
        maxs = X.max(dim=self.dim).values

        coefs = (self.max_to - self.min_to) / (maxs - mins)
        biases = self.min_to - coefs * mins

        shape = list(X.shape)
        shape[self.dim] = 1

        coefs = coefs.reshape(*shape)
        biases = biases.reshape(*shape)

        y = coefs * X + biases
        y = torch.clip(y, self.min_to, self.max_to)  # clipping for making sure

        return y

class ExtractIndicesDataset(torch.utils.data.Dataset):
    def __init__(self, dataset, indices: Union[Tuple[int], int]):
        self.dataset = dataset
        self.indices = indices

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

    def __getitem__(self, n: int):
        obj = self.dataset[n]
        if isinstance(self.indices, int):
            return obj[self.indices]
        else:
            return tuple(obj[i] for i in self.indices)

class UnifiedDatasetWrapper(torch.utils.data.Dataset):
    """
    Обёртка для поддержки датасетов обоих типов
    """
    def __init__(self, dataset: torch.utils.data.Dataset):
        self.dataset = dataset
        self.inverse_transform = getattr(dataset, 'inverse_transform', None)

    def __len__(self) -> int:
        return len(self.dataset)

    def __getitem__(self, n: int) -> Tuple[Any, Any]:
        element = self.dataset[n]
        if isinstance(element, tuple):
            assert len(element) == 2
            x, y = element
        else:
            x, y = element, None
        return x, y

def get_default_image_transform(dim: int) -> transforms.Compose:
    return transforms.Compose([
        transforms.ToTensor(),
        # Переводим цвета пикселей в отрезок [-1, 1] афинным преобразованием, изначально они в отрезке [0, 1]
        transforms.Normalize(tuple(0.5 for _ in range(dim)), tuple(0.5 for _ in range(dim)))
    ])

default_image_transform = get_default_image_transform(3)

def get_cifar_10_dataset(root='./cifar10', train: bool = True, keep_labels: bool = True, kept_labels: Optional[List[int]] = None):
    """
    :param kept_labels: images with which labels should be used
    """
    cifar_dataset = torchvision.datasets.CIFAR10(root=root, train=train, download=True,
                                                 transform=default_image_transform, )

    if kept_labels is not None:
        kept_indices = []
        for i in range(len(cifar_dataset)):
            if cifar_dataset[i][1] in kept_labels:
                kept_indices.append(i)

        cifar_dataset = torch.utils.data.Subset(cifar_dataset, kept_indices)

    if not keep_labels:
        cifar_dataset = ExtractIndicesDataset(cifar_dataset, indices=0)
    return cifar_dataset

def get_mnist_dataset(root='./mnist', train: bool = True, keep_labels: bool = True):
    mnist_dataset = torchvision.datasets.MNIST(root=root, train=train, download=True,
                                               transform=get_default_image_transform(1))

    if not keep_labels:
        mnist_dataset = ExtractIndicesDataset(mnist_dataset, indices=0)
    return mnist_dataset

class PhysicsDataset(torch.utils.data.Dataset):
    """
    one element: (energy deposit, (point, momentum))
    """
    def __init__(self, energy: torch.Tensor, point: torch.Tensor, momentum: torch.Tensor,
                 transform=None, inverse_transform=None) -> None:
        """
        TODO: указать сигнатуры transform и inverse_transform через typing
        transform(energy, point, momentum) - tensors as batches or single
        inverse_transform(energy, point, momentum)
        """
        self.transform = transform
        self.inverse_transform = inverse_transform  # for outer use

        if transform is not None:
            energy = self.transform(energy)

        self.energy = energy
        self.point = point
        self.momentum = momentum

    def __getitem__(self, idx: int) -> tuple:
        return self.energy[idx], (self.point[idx], self.momentum[idx])

    def __len__(self) -> int:
        return self.energy.shape[0]

# принимают batch-и x-ов
def log1p_transform(x: torch.Tensor):
    return torch.log1p(x)

def log1p_inverse_transform(x: torch.Tensor):
    return torch.expm1(x)

def get_physics_dataset(path: str, train: bool = True, val_ratio: float = 0.5,
                        log1p_energy: bool = True) -> torch.utils.data.Dataset:
    TRAIN_VAL_SPLIT_SEED = 0x3df3fa

    data_train = np.load(path)

    np.random.seed(TRAIN_VAL_SPLIT_SEED)
    dataset_size = len(data_train['EnergyDeposit'])
    val_size = int(dataset_size * val_ratio)

    all_indices = np.arange(dataset_size)
    val_indices = np.random.choice(all_indices, size=val_size, replace=False)
    val_mask = np.zeros(dataset_size, dtype=bool)
    val_mask[val_indices] = True
    train_indices = all_indices[~val_mask]
    indices = train_indices if train else val_indices

    energy = torch.tensor(data_train['EnergyDeposit'][indices]).float()
    energy = torch.permute(energy, dims=(0, 3, 1, 2))
    point = torch.tensor(data_train['ParticlePoint'][:, :2][indices]).float()
    momentum = torch.tensor(data_train['ParticleMomentum'][indices]).float()

    transform, inverse_transform = None, None
    if log1p_energy:
        transform = log1p_transform
        inverse_transform = log1p_inverse_transform

    return PhysicsDataset(energy, point, momentum,
                          transform=transform, inverse_transform=inverse_transform)


import sim
import logging
from models.properties import *
import re

def print_header():
    header = [
    "   _____                     _  _____              ________      __   _____       _                ",
    "  / ____|                   | |/ ____|            |  ____\ \    / /  / ____|     | |               ",
    " | |     __ _ _ __ ___   ___| | |    _   _ _ __   | |__   \ \  / /  | (___   ___ | |_   _____ _ __ ",
    " | |    / _` | '_ ` _ \ / _ \ | |   | | | | '_ \  |  __|   \ \/ /    \___ \ / _ \| \ \ / / _ \ '__|",
    " | |___| (_| | | | | | |  __/ | |___| |_| | |_) | | |____   \  /     ____) | (_) | |\ V /  __/ |   ",
    "  \_____\__,_|_| |_| |_|\___|_|\_____\__,_| .__/  |______|   \/     |_____/ \___/|_| \_/ \___|_|   ",
    "                                          | |                                                      ",
    "                                          |_|                                                      "
    ]
    print(*header, sep = "\n")

def get_user_input():
    user_input = input("Enter camel positions:")
    tokens = user_input.split(" ")
    tokens.reverse()

    if len(tokens) != 5:
        print("invalid input")
        return False

    char_mapping = {"B": Color.BLUE, "G": Color.GREEN, "O": Color.ORANGE, "Y": Color.YELLOW, "W": Color.WHITE}
    pos_dict = {}
    color_list = []
    for t in tokens:
        try:
            camel = char_mapping[t[0]]
            pos = int(re.findall(r'\d+', t)[0])
            if t[-1] != 'x':
                color_list.append(camel)

            if pos in pos_dict:
                pos_dict[pos].append(camel)
            else:
                pos_dict[pos] = [camel]

        except Exception as e:
            print("You mostly likely entered something wrong... please try again")
            return False

    return color_list, pos_dict

if __name__ == "__main__":
    logging.basicConfig(level=logging.INFO)

    # # List of camels that can still move this round
    color_list = [Color.GREEN, Color.BLUE, Color.ORANGE, Color.WHITE, Color.YELLOW]
    # # Dict of camel positions
    pos_dict = {10: [Color.GREEN, Color.ORANGE], 11: [Color.BLUE], 13:[Color.YELLOW], 15:[Color.WHITE]}
    # # Dict of modifier locations
    mod_dict = {14: {TileMod.BOOST}, 12: {TileMod.BOOST}}

    print_header()

    print("Input format: \"[Color][Pos][Cannot Move] [Color][Pos][Cannot Move] .... \"")
    # color_list, pos_dict = getUserInput()
    # mod_dict = {}

    rs = sim.RoundSimulator(color_list, pos_dict, mod_dict)
    rs.print_board()
    probabilities = rs.sim_round()
    evs = rs.calculate_ev()

    print(probabilities)
    print(evs)


# ---
# jupyter:
#   jupytext:
#     formats: ipynb,py
#     text_representation:
#       extension: .py
#       format_name: light
#       format_version: '1.5'
#       jupytext_version: 1.3.3
#   kernelspec:
#     display_name: Python 3
#     language: python
#     name: python3
# ---

# %load_ext autoreload
# %autoreload 2

# +
import pandas as pd

from torchvision import transforms

from hw_grapheme.predict_utils import bengali_predict
from hw_grapheme.model import EfficientNet_0

# +
test_data_paths = [
     '../data/train_image_data_0.parquet',
     '../data/train_image_data_2.parquet',
#     '../data/test_image_data_0.parquet',
#     '../data/test_image_data_1.parquet',
#     '../data/test_image_data_2.parquet',
#     '../data/test_image_data_3.parquet'
]

model_archs_weights = [
    (EfficientNet_0, "../model_weights/eff_0_with_mixup_cutmix/fold_0/eff_0_high_acc.pth"),
    (EfficientNet_0, "../model_weights/eff_0_with_mixup_cutmix/fold_2/eff_0_high_acc.pth"),
]

transforms = transforms.Compose([
    transforms.ToPILImage(),
    transforms.Grayscale(num_output_channels=3),
    transforms.ToTensor(),
    # transforms.Normalize([0.0692], [0.2051])
])
# -

result = bengali_predict(
    test_data_paths, model_archs_weights, transforms,
    batch_size=128, n_workers=2
)

result

sub_df = pd.DataFrame({'row_id': result[0], 'target': result[1]})
#sub_df.to_csv('submission.csv', index=False)

sub_df


#!/usr/bin/env python3
# coding:utf-8
import os
from django.http import HttpResponse
import json
from src.lib import db_mysql,django_api

mysql_conn = db_mysql.MyPymysqlPool()

def get_ram_userinfo(request):
    userinfo_list = []
    ram_result_dict = {}
    ram_body_dict = {}
    success = False
    code = 500
    message = ''

    try:
        page = int(request.GET['page'])
        limit = int(request.GET['limit'])
    except Exception as e:
        print("%s:未传入page或limit，使用默认值" % e)
        page = 1
        limit = 10

    try:
        username = str(request.GET['username'])
    except Exception as e:
        print("%s:未传入username，使用默认值" % e)
        username = ''

    django_api.DjangoApi().os_environ_update()
    offset = (page - 1) * limit  # （当前页数-1）*每页数量 = 每页的开始位置

    # 获取表数据总条数
    try:
        sql_count = "select count(id) from %s ;" % ('ram_user_info')
        total_count = int(mysql_conn.select(sql_count)[0][0])
    except Exception as e:
        print("%s:表数据为空，使用默认值" % e)
        total_count = 0

    if total_count > 0:
        try:
            # 执行查询表数据
            sql_cmd = "select * from %s where username like '%%%s%%' order by username limit %s,%s" % \
                      ('ram_user_info', username, offset, limit)
            result = mysql_conn.select(sql_cmd)
        except Exception as e:
            print("%s:查询数据失败" % e)
            pass
        else:
            # 循环赋值，定义列表
            for record in result:
                username = record[1]
                login_enable = record[2]
                try:
                    lastlogin_time = record[3].strftime("%Y-%m-%d %H:%M:%S")
                except Exception as e:
                    print("%s:未获取到用户最后登录时间" % e)
                    lastlogin_time = ''
                policies_info = record[4]
                ak_info = record[5]

                single_userinfo = dict()
                single_userinfo['username'] = username
                single_userinfo['login_enable'] = login_enable
                single_userinfo['lastlogin_time'] = lastlogin_time
                single_userinfo['policies_info'] = policies_info
                single_userinfo['ak_info'] = ak_info

                userinfo_list.append(single_userinfo)
            code = 200
            success = True
            message = 'ok'
    ram_body_dict['data'] = userinfo_list
    ram_body_dict['count'] = total_count

    ram_result_dict['code'] = code
    ram_result_dict['success'] = success
    ram_result_dict['message'] = message
    ram_result_dict['body'] = ram_body_dict
    ram_result_json = json.dumps(ram_result_dict, ensure_ascii=False)

    print(ram_result_json)
    return HttpResponse(ram_result_json, content_type="application/json,charset=utf-8")

if __name__ == "__main__":
    get_ram_userinfo('xxx')


import os
import sys
import configparser
import yaml

#### Set up the system interface
sys.path.append(os.path.join("..", "ModelsAPI"))
from src.models import models
from src.experiments.TSE import TSE

if __name__ == "__main__":
    path_config = configparser.ConfigParser()
    path_config.read('path_config.cfg')

    if len(sys.argv) != 2:
        print('Did not pass in run_config file')
        sys.exit(1)
    else:
        run_config_fname = sys.argv[1]

    with open(run_config_fname, 'r') as f:
        run_config = yaml.load(f, Loader=yaml.FullLoader)

    #add paths to run_config
    run_config['nc_path'] = path_config['libraries']['neural-complexity']

    ################
    # Get Results
    ################
    if run_config['run'] == 'results':

        #load models
        print('Loading models...')
        LMs = models.load_models(run_config)

        #Run experiments
        for exp_name in run_config['exp']:
            #Set experiment
            fname = ''

            if exp_name == 'Chow_1':

                fname = 'stimuli/Chow_Exp1.csv'

            elif exp_name == 'Nicol':
                fname = 'stimuli/Nicol_Exp.csv'

            elif exp_name == 'vanGompel_1':
                fname = 'stimuli/vanGompel_Liversedge_Exp1.csv'

            elif exp_name == 'Kush_Dillon_1':
                fname = 'stimuli/Kush_Dillon_Exp1.csv'

            elif exp_name == 'Kush_Dillon_2':
                fname = 'stimuli/Kush_Dillon_Exp2.csv'

            print(f"Running {exp_name}...")

            assert fname != ''
            exp = TSE(fname)

            #Load experiment and wildcards
            exp.load_experiment()

            #Set sent to write type (e.g., the [MASK] is happy vs. the )
            if run_config['model_type'] == 'bert':
                exp.dataframe['sent'] = exp.dataframe['mask_sents']
            elif run_config['model_type'] in {'auto', 'lstm'}:
                exp.dataframe['sent'] = exp.dataframe['auto_sents']

            #Run models
            for LM in LMs:
                print(LM)
                exp.get_targeted_results(LM, return_type = 'surp')

            #Save output
            outname = 'results/'+fname.split('/')[-1].split('.csv')[0]+'_'+run_config['model_type']+'.csv'
            print(f"Saving to {outname}....")
            exp.save(outname)


from django.shortcuts import render, get_object_or_404 ,redirect
from django.utils import timezone
from .models import Post , Comment , Fungo , CsvFile
from .forms import PostForm , CommentForm , FungoForm , CsvFileForm
from django.contrib.auth.decorators import login_required

def post_list(request):
    posts = Post.objects.filter(published_date__lte=timezone.now()).order_by('published_date')
    return render(request, 'blog/post_list.html', {'posts': posts})

def post_detail(request, pk):
    post = get_object_or_404(Post, pk=pk)
    return render(request, 'blog/post_detail.html', {'post': post})

def post_new(request):
    if request.method == "POST":
        form = PostForm(request.POST)
        if form.is_valid():
            post = form.save(commit=False)
            post.author = request.user
            #post.published_date = timezone.now()
            post.save()
            return redirect('post_detail', pk=post.pk)
    else:
        form = PostForm()
    return render(request, 'blog/post_edit.html', {'form': form})

def post_edit(request, pk):
    post = get_object_or_404(Post, pk=pk)
    if request.method == "POST":
        form = PostForm(request.POST, instance=post)
        if form.is_valid():
            post = form.save(commit=False)
            post.author = request.user
            #post.published_date = timezone.now()
            post.save()
            return redirect('post_detail', pk=post.pk)
    else:
        form = PostForm(instance=post)
    return render(request, 'blog/post_edit.html', {'form': form})

def post_draft_list(request):
    posts = Post.objects.filter(published_date__isnull=True).order_by('created_date')
    return render(request, 'blog/post_draft_list.html', {'posts': posts})

def publish(self):
    self.published_date = timezone.now()
    self.save()

def post_publish(request, pk):
    post = get_object_or_404(Post, pk=pk)
    post.publish()
    return redirect('post_detail', pk=pk)

def post_remove(request, pk):
    post = get_object_or_404(Post, pk=pk)
    post.delete()
    return redirect('post_list')

def add_comment_to_post(request, pk):
    post = get_object_or_404(Post, pk=pk)
    if request.method == "POST":
        form = CommentForm(request.POST)
        if form.is_valid():
            comment = form.save(commit=False)
            comment.post = post
            comment.save()
            return redirect('post_detail', pk=post.pk)
    else:
        form = CommentForm()
    return render(request, 'blog/add_comment_to_post.html', {'form': form})

@login_required
def comment_approve(request, pk):
    comment = get_object_or_404(Comment, pk=pk)
    comment.approve()
    return redirect('post_detail', pk=comment.post.pk)

@login_required
def comment_remove(request, pk):
    comment = get_object_or_404(Comment, pk=pk)
    comment.delete()
    return redirect('post_detail', pk=comment.post.pk)

#############################################################################################

def fungo_list(request):
    fungos = Fungo.objects.filter().order_by('specie_genere')
    return render(request, 'blog/fungo_list.html', {'fungos': fungos})

def fungo_remove(request, pk):
    fungo = get_object_or_404(Fungo, pk=pk)
    fungo.delete()
    return redirect('fungo_list')

def fungo_new(request):
    if request.method == "POST":
        form = FungoForm(request.POST)
        if form.is_valid():
            fungo = form.save(commit=False)
            fungo.save()
            return redirect('fungo_list')#, pk=fungo.pk)
    else:
        form = FungoForm()
    return render(request, 'blog/fungo_edit.html', {'form': form})

def fungo_edit(request, pk):
    fungo = get_object_or_404(Fungo, pk=pk)
    if request.method == "POST":
        form = FungoForm(request.POST, instance=fungo)
        if form.is_valid():
            fungo = form.save(commit=False)
            fungo.save()
            return redirect('fungo_list' )#, pk=fungo.pk)
    else:
        form = FungoForm(instance=fungo)
    return render(request, 'blog/fungo_edit.html', {'form': form})

def fungo_detail(request, pk):
    fungo = get_object_or_404(Fungo, pk=pk)
    return render(request, 'blog/fungo_detail.html', {'post': post})

##############################################################################

####################        CSV Uploader

def csv_file_new(request):
    if request.method == "POST":
        form = CsvFileForm(request.POST)
        if form.is_valid():
            csv_file = form.save(commit=False)
            csv_file.save()
            return redirect('fungo_list')
    else:
        form = CsvFileForm()
    return render(request, 'blog/csv_file_edit.html', {'form': form})

def csv_file_edit(request, pk):
    csv_file = get_object_or_404(CsvFile, pk=pk)
    if request.method == "POST":
        form = CsvFileForm(request.POST, instance=csv_file)
        if form.is_valid():
            csv_file = form.save(commit=False)
            csv_file.save()
            return redirect('fungo_list' )
    else:
        form = CsvFileForm(instance=csv_file)
    return render(request, 'blog/csv_file_edit.html', {'form': form})


from skimage.io import imread, imsave
from scipy.cluster.vq import kmeans2
import skimage.filters
from matplotlib import cm
from mpl_toolkits.mplot3d import axes3d
from scipy import ndimage
import scipy.ndimage
import matplotlib.pyplot as plt
import numpy as np
import maxflow
from numpy import random
from kmeans import K_Means

def computeNormalizedImage(im, display_distribution=False):
    im_norm = np.linalg.norm(im, axis=-1)[..., np.newaxis]
    im_intensity_normalized = im / im_norm
    if display_distribution:
        # display the disribution of normalized color, should be on the unity sphere
        points = im_intensity_normalized.reshape(-1, 3)
        fig = plt.figure(figsize=(8, 8))
        ax = fig.add_subplot(111, projection='3d')
        ax.scatter(points[::100, 0], points[::100, 1],
                   points[::100, 2], c=points[::100, :])
        ax.set_xlabel('red')
        ax.set_ylabel('green')
        ax.set_zlabel('blue')
        ax.set_xlim([0, 1])
        ax.set_ylim([0, 1])
        ax.set_zlim([0, 1])
        plt.show()
    return im_intensity_normalized

def displayLabelsImage(imlabels):
    # Displaying the labels image
    colormap = np.array([[250, 250, 0], [0, 0, 200], [
                        0, 200, 0], [200, 0, 0]], dtype=np.uint8)
    imlabelsColors = colormap[imlabels, :]
    plt.figure()
    plt.imshow(imlabelsColors)
    plt.show()

def clustersLabels(clusters, pts):
    labels = np.zeros(len(pts), dtype=np.uint8)
    for clusterId, cluster in enumerate(clusters):
            labels[cluster] = clusterId
    return labels

# TODO
# Define your own kmeans function
def kmeans(X):
    model = K_Means()
    model.fit(X)

    for centroid in model.centroids:
        plt.scatter(model.centroids[centroid][0], model.centroids[centroid][1],
                    marker="o", color="k", s=150, linewidths=5)

    label = clustersLabels(model.classifications,X)
    return centroid, label

def imageKmeans(im_intensity_normalized, nb_clusters):
    # from the image, create a vector of point colors of size N by 3 with N the number of pixels in the image
    # and you can call the function kmeans2 from scipy.cluster.vq before defining your own kmeans function
    # retrive both the centers and the labels from this function
    # reshape the labels to have the size of the image to get an image called imlabels
    H = im_intensity_normalized.shape[0]
    W = im_intensity_normalized.shape[1]
    points = im_intensity_normalized.reshape(-1, 3)
    pixels = im_intensity_normalized.reshape((H*W,3))
    means, imlabels = scipy.cluster.vq.kmeans2(pixels, nb_clusters)
    point_labels = np.array([imlabels[point_idx] for point_idx in range(points.shape[0])])
    img_labels = np.reshape(point_labels, im_intensity_normalized.shape[:2])
    means2, label = kmeans(pixels)
    return img_labels, means

def displayUnaryLabelCosts(Costs):
    plt.figure()
    # TODO : improve this part to be more general
    for i in range(4):
        plt.subplot(2, 2, i+1)
        plt.imshow(Costs, cmap=plt.cm.Greys_r)

def unaryLabelCosts(im_intensity_normalized, mean_colors):
    # TODO
    # given a matrix of color of size N by 3
    # Compute an array Costs of size H by W by nb_clusters
    # such that Costs[i,j,k]= norm(im[i,j,:]-colors[:,k])**2
    # you can avoid loops by using numpy broadcasting
    # http://docs.scipy.org/doc/numpy/user/basics.broadcasting.html
    H = im_intensity_normalized.shape[0]
    W = im_intensity_normalized.shape[1]
    #Costs = np.array([H,W,4])
    # Solution without broadcasting:
    '''
    for i in range(H):
        for j in range(W):
            for k in range(4):
                Costs = np.linalg.norm(im_intensity_normalized[i,j,:] - mean_colors[k,:])
    '''
    # Solution using broadcasting:
    # we create first an array of size H x W x 1 x 3 from an array of size H x W x 3 using [:,:,None,:] to create a new axis of size one
    # then we can substract an array of size K x 3 from an array of size H x W x 1 x 3 using broadcasting
    # to get an array of size H x W x K x 3 and we sum the square along the last dimension
    Costs = np.linalg.norm(im_intensity_normalized[:, :, np.newaxis, :] - mean_colors, axis=-1) ** 2
    return Costs

def graphCutSegment(costs_class0, costs_class1, imlabelsBinary):

    H = costs_class0.shape[0]
    W = costs_class0.shape[1]
    nbpixels = H*W

    # -----------------------Segmentation method using regional data term and constant edge cost-------------------------------

    g = maxflow.Graph[float](nbpixels, nbpixels * 2)

    # TODO
    # encode unary term of the energy shown in those slides of graph-cut (i.e., sum_p Dp(lp) +sum_pq Vqp(lq,lp))
    # by adding arcs in the graph by calling the function g.add_tweights_vectorized
    # this function allows to add arcs between nodes and the source node s and a the sink node t (oriented as source->node and node->target)
    # g.add_tweights_vectorized(indices_nodes,costs_arcs_from_s_to_nodes,costs_arcs_from_nodes_to_t)
    # with indices_nodes,costs_arcs_from_s_to_nodes,costs_arcs_from_nodes_to_t vector whose lenght is the number of pixels
    # WARNING, in the contrary to the slide  24 , the pymaxflow code seems to use the convention
    # that s is in the set of node with labels 0 and t is in the set of node with labels 1
    # look at the graph slide 24 to see how to go from Dp(0) and Dp(1) to the arc weights keeping
    # in mind that pymaxflow use a opposite convention
    # make sure that indices_nodes,costs_arcs_to_s and costs_arcs_to_t are vectors of the same size
    # otherwise will get an assertion error
    # Note :the unvectorized version is documented in the graph.h file un pymaxflow

    indices = g.add_node(nbpixels)
    costs_arcs_from_s_to_nodes = costs_class0
    costs_arcs_from_nodes_to_t = costs_class1
    g.add_tweights_vectorized(indices.astype(np.int32), costs_arcs_from_s_to_nodes.astype(
        np.float32), costs_arcs_from_nodes_to_t.astype(np.float32))

    # We check that the minimization of this energy without extra node gives back the same labels as imlabelsBinary
    print("calling maxflow")
    g.maxflow()
    out = g.what_segment_vectorized()
    imlabels2 = out.reshape((H, W))
    assert(np.all(imlabelsBinary == imlabels2))

    # TODO
    # encode binary terms of the energy in slide 25 (sum_p Dp(fp) +sum_pq Vqp(fq,fp))
    # by considering first horizontal edges between neighboring pixels then vertical edges
    # you  add oriented arcs in the graph between nodes by calling the function g.add_edge_vectorized
    # g.add_edge_vectorized(indices_node_i,indices_node_j,weight_arc_i_to_j,weight_arc_j_to_i)
    # in our case we use weight_arc_i_to_j=weight_arc_i_to_j=alpha
    # first create a matrix indices = np.arange(nbpixels) .reshape(H,W) an use
    # then use submaxtrices extracted from  indices then flattened to create indices_node_i and indices_node_j
    # Note : you can have a look on the example in test.py in the pymaxflow directory

    alpha = 0.1

    # ------ adding horizontal edges------
    indices = np.arange(nbpixels).reshape(H, W).astype(np.int32)
    indices_node_i = indices[:, :-1].ravel()
    indices_node_j = indices[:, 1:].ravel()
    cost_diff = alpha
    g.add_edge_vectorized(indices_node_i, indices_node_j, cost_diff, cost_diff)

    # ------ adding vertical edges------
    indices_node_i = indices[1:, :-1].ravel()
    indices_node_j = indices[:-1, 1:].ravel()
    g.add_edge_vectorized(indices_node_i, indices_node_j, cost_diff, cost_diff)

    # Getting the result image
    print("calling maxflow")
    g.maxflow()
    out = g.what_segment_vectorized()

    imlabelsGC = out.reshape((H, W))
    return imlabelsGC

def main():
    im = np.array(imread('tiger.png')).astype(np.float)
    H=im.shape[0]
    W=im.shape[1]
    nbpixels=H*W
    im_intensity_normalized=computeNormalizedImage(im,display_distribution=True)
    nb_clusters=4
    random.seed((1000,2000))# make sure the kmean call is repeatable to check correctness of te code
    imlabels,mean_colors=imageKmeans(im_intensity_normalized,nb_clusters =nb_clusters)
    displayLabelsImage(imlabels)
    Costs=unaryLabelCosts(im_intensity_normalized,mean_colors)
    displayUnaryLabelCosts(Costs)
    # retrive the class that is the most   represented in the center region of the image
    classSegment=np.argmax(np.bincount(imlabels[100:150,150:250].flat))

    # New cost using only two classes by grouping all other classes into a single class ,
    # we take the minium of the cost in the set of other classes to get the unary cost for new
    # aggregated class
    otherClasses=[i for i in range(nb_clusters) if i!=classSegment ]
    costs_class0=Costs[:,:,classSegment]
    costs_class1=np.min(Costs[:,:,otherClasses],axis=2)
    plt.figure()
    plt.subplot(1,2,1)
    plt.imshow(costs_class0,cmap=plt.cm.Greys_r)
    plt.subplot(1,2,2)
    plt.imshow(costs_class1,cmap=plt.cm.Greys_r)
    imlabelsBinary=imlabels!=classSegment
    imlabelsGC=graphCutSegment(costs_class0,costs_class1,imlabelsBinary)
    displayLabelsImage(imlabelsGC)

if __name__ == "__main__":
    main()