import io
import sys
import os
import traceback
import asyncio
from pyrogram import filters, enums
from misskaty import app
from misskaty.vars import COMMAND_HANDLER, SUDO

__MODULE__ = "DevCommand"
__HELP__ = """
**For Owner Bot Only.**
/run [args] - Run eval CMD
/shell [args] - Run Exec/Terminal CMD
/download [link/reply_to_telegram_file] - Download file from Telegram

**For Public Use**
/json - Send structure message Telegram in JSON using Pyrogram Style.
"""

@app.on_message(filters.command(["logs"], COMMAND_HANDLER) & filters.user(SUDO))
async def log_file(bot, message):
    """Send log file"""
    try:
        await message.reply_document("MissKatyLogs.txt", caption="Log Bot MissKatyPyro")
    except Exception as e:
        await message.reply(str(e))

@app.on_message(filters.command(["donate"], COMMAND_HANDLER))
async def donate(_, message):
    await message.reply_photo(
        "AgACAgQAAxkBAAECsVNjbMvjxbN4gRafvNBH-Kv-Zqml8wACzq4xG95tbVPDeZ_UusonbAAIAQADAgADeQAHHgQ",
        caption=f"Hai {message.from_user.mention}, jika kamu merasa bot ini berguna bisa melakukan donasi dengan scan kode QRIS diatas untuk kebutuhan server dan lainnya. Terimakasih..",
    )

@app.on_message(
    filters.command(["balas"], COMMAND_HANDLER) & filters.user(SUDO) & filters.reply
)
async def balas(c, m):
    pesan = m.text.split(" ", 1)
    await m.delete()
    await m.reply(pesan[1], reply_to_message_id=m.reply_to_message.id)

@app.on_message(filters.command(["neofetch"], COMMAND_HANDLER) & filters.user(SUDO))
async def neofetch(c, m):
    neofetch = (await shell_exec("neofetch --stdout"))[0]
    await m.reply(f"<code>{neofetch}</code>")

@app.on_message(filters.command(["shell", "sh"], COMMAND_HANDLER) & filters.user(SUDO))
@app.on_edited_message(
    filters.command(["shell", "sh"], COMMAND_HANDLER) & filters.user(SUDO)
)
async def shell(client, message):
    cmd = message.text.split(" ", 1)
    if len(cmd) == 1:
        return await message.reply("No command to execute was given.")
    shell = (await shell_exec(cmd[1]))[0]
    if len(shell) > 3000:
        with open("shell_output.txt", "w") as file:
            file.write(shell)
        with open("shell_output.txt", "rb") as doc:
            await message.reply_document(document=doc, file_name=doc.name)
            try:
                os.remove("shell_output.txt")
            except:
                pass
    elif len(shell) != 0:
        await message.reply(shell, parse_mode=enums.ParseMode.HTML)
    else:
        await message.reply("No Reply")

@app.on_message(filters.command(["ev", "run"], COMMAND_HANDLER) & filters.user(SUDO))
@app.on_edited_message(filters.command(["ev", "run"]) & filters.user(SUDO))
async def evaluation_cmd_t(client, message):
    status_message = await message.reply("__Processing eval pyrogram...__")
    try:
        cmd = message.text.split(" ", maxsplit=1)[1]
    except IndexError:
        return await status_message.edit("__No evaluate message!__")
    old_stderr = sys.stderr
    old_stdout = sys.stdout
    redirected_output = sys.stdout = io.StringIO()
    redirected_error = sys.stderr = io.StringIO()
    stdout, stderr, exc = None, None, None

    try:
        await aexec(cmd, client, message)
    except Exception:
        exc = traceback.format_exc()

    stdout = redirected_output.getvalue()
    stderr = redirected_error.getvalue()
    sys.stdout = old_stdout
    sys.stderr = old_stderr

    evaluation = ""
    if exc:
        evaluation = exc
    elif stderr:
        evaluation = stderr
    elif stdout:
        evaluation = stdout
    else:
        evaluation = "Success"

    final_output = f"**EVAL**:\n`{cmd}`\n\n**OUTPUT**:\n`{evaluation.strip()}`\n"

    if len(final_output) > 4096:
        with open("MissKatyEval.txt", "w+", encoding="utf8") as out_file:
            out_file.write(final_output)
        await status_message.reply_document(
            document="MissKatyEval.txt",
            caption=cmd[: 4096 // 4 - 1],
            disable_notification=True,
        )
        os.remove("MissKatyEval.txt")
        await status_message.delete()
    else:
        await status_message.edit(final_output, parse_mode=enums.ParseMode.MARKDOWN)

async def aexec(code, client, message):
    exec(
        "async def __aexec(client, message): "
        + "".join(f"\n {l_}" for l_ in code.split("\n"))
    )
    return await locals()["__aexec"](client, message)

async def shell_exec(code, treat=True):
    process = await asyncio.create_subprocess_shell(
        code, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.STDOUT
    )

    stdout = (await process.communicate())[0]
    if treat:
        stdout = stdout.decode().strip()
    return stdout, process


#!/usr/bin/python3
"""EXPORT TO JSON"""
import json
import requests
from sys import argv

if __name__ == '__main__':
    url = 'https://jsonplaceholder.typicode.com/'
    user_name = requests.get(url + f'users/{argv[1]}').json().get('username')
    todos = requests.get(url + f'todos?userId={argv[1]}').json()

    data = [
        {"task": f'{r.get("title")}',
         "completed": eval(f'{r.get("completed")}'),
         "username": user_name
         } for r in todos
         ]

    json_data = {argv[1]: [items for items in data]}
    with open(f'{argv[1]}.json', 'w', encoding='utf-8') as file:
        json.dump(json_data, file)


"""
2. Write a Python function to sum all the numbers in a list. Go to the editor
Sample List : (8, 2, 3, 0, 7)
Expected Output : 20

def sumOfAllNumber(numbList):
    sum = 0
    for i in numbList:
        sum += i
        #numbList.remove(i)
    return sum

numbers = (8, 2, 3, 0, 7,4)
print(sumOfAllNumber(numbers))

"""
"""
 Write a Python function to multiply all the numbers in a list. Go to the editor
Sample List : (8, 2, 3, -1, 7)
Expected Output : -336

"""

def multiAllNum(allNum):
    result = 1
    for i in allNum:
        result = result*i

    return result

numbers = (8, 2, 3, -1, 7)

print(multiAllNum(numbers))


R, C = map(int, input().split())

board = []
visited = [[False]*(C) for _ in range(R)]

dx = [0, 0, -1, 1]
dy = [-1, 1, 0, 0]
maxlen = -int(1e9)

for i in range(R):
    sentence = input()
    tmp = []

    for j in range(C):
        tmp.append(sentence[j])

    board.append(tmp)

def dfs(x, y, ans):

    global maxlen

    maxlen = max(maxlen, len(ans))

    for k in range(4):
        nx = x + dx[k]
        ny = y + dy[k]

        if 0<=nx and nx<R and 0<=ny and ny<C and visited[nx][ny] == False:
            if board[nx][ny] not in ans:
                visited[nx][ny] = True
                ans += board[nx][ny]
                dfs(nx, ny, ans)
                ans = ans[:-1]
                visited[nx][ny] = False

ans = board[0][0]
maxlen = 1

dfs(0, 0, ans)

print(maxlen)


import math
import os

import matplotlib.pyplot as plt
import matplotlib.ticker as ticker
import numpy as np
import pandas as pd

START_ANGLE = -180

def get_new_coordinate(x0, y0, length, angle):
    """
    Take last coordinate plus new length and angle in order to calculate new coordinate
    :param x0: last x coordinate
    :param y0: last y coordinate
    :param length: length of line
    :param angle: angle of line
    :return: new coordinate
    """
    x1 = x0 + math.cos(math.radians(angle)) * length
    y1 = y0 + math.sin(math.radians(angle)) * length
    return x1, y1

def calculate_coordinates(datatable):
    # Coordinates DataFrame has one additional line = starting point (0,0)
    coordinates = pd.DataFrame(np.zeros(shape=(datatable.shape[0] + 1, datatable.shape[1])), columns=["x", "y"])

    for index, row in datatable.iterrows():
        angle = (START_ANGLE + 180 + row[1]) % 360  # Convert relative angle to absolute angle
        x, y = get_new_coordinate(x0=coordinates.iloc[index, 0],
                                  y0=coordinates.iloc[index, 1],
                                  length=row[0],
                                  angle=angle)
        coordinates.iloc[index + 1, 0] = x
        coordinates.iloc[index + 1, 1] = y

    """
    Plausibility check: is the distance between first and last coordinate roughly the same?
    In other words: is the room closed? ;-)
    """
    print("Distance between start and end point [in cm]:")
    x = math.pow(coordinates.iloc[0, 0] - coordinates.iloc[-1, 0], 2)
    y = math.pow(coordinates.iloc[0, 1] - coordinates.iloc[-1, 1], 2)
    print(math.sqrt(x + y))

    return coordinates

def plot_room(coordinates, raw_table, room_name):
    length_x = coordinates["x"].max() - coordinates["x"].min()
    length_y = coordinates["y"].max() - coordinates["y"].min()

    fig, ax = plt.subplots(figsize=(int(length_x / 15), int(length_y / 15)))
    for i in range(coordinates.shape[0] - 1):
        two_coordinates = coordinates.iloc[i:i + 2, :]
        ax = two_coordinates.plot(ax=ax, kind="line", marker="o", x="x", y="y", c="black", legend=None)

        # Label the drawn line in the center
        x_mean = two_coordinates["x"].mean()
        y_mean = two_coordinates["y"].mean()
        plt.annotate(str(raw_table.iloc[i, 0]) + "cm",  # this is the text (number of cm)
                     (x_mean, y_mean),  # this is the point to label
                     textcoords="offset points",  # how to position the text
                     xytext=(5, 5),  # distance from text to points (x,y)
                     ha="center",
                     fontsize=int(length_x / 20))

    ax.set_xlabel("")
    ax.set_ylabel("")
    ax.xaxis.set_major_locator(ticker.MultipleLocator(100))
    ax.yaxis.set_major_locator(ticker.MultipleLocator(100))
    plt.title(str(room_name), fontsize=int(length_x / 10))
    ax.tick_params(labelsize=int(length_x / 40))
    plt.grid(True)
    plt.savefig("Output/" + str(room_name) + ".png")

def process_room(file_name):
    room_name = file_name.split(".")[0]
    print(f"Process room: {room_name}")
    raw_table = pd.read_csv("Input/" + file_name, sep=";")

    coordinates = calculate_coordinates(raw_table)

    plot_room(coordinates, raw_table, room_name)

if __name__ == "__main__":
    for file_name in os.listdir("Input"):
        process_room(file_name)


"""
LayerArtist classes handle the visualization of an individual subset
or dataset
"""
import logging

import numpy as np
from matplotlib.colors import Normalize
from matplotlib.cm import gray
from ..core.exceptions import IncompatibleAttribute
from ..core.util import color2rgb
from ..core.subset import Subset
from .util import view_cascade, get_extent, fast_limits

class ChangedTrigger(object):
    """Sets an instance's _changed attribute to True on update"""
    def __init__(self, default=None):
        self._default = default
        self._vals = {}

    def __get__(self, inst, type=None):
        return self._vals.get(inst, self._default)

    def __set__(self, inst, value):
        changed = value != self.__get__(inst)
        self._vals[inst] = value
        if changed:
            inst._changed = True

class LayerArtist(object):
    def __init__(self, layer, axes):
        """Create a new LayerArtist

        :param layer: Data or subset to draw
        :type layer: :class:`~glue.core.data.Data` or `glue.core.subset.Subset`
        """
        self.layer = layer
        self._axes = axes
        self._visible = True

        self._zorder = 0
        self.view = None
        self.artists = []

        self._changed = True
        self._state = None  # cache of subset state, if relevant

    def redraw(self):
        self._axes.figure.canvas.draw()

    @property
    def zorder(self):
        return self._zorder

    @zorder.setter
    def zorder(self, value):
        for artist in self.artists:
            artist.set_zorder(value)
        self._zorder = value

    @property
    def visible(self):
        return self._visible

    @visible.setter
    def visible(self, value):
        self._visible = value
        for a in self.artists:
            a.set_visible(value)

    @property
    def enabled(self):
        return len(self.artists) > 0

    def update(self, view=None):
        """Redraw this layer"""
        raise NotImplementedError()

    def clear(self):
        """Clear the visulaization for this layer"""
        for artist in self.artists:
            try:
                artist.remove()
            except ValueError:  # already removed
                pass
        self.artists = []

    def _check_subset_state_changed(self):
        """Checks to see if layer is a subset and, if so,
        if it has changed subset state. Sets _changed flag to True if so"""
        if not isinstance(self.layer, Subset):
            return
        state = self.layer.subset_state
        if state is not self._state:
            self._changed = True
            self._state = state

    def _sync_style(self):
        style = self.layer.style
        for artist in self.artists:
            artist.set_markeredgecolor('none')
            artist.set_markerfacecolor(style.color)
            artist.set_marker(style.marker)
            artist.set_markersize(style.markersize)
            artist.set_linestyle('None')
            artist.set_alpha(style.alpha)
            artist.set_zorder(self.zorder)
            artist.set_visible(self.visible and self.enabled)

    def __str__(self):
        return "%s for %s" % (self.__class__.__name__, self.layer.label)

    __repr__ = __str__

class ImageLayerArtist(LayerArtist):
    def __init__(self, layer, ax):
        super(ImageLayerArtist, self).__init__(layer, ax)
        self.norm = None
        self._cmap = gray

    @property
    def cmap(self):
        return self._cmap

    @cmap.setter
    def cmap(self, value):
        self._cmap = value
        for a in self.artists:
            a.set_cmap(value)

    def _default_norm(self, layer):
        vals = np.sort(layer.ravel())
        vals = vals[np.isfinite(vals)]
        result = InvNormalize()
        result.stretch = 'arcsinh'
        result.clip = True
        if vals.size > 0:
            result.vmin = vals[.01 * vals.size]
            result.vmax = vals[.99 * vals.size]
        return result

    def update(self, view):
        self.clear()
        views = view_cascade(self.layer, view)
        artists = []

        lr0 = self.layer[views[0]]
        self.norm = self.norm or self._default_norm(lr0)
        self.norm = self.norm or self._default_norm(lr0)
        self.norm.update_clip(self.layer, view[0])

        for v in views:
            image = self.layer[v]
            extent = get_extent(v)
            artists.append(self._axes.imshow(image, cmap=self.cmap,
                                             norm=self.norm,
                                             interpolation='nearest',
                                             origin='lower',
                                             extent=extent, zorder=0))
        self.artists = artists
        self._sync_style()

    def set_norm(self, vmin=None, vmax=None,
                 bias=None, contrast=None, stretch=None, norm=None,
                 clip_lo=None, clip_hi=None):
        if norm is not None:
            self.norm = norm
            return norm
        if self.norm is None:
            self.norm = InvNormalize()
        if vmin is not None:
            self.norm.vmin = vmin
        if vmax is not None:
            self.norm.vmax = vmax
        if bias is not None:
            self.norm.bias = bias
        if contrast is not None:
            self.norm.contrast = contrast
        if clip_lo is not None:
            self.norm.clip_lo = clip_lo
        if clip_hi is not None:
            self.norm.clip_hi = clip_hi
        if stretch is not None:
            if stretch not in ['linear', 'sqrt', 'arcsinh']:
                raise TypeError(
                    "Stretch must be one of 'linear', 'sqrt', or 'arcsinh'")
            self.norm.stretch = stretch
        return self.norm

    def clear_norm(self):
        self.norm = None

    def _sync_style(self):
        for artist in self.artists:
            artist.set_zorder(self.zorder)
            artist.set_visible(self.visible and self.enabled)

class RGBImageLayerArtist(ImageLayerArtist):
    def __init__(self, layer, ax):
        super(RGBImageLayerArtist, self).__init__(layer, ax)
        self.r = None
        self.g = None
        self.b = None
        self.rnorm = None
        self.gnorm = None
        self.bnorm = None
        self.contrast_layer = 'green'
        self.layer_visible = dict(red=True, green=True, blue=True)

    def set_norm(self, *args, **kwargs):
        spr = super(RGBImageLayerArtist, self).set_norm
        if self.contrast_layer == 'red':
            self.norm = self.rnorm
            self.rnorm = spr(*args, **kwargs)
        if self.contrast_layer == 'green':
            self.norm = self.gnorm
            self.gnorm = spr(*args, **kwargs)
        if self.contrast_layer == 'blue':
            self.norm = self.bnorm
            self.bnorm = spr(*args, **kwargs)

    def update(self, view=None):
        self.clear()
        if self.r is None or self.g is None or self.b is None:
            return

        if view is None:
            view = self._last_view

        if view is None:
            return
        self._last_view = view

        views = view_cascade(self.layer, view)
        artists = []
        for v in views:
            extent = get_extent(v)
            # first argument = component. swap
            r = tuple([self.r] + list(v[1:]))
            g = tuple([self.g] + list(v[1:]))
            b = tuple([self.b] + list(v[1:]))
            r = self.layer[r]
            g = self.layer[g]
            b = self.layer[b]
            self.rnorm = self.rnorm or self._default_norm(r)
            self.gnorm = self.gnorm or self._default_norm(g)
            self.bnorm = self.bnorm or self._default_norm(b)
            if v is views[0]:
                self.rnorm.update_clip(self.layer, self.r)
                self.gnorm.update_clip(self.layer, self.g)
                self.bnorm.update_clip(self.layer, self.b)

            image = np.dstack((self.rnorm(r),
                               self.gnorm(g),
                               self.bnorm(b)))

            if not self.layer_visible['red']:
                image[:, :, 0] *= 0
            if not self.layer_visible['green']:
                image[:, :, 1] *= 0
            if not self.layer_visible['blue']:
                image[:, :, 2] *= 0

            artists.append(self._axes.imshow(image,
                                             interpolation='nearest',
                                             origin='lower',
                                             extent=extent, zorder=0))
        self.artists = artists
        self._sync_style()

class SubsetImageLayerArtist(LayerArtist):

    def update(self, view):
        subset = self.layer
        self.clear()
        logging.debug("View into subset %s is %s", self.layer, view)

        try:
            mask = subset.to_mask(view[1:])
        except IncompatibleAttribute:
            return
        logging.debug("View mask has shape %s", mask.shape)

        #shortcut for empty subsets
        if not mask.any():
            return

        extent = get_extent(view)
        r, g, b = color2rgb(self.layer.style.color)
        mask = np.dstack((r * mask, g * mask, b * mask, mask * .5))
        mask = (255 * mask).astype(np.uint8)
        self.artists = [self._axes.imshow(mask, extent=extent,
                                          interpolation='nearest',
                                          origin='lower',
                                          zorder=5, visible=self.visible)]

class ScatterLayerArtist(LayerArtist):
    xatt = ChangedTrigger()
    yatt = ChangedTrigger()

    def __init__(self, layer, ax):
        super(ScatterLayerArtist, self).__init__(layer, ax)
        self.emphasis = None

    def _recalc(self):
        self.clear()
        assert len(self.artists) == 0

        try:
            x = self.layer[self.xatt].ravel()
            y = self.layer[self.yatt].ravel()
        except IncompatibleAttribute:
            return False
        self.artists = self._axes.plot(x, y)
        return True

    def update(self, view=None):
        self._check_subset_state_changed()
        if self._changed:
            if not self._recalc():
                return
            self._changed = False

        has_emph = False
        if self.emphasis is not None:
            try:
                s = Subset(self.layer.data)
                s.subset_state = self.emphasis & self.layer.subset_state
                x = s[self.xatt].ravel()
                y = s[self.yatt].ravel()
                self.artists.extend(self._axes.plot(x, y))
                has_emph = True
            except IncompatibleAttribute:
                pass

        self._sync_style()
        if has_emph:
            self.artists[-1].set_mec('green')
            self.artists[-1].set_mew(2)
            self.artists[-1].set_alpha(1)

    def get_data(self):
        try:
            return self.layer[self.xatt].ravel(), self.layer[self.yatt].ravel()
        except IncompatibleAttribute:
            return np.array([]), np.array([])

class LayerArtistContainer(object):
    """A collection of LayerArtists"""
    def __init__(self):
        self.artists = []

    def _duplicate(self, artist):
        for a in self.artists:
            if type(a) == type(artist) and a.layer is artist.layer:
                return True
        return False

    def _check_duplicate(self, artist):
        """Raise an error if this artist is a duplicate"""
        if self._duplicate(artist):
            raise ValueError("Already have an artist for this type "
                             "and data")

    def append(self, artist):
        """Add a LayerArtist to this collection"""
        self._check_duplicate(artist)
        self.artists.append(artist)
        artist.zorder = max(a.zorder for a in self.artists) + 1

    def remove(self, artist):
        """Remove a LayerArtist from this collection"""
        try:
            self.artists.remove(artist)
            artist.clear()
        except ValueError:
            pass

    def pop(self, layer):
        """Remove all artists associated with a layer"""
        to_remove = [a for a in self.artists if a.layer is layer]
        for r in to_remove:
            self.remove(r)
        return to_remove

    @property
    def layers(self):
        """A list of the unique layers in the container"""
        return list(set([a.layer for a in self.artists]))

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

    def __iter__(self):
        return iter(self.artists)

    def __contains__(self, item):
        if isinstance(item, LayerArtist):
            return item in self.artists
        return any(item is a.layer for a in self.artists)

    def __getitem__(self, layer):
        if isinstance(layer, int):
            return self.artists[layer]
        return [a for a in self.artists if a.layer is layer]

class HistogramLayerArtist(LayerArtist):
    lo = ChangedTrigger(0)
    hi = ChangedTrigger(1)
    nbins = ChangedTrigger(10)
    xlog = ChangedTrigger(False)

    def __init__(self, layer, axes):
        super(HistogramLayerArtist, self).__init__(layer, axes)
        self.ylog = False
        self.cumulative = False
        self.normed = False
        self.y = np.array([])
        self.x = np.array([])
        self._y = np.array([])

        self._scale_state = None

    def has_patches(self):
        return len(self.artists) > 0

    def get_data(self):
        return self.x, self.y

    def clear(self):
        super(HistogramLayerArtist, self).clear()
        self.x = np.array([])
        self.y = np.array([])
        self._y = np.array([])

    def _calculate_histogram(self):
        """Recalculate the histogram, creating new patches"""
        self.clear()
        try:
            data = self.layer[self.att].ravel()
        except IncompatibleAttribute:
            return False

        if data.size == 0:
            return

        if self.lo > np.nanmax(data) or self.hi < np.nanmin(data):
            return
        if self.xlog:
            data = np.log10(data)
            rng = [np.log10(self.lo), np.log10(self.hi)]
        else:
            rng = self.lo, self.hi
        nbinpatch = self._axes.hist(data,
                                    bins=self.nbins,
                                    range=rng)
        self._y, self.x, self.artists = nbinpatch
        return True

    def _scale_histogram(self):
        """Modify height of bins to match ylog, cumulative, and norm"""
        if self.x.size == 0:
            return

        y = self._y.astype(np.float)
        dx = self.x[1] - self.x[0]
        if self.normed:
            div = y.sum() * dx
            if div == 0:
                div = 1
            y /= div
        if self.cumulative:
            y = y.cumsum()
            y /= y.max()

        self.y = y
        bottom = 0 if not self.ylog else 1e-100

        for a, y in zip(self.artists, y):
            a.set_height(y)
            x, y = a.get_xy()
            a.set_xy((x, bottom))

    def _check_scale_histogram(self):
        """
        If needed, rescale histogram to match cumulative/log/normed state.
        """
        state = (self.normed, self.ylog, self.cumulative)
        if state == self._scale_state:
            return
        self._scale_state = state
        self._scale_histogram()

    def update(self, view=None):
        """Sync plot.

        The _change flag tracks whether the histogram needs to be
        recalculated. If not, the properties of the existing
        artists are updated
        """
        self._check_subset_state_changed()
        if self._changed:
            if not self._calculate_histogram():
                return
            self._changed = False
            self._scale_state = None
        self._check_scale_histogram()
        self._sync_style()

    def _sync_style(self):
        """Update visual properties"""
        style = self.layer.style
        for artist in self.artists:
            artist.set_facecolor(style.color)
            artist.set_alpha(style.alpha)
            artist.set_zorder(self.zorder)
            artist.set_visible(self.visible and self.enabled)

class InvNormalize(Normalize):
    """ Simple wrapper to matplotlib Normalize object, that
    handles the case where vmax <= vmin """
    def __init__(self):
        Normalize.__init__(self)
        self.stretch = 'linear'
        self.bias = 0.5
        self.contrast = 0.5
        self.clip_lo = 5.
        self.clip_hi = 95.

    def update_clip(self, data, component):
        vmin, vmax = fast_limits(data, component, self.clip_lo, self.clip_hi)
        self.vmin = vmin
        self.vmax = vmax

    def __call__(self, value):
        self.autoscale_None(value)  # set vmin, vmax if unset
        inverted = self.vmax <= self.vmin

        hi, lo = max(self.vmin, self.vmax), min(self.vmin, self.vmax)
        ra = hi - lo
        mid = lo + ra * self.bias
        mn = mid - ra * self.contrast
        mx = mid + ra * self.contrast

        if self.stretch == 'linear':
            result = (value - mn) * (1.0 / (mx - mn))
            result = np.clip(result, 0, 1)
        elif self.stretch == 'arcsinh':
            b = max(self.bias, 1e-5)
            c = self.contrast
            result = (value - lo) / (1.0 * (hi - lo))
            result = np.arcsinh(result / b) / np.arcsinh((b + c) / b)
            result = np.clip(result, 0, 1)
        elif self.stretch == 'sqrt':
            result = (value - mn) * (1.0 / (mx - mn))
            result = np.clip(result, 0, 1)
            result = np.sqrt(result)
        else:
            raise TypeError("Invalid stretch: %s" % self.stretch)

        if inverted:
            result = 1 - result

        return result


s = 0

for i in range(100):
    #@ invariant s == i
    #@ invariant i < 11
    if i == 10:
        break
    s += 1

#@ assert s == 10

s = 0

for i in range(100):
    #@ invariant i <= 42 -> s == i*(i-1)//2
    #@ invariant i > 42 -> s + 42 == i*(i-1)//2
    if i == 42:
        continue
    s += i

#@ assert s == 4908


from model.user import User
from model.event import Event
from flask import abort
from common import user_service_helper
from common.constants import Statuses
from service.processing_service import are_processing_resources_available
from jobs import timeout_job
from mongoengine.errors import ValidationError, DoesNotExist

def register_user(request_payload):
    priority = request_payload['priority']
    if not are_processing_resources_available(priority):
        abort(404, description="Unavailable service resources")

    user = User(name=request_payload['name'],
                surname=request_payload['surname'],
                status=Statuses.Building.name)
    user.save()
    timeout_job.end_user_session(user)
    return user.to_json()

def get_user_info(id):
    user = None
    try:
        user = User.objects.get(pk=id)
    except (ValidationError, DoesNotExist):
        abort(404, description="User does not exist")

    return user.to_json()

def create_event(id, request_payload):
    user = None
    try:
        user = User.objects.get(pk=id)
    except (ValidationError, DoesNotExist):
        abort(404, description="User does not exist")

    if user_service_helper.check_user_status(user, "Timed_out"):
        abort(404, description="User session timed out")

    if not user_service_helper.check_user_status(user, "Building"):
        abort(404, description="User hours are computed")

    event_type = request_payload['type']
    status = user_service_helper.define_event_status(event_type)
    event = Event(type=event_type,
                  status=status,
                  timestamp=request_payload['timestamp'])
    User.objects(id=id).update_one(push__events=event)
    user.reload()
    return user.to_json()


"""This file creates a trainer that finds the best (fittest) AI"""
from ai_player import AiPlayer
from game import Game, SampleStrategies
import numpy as np
from numpy import random
import random
from typing import List, Tuple, Any
import pickle
from copy import copy, deepcopy

class AiLogEntry:
    """data to track evolution of AIs across generations during training"""

    def __init__(self, points_average, points_variance, events):
        self.points_average = points_average
        self.points_variance = points_variance
        self.events = events

    def __repr__(self):
        return "(" + str(self.points_average) + ", " + str(self.points_variance) + ", " + str(self.events) + ")"

class Trainer:
    """trains AIs (with a genetic algorithm) in order to get the best AI out of all;
    parameters therefore given manually"""

    strategy_parameter_min = -10
    strategy_parameter_max = 10

    def __init__(self, group_size=5, play_against_own_copies=False, population_size=100, survivor_rate=0.74,
                 child_rate=1, mutation_rate=0.05, mutation_copy_rate=0.0, lowest_variance_rate=0.98,
                 num_generations=200):
        assert (population_size % group_size == 0)
        self.group_size = group_size
        self.play_against_own_copies = play_against_own_copies
        self.population_size = population_size
        self.mutation_rate = mutation_rate
        self.mutation_copy_rate = mutation_copy_rate
        self.lowest_variance_rate = lowest_variance_rate
        self.num_generations = num_generations
        self.survivor_rate = survivor_rate
        self.num_survivors = int(survivor_rate * self.population_size)
        self.child_rate = child_rate
        self.num_children = int((self.population_size - self.num_survivors) * child_rate) # child_rate is relative amount of died AIs that is 'reborn' by recombination
        self.num_parents = self.num_children * 2
        self.fitness_game_number = 5   # empiric value
        self.points_per_ai = None
        self.ai_histories = dict()
        self.generation = 0
        self.population = []

    def _group(self) -> List[Tuple[Any, List[AiPlayer]]]:
        """puts the individuals (AIs) of a population into random groups of the same size"""
        if self.play_against_own_copies:
            groups = [(ai, [deepcopy(ai) for _ in range(self.group_size)]) for ai in self.population]
        else:
            random.shuffle(self.population)
            groups = []
            for ai_index in range(0, len(self.population), self.group_size):
                groups.append(("different AIs", self.population[ai_index: ai_index + self.group_size]))
        return groups

    def _select_extreme_ais(self, point_sum_per_ai, num_extreme_ais, selects_best_ais, variance_threshold) -> List[
        AiPlayer]:
        """selects strongest or weakest AIs of a population"""
        extreme_ais = []
        for _ in range(num_extreme_ais):
            max_points = float("-inf")
            min_points = float("inf")
            extreme_ai = None
            for ai, points in point_sum_per_ai.items():
                if self.ai_histories[ai][self.generation].points_variance > variance_threshold:
                    continue    # ignore AIs with high points variance in ranking -> middle field (extreme good/bad daily form)
                if selects_best_ais and max_points < points:
                    max_points = points
                    extreme_ai = ai
                elif not selects_best_ais and min_points > points:
                    min_points = points
                    extreme_ai = ai
            extreme_ais.append(extreme_ai)
            del point_sum_per_ai[extreme_ai]
        assert(None not in extreme_ais)
        return extreme_ais

    def _compute_avg_points_per_ai(self, point_list_per_ai) -> None:
        """creates a dictionary with average points of every AI"""
        self.points_per_ai = dict()
        for ai, point_list in point_list_per_ai.items():
            self.points_per_ai[ai] = sum(point_list) / len(point_list)
            points_variance = Trainer._compute_variance(point_list_per_ai[ai], self.points_per_ai[ai])
            if self.generation in self.ai_histories[ai]:
                self.ai_histories[ai][self.generation].points_average = int(self.points_per_ai[ai])
                self.ai_histories[ai][self.generation].points_variance = int(points_variance)
            else:
                self.ai_histories[ai][self.generation] = \
                    AiLogEntry(int(self.points_per_ai[ai]), int(points_variance), [])

    @staticmethod
    def _compute_variance(numbers, average) -> float:
        """calculates the corrected sample variance of any list of numbers with a given average"""
        variance = 0  # korrigierte Stichprobenvarianz
        for number in numbers:
            variance += (number - average) ** 2
        return variance / len(numbers)

    def _play_in_groups(self, point_list_per_ai, game_count) -> None:
        """part of _rank(); lets AIs play in groups"""
        groups = self._group()
        for original_ai, group in groups:
            game = Game(group)
            # same lists of dice eyes for each generation to make AIs more comparable
            random.seed(self.generation * self.fitness_game_number + game_count)
            game.play()
            for ai in group:
                points = ai.get_points()
                if original_ai == "different AIs":
                    point_list_per_ai[ai].append(points)
                else:
                    point_list_per_ai[original_ai].append(points)

    def _play_against_own_copies(self, final_ai):
        """lets final AI play against its copies"""
        group = [deepcopy(final_ai) for _ in range(self.group_size)]
        point_list = []
        for _ in range(10):
            game = Game(group)
            game.play()
            for ai in group:
                point_list.append(ai.get_points())
        average = sum(point_list) / len(point_list)
        return average, self._compute_variance(point_list, average)

    def _split_ais_by_fitness(self, point_sum_per_ai):
        """part of _rank(); splits AIs by fitness after playing in groups"""
        variance_threshold = self._calculate_variance_threshold()
        point_sum_per_ai_temp = copy(point_sum_per_ai)
        strongest_ais = self._select_extreme_ais(point_sum_per_ai_temp, self.num_parents,
                                                 True, variance_threshold)  # side-effect intentional
        weakest_ais = self._select_extreme_ais(point_sum_per_ai_temp, self.population_size - self.num_survivors,
                                               False, variance_threshold)
        weakest_ais = list(reversed(weakest_ais))
        middle_field = point_sum_per_ai_temp.keys()  # keys() only selects the AIs, not the points
        return strongest_ais, middle_field, weakest_ais

    def _calculate_variance_threshold(self):
        """calculates the threshold of variance; necessary to put AIs with extreme points variance into the middle field
        (influence from daily form too high)"""
        variances = []
        for ai in self.population:
            variances.append(self.ai_histories[ai][self.generation].points_variance)
        return list(sorted(variances))[int(self.lowest_variance_rate * self.population_size) - 1]

    def _create_ranking(self, point_list_per_ai):
        """part of _rank(); creates a ranking based on the fitness of an AI"""
        point_sum_per_ai = {ai: sum(point_list) for ai, point_list in point_list_per_ai.items()}
        strongest_ais, middle_field, weakest_ais = self._split_ais_by_fitness(point_sum_per_ai)
        ranking = copy(strongest_ais)
        ranking.extend(middle_field)
        ranking.extend(weakest_ais)
        assert (len(ranking) == self.population_size)
        return ranking

    def _rank(self) -> None:
        """lets the groups play and ranks them inside these groups by performance"""
        point_list_per_ai = {ai: [] for ai in self.population}
        for game_count in range(self.fitness_game_number):
            self._play_in_groups(point_list_per_ai, game_count)
        if not self.play_against_own_copies:
            for point_list in point_list_per_ai.values():
                assert (len(point_list) == self.fitness_game_number)
        self._compute_avg_points_per_ai(point_list_per_ai)
        self.population = self._create_ranking(point_list_per_ai)

    def _select(self) -> None:
        """selects the best AIs, these survive -> rate of survivors given by parameter"""
        dead_ais = self.population[self.num_survivors:]
        for ai in dead_ais:
            self._add_event_to_ai_history(ai, "SELEction")
        self.population = self.population[: self.num_survivors]

    def _mix_strategies(self, parent1, parent2) -> AiPlayer:
        """mixes the strategies of the parents by creating averages of the different factors / bias to be their child's
         strategy"""
        child_quadratic_factor = np.array([x / 2 for x in (parent1.quadratic_factor + parent2.quadratic_factor)])
        child_linear_factor = np.array([x / 2 for x in (parent1.linear_factor + parent2.linear_factor)])
        child_bias = np.array([x / 2 for x in (parent1.bias + parent2.bias)])
        assert (len(child_linear_factor) == len(parent1.linear_factor) and len(child_linear_factor) == len(
            parent2.linear_factor))
        self._add_event_to_ai_history(parent1, "PAREnt")
        self._add_event_to_ai_history(parent2, "PAREnt")
        ai_number = len(self.ai_histories)
        return AiPlayer(str(ai_number), child_quadratic_factor, child_linear_factor, child_bias)

    def _add_event_to_ai_history(self, ai, event) -> None:
        if self.generation in self.ai_histories[ai]:
            self.ai_histories[ai][self.generation].events.append(event)
        else:
            self.ai_histories[ai][self.generation] = AiLogEntry(None, None, [event])

    def _recombine(self) -> None:
        """extends the population by children that are created by recombination of their parents strategies"""
        children = []
        for child_index in range(self.num_children):  # build pairs
            child = self._mix_strategies(self.population[child_index * 2], self.population[child_index * 2 + 1])
            children.append(child)
            self.ai_histories[child] = dict()
            self._add_event_to_ai_history(child, "RECOmbination")
        self.population.extend(children)
        assert (len(self.population) <= self.population_size)

    def _mutate_strategy(self, ai) -> int:
        """mutates randomly small parts of the strategy of an AI"""
        mutation_counter = 0
        for value_index in range(AiPlayer.strategy_length):
            if random.random() < self.mutation_rate:
                ai.quadratic_factor[value_index] = Trainer._adjust_strategy_range(random.random())
                mutation_counter += 1
            if random.random() < self.mutation_rate:
                ai.linear_factor[value_index] = Trainer._adjust_strategy_range(random.random())
                mutation_counter += 1
            if random.random() < self.mutation_rate:
                ai.bias[value_index] = Trainer._adjust_strategy_range(random.random())
                mutation_counter += 1
        return mutation_counter  # call by reference on ai (pointer)

    def _mutate(self) -> None:
        """creates a list of mutated AIs"""
        copied_ais = []
        max_copies = (self.population_size - len(self.population)) * self.mutation_copy_rate
        for ai in self.population:
            ai_copy = deepcopy(ai)
            ai_number = len(self.ai_histories)
            ai_copy.name = str(ai_number)
            ai_history_copy = deepcopy(self.ai_histories[ai])
            mutation_counter = self._mutate_strategy(ai)
            if mutation_counter > 0:
                self._add_event_to_ai_history(ai, f"MUTAtion, {mutation_counter}")
                if len(copied_ais) < max_copies:
                    copied_ais.append(ai_copy)
                    self.ai_histories[ai_copy] = ai_history_copy
                    self._add_event_to_ai_history(ai_copy, f"COPY from {ai}")
        self.population.extend(copied_ais)
        assert (len(self.population) <= self.population_size)

    def _add_random_ais(self) -> None:
        """adds random AIs to the population in order to reach the original population size"""
        missing_ais = self.population_size - len(self.population)
        ais = []
        for ai_number in range(len(self.ai_histories), len(self.ai_histories) + missing_ais):
            ai = AiPlayer(str(ai_number), Trainer._build_random_strategy(),
                          Trainer._build_random_strategy(), Trainer._build_random_strategy())
            # ai = AiPlayer(str(ai_number), SampleStrategies.bodo_quadratic_factor,
                          # SampleStrategies.bodo_linear_factor, SampleStrategies.bodo_bias)
            self.ai_histories[ai] = dict()
            self._add_event_to_ai_history(ai, "INITialization")
            ais.append(ai)
        self.population.extend(ais)
        assert (len(self.population) <= self.population_size)

    def _find_strongest_ai(self):
        """finds the highest scoring ai in a population"""
        max_points = float("-inf")
        strongest_ai = None
        for ai in self.population:
            if max_points < self.points_per_ai[ai]:
                max_points = self.points_per_ai[ai]
                strongest_ai = ai
        return strongest_ai, max_points

    def _compute_points_statistics(self):
        """calculates the average points that were scored in a generation"""
        sum_points = 0
        for ai in self.population:
            sum_points += self.points_per_ai[ai]
        avg_points = sum_points / self.population_size

        var_points = Trainer._compute_variance(self.points_per_ai.values(), avg_points)
        return avg_points, var_points

    def _compute_next_generation(self) -> None:
        """directs all steps that have to be done to create the next generation / a (partly) new population"""
        if self.generation > 0:
            self._select()
            self._recombine()
            self._mutate()
        self._add_random_ais()
        self._rank()  # &[(ai, list(reversed(list(self.ai_histories[ai].items())))) for ai in self.population]

    @staticmethod
    def _build_random_strategy():
        """builds any part of strategy (quadratic, linear, bias)"""
        return Trainer._adjust_strategy_range(np.random.rand(AiPlayer.strategy_length))

    @staticmethod
    def _adjust_strategy_range(array_or_value):
        width = Trainer.strategy_parameter_max - Trainer.strategy_parameter_min
        return array_or_value * width + Trainer.strategy_parameter_min

    def train(self, load_population_from_file, load_ai_as_population, save_population_in_file) -> None:
        """trains the AIs due to the parameters and returns the final and best AI"""
        if load_population_from_file:
            self._load_population()
        if load_ai_as_population:
            self._load_ai_as_population()
        else:
            assert (self.generation == 0 and self.population == [])

        best_ai = None
        max_points = float("-inf")
        stop_generation = self.num_generations + self.generation
        print(f"group_size = {self.group_size}, play_against_own_copies = {self.play_against_own_copies}, "
              f"population_size = {self.population_size}, survivor_rate = {self.survivor_rate}, \n"
              f"child_rate = {self.child_rate}, mutation_rate = {self.mutation_rate}, "
              f"mutation_copy_rate = {self.mutation_copy_rate}, lowest_variance_rate = {self.lowest_variance_rate}, "
              f"num_generations = {self.num_generations}")
        while self.generation < stop_generation:
            self._compute_next_generation()
            strong_ai, strong_ai_points = self._find_strongest_ai()
            if strong_ai_points > max_points:
                max_points = strong_ai_points
                best_ai = strong_ai
            avg_points, variance = self._compute_points_statistics()
            print(f"Generation: {self.generation} \t Max: {strong_ai_points:.0f} \t Avg: {avg_points:.0f} "
                  f"\t Var: {variance:.0f}")
            self.generation += 1
        avg_points, variance = self._play_against_own_copies(best_ai)
        print(f"Best AI \t\t\t\t\t Avg: {avg_points:.0f} \t Var: {variance:.0f}")
        print("Evolution finished")
        if save_population_in_file:
            self._save_final_population_and_best_ai(best_ai, avg_points)

    def _save_final_population_and_best_ai(self, best_ai, avg_points) -> None:
        """saves the final population and the best AI of a train cycle """
        pickle.dump((self.population, self.ai_histories, self.generation), open("final_population.dat", "wb"))
        pickle.dump((best_ai, self.ai_histories[best_ai]), open(f"best_ai_{avg_points:.0f}_points.dat", "wb"))

    def _load_ai_as_population(self):
        """loads a saved AI as a population, like AI loaded by SampleStrategies"""
        file = open("best_ai_67_points.dat", "rb")
        ai, ai_history = pickle.load(file)
        for _ in range(self.population_size):
            ai_copy = deepcopy(ai)
            self.population.append(ai_copy)
            self.ai_histories[ai_copy] = ai_history
        file.close()

    def _load_population(self) -> None:
        """loads the population that was saved"""
        file = open("final_population.dat", "rb")
        self.population, self.ai_histories, self.generation = pickle.load(file)
        file.close()

if __name__ == "__main__":
    trainer = Trainer()
    trainer.train(load_population_from_file=False, load_ai_as_population=False, save_population_in_file=True)


import winsound
import cv2
import time
import threading

def func1():
    winsound.PlaySound("reimu.wav", winsound.SND_FILENAME)

def func2():
    time.sleep(20)
    img = cv2.imread('reimu.png')
    cv2.imshow('', img)
    cv2.waitKey(0)

if __name__ == "__main__":
    thread_1 = threading.Thread(target=func1)
    thread_2 = threading.Thread(target=func2)

    thread_1.start()
    thread_2.start()


from telegram.ext import Updater, CommandHandler, MessageHandler, Filters
import logging
import PIL
from PIL import Image

# Enable logging
logging.basicConfig(format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
                    level=logging.INFO)

logger = logging.getLogger(__name__)

# Define a few command handlers. These usually take the two arguments bot and
# update. Error handlers also receive the raised TelegramError object in error.
def start(bot, update):
    """Send a message when the command /start is issued."""
    update.message.reply_text('Hi!')

def help(bot, update):
    """Send a message when /help is issues"""
    reply = "Handwritten Equation Solver Bot\nSend an image to get started.\n"
    update.message.reply_text(reply)

def echo(bot, update):
    """Echo the user message."""
    update.message.reply_text("Please send an image of the equation to get started.")

def error(bot, update, error):
    """Log Errors caused by Updates."""
    logger.warning('Update "%s" caused error "%s"', update, error)

def image_reply(bot, update):
    update.message.reply_text("Downloading...")
    file_id = update.message.photo[0].file_id
    newFile = bot.getFile(file_id)
    newFile.download('test.jpg')
    print("Saving image to file test.jpg")
    compress(28, 'test.jpg')

def compress(basewidth, name):
    img = Image.open(name)
    wpercent = (basewidth / float(img.size[0]))
    hsize = int((float(img.size[1]) * float(wpercent)))
    img = img.resize((basewidth, hsize), PIL.Image.ANTIALIAS)
    img.save('test_re.jpg')

def main():
    # Create the EventHandler and pass it your bot's token.
    token = "565522254:AAFzehm10MW8Z1CmNxamlcb2ZubQGIoNFvI"
    updater = Updater(token)

    # Get the dispatcher to register handlers
    dp = updater.dispatcher

    # on different commands - answer in Telegram
    dp.add_handler(CommandHandler("start", start))
    dp.add_handler(CommandHandler("help", help))

    # on noncommand i.e message - echo the message on Telegram
    dp.add_handler(MessageHandler(Filters.text, echo))
    dp.add_handler(MessageHandler(Filters.photo, image_reply))
    # log all errors
    dp.add_error_handler(error)

    # Start the Bot
    updater.start_polling()

    updater.idle()

if __name__ == '__main__':
    main()


import os
import numpy as np
from tqdm import tqdm

from PIL import Image
from keras.preprocessing import image
from keras.models import load_model

model = load_model('333_model.h5')
testdir = "data/seg_train/buildings"
dir = os.listdir(testdir)

testset = np.empty(shape=(1,150,150,3))

for i in tqdm(range(len(dir))):
    traindir = "data/seg_train/buildings/" + dir[i]
    imagee = Image.open(traindir, mode='r')
    img_tensor = image.img_to_array(imagee)
    img_tensor = img_tensor / 255
    if (np.size(img_tensor) != 67500):
        print(dir[i])
    else:
        img_tensor = np.reshape(img_tensor, (1, 150, 150, 3))
        testset = np.append(testset, img_tensor, axis=0)

testlabel = []

for i in range(len(dir)):
    testlabel.append(0)

testset = np.array(testset)
testlabel = np.array(testlabel)

loss, acc = model.evaluate(testset, testlabel)

print(str(loss) + ':오차율  ', str(acc) + ":정확도")


"""
文件名：check_devices.py
创建人：苏杨
创建日期：
文件描述：定义一个log输出的格式和log输出等级的定义等等
"""
import logging
from datetime import datetime
import os
import threading

class Log:
    def __init__(self):
        self.pro_dir = os.path.dirname(os.path.abspath(__file__))
        self.pro_dir = os.path.split(self.pro_dir)[0]

        # 下面是记录log的文件创建的过程
        self.result_path = os.path.join(self.pro_dir, "result")
        if not os.path.exists(self.result_path):
            os.mkdir(self.result_path)
        self.log_path = os.path.join(self.result_path, str(datetime.now().strftime("%Y%m%d%H%M%S")))
        if not os.path.exists(self.log_path):
            os.mkdir(self.log_path)

        self.logger = logging.getLogger()
        self.logger.setLevel(logging.INFO)
        # 创建处理器对象
        handler = logging.FileHandler(os.path.join(self.log_path, "output.log"))
        formatter = logging.Formatter('%(levelname)s  %(name)s:%(filename)s:%(lineno)s>> %(message)s')
        # 为处理器添加设置格式器对象，添加过滤器对象的方法为：handler.setFilter(filter)
        handler.setFormatter(formatter)
        self.logger.addHandler(handler)

    def get_logger(self):
        return self.logger

class MyLog:
    """
    将上面的记录log的方法放到一个线程内，让它单独启用一个线程，是为了更好的写log
    """
    log = None
    mutex = threading.Lock()

    def __init__(self):
        pass

    @staticmethod
    def get_log():
        if MyLog.log is None:
            MyLog.mutex.acquire()
            MyLog.log = Log()
            MyLog.mutex.release()
        return MyLog.log


from django.contrib import admin

from duoyidian.models import DishClassifyInfo, DishInfo

class DishClassifyInfoAdmin(admin.ModelAdmin):
    list_display = ('classify', 'status', 'priority', 'create_at', 'update_at')

class DishInfoAdmin(admin.ModelAdmin):
    list_display = ('dish_classify', 'dish_name', 'dish_image', 'dish_price', 'status', 'priority', 'create_at', 'update_at')

admin.site.register(DishClassifyInfo, DishClassifyInfoAdmin)
admin.site.register(DishInfo, DishInfoAdmin)


import streamlit as st
import openslide

from services.PANDASegmentation import *

st.set_page_config(page_title="PANDA Segmentation",
                   page_icon="./app/images/tf_icon.png", layout='wide', initial_sidebar_state="expanded")

st.title('Prostate Gland Cancer Segmentation Engine')
st.sidebar.info('Set the parameters and upload the WSI to get the inference.')

uploaded_WSI = st.file_uploader("Upload the Whole Slide Image (WSI) of the Prostate tissue", ['tiff', 'tif'])

if uploaded_WSI is not None:
    tiff_encoded_image = uploaded_WSI.read()
    with open('./app/images/test_sub.tiff', 'wb') as f:
        f.write(tiff_encoded_image)
    test = openslide.OpenSlide('./app/images/test_sub.tiff')

    st.sidebar.markdown("## Params for Inference")
    index_level = st.sidebar.selectbox('Index_level', [0, 1, 2], help="""Indicates at which levels the patches should
    be analyzed. 0: Highest Resolution (May be slower but accurate). 2: Lowest Resolution (May be Faster by Compromising
    the accuracy)""")
    seg_res = st.sidebar.checkbox('Show Segmented Results', True)

    cols = st.columns(2)

    with cols[0]:
        x = int(cols[0].number_input('Width of Patch Size', 128, test.level_dimensions[index_level][0], step=1,
                                     help="""Width of the patch to extract from the image"""))

    with cols[1]:
        y = int(cols[1].number_input('Height of Patch Size', 128, test.level_dimensions[index_level][1], step=1,
                                     help="""Height of the patch to extract from the image"""))

    cols1 = st.columns(2)

    with cols1[0]:
        tissue_thresh = cols1[0].slider('Tissue Threshold %', 0.0, 1.0, step=0.01, value=0.35, help="""Percentage of
        tissue region in a patch to consider that patch to be valid""")

    with cols[1]:
        confidence_level = cols1[1].slider('Confidence_level %', 0.5, 1.0, step=0.01, value=0.75, help="""Minimum
        value of the model's prediction score to classify any given patch as malignant""")

    sub = st.button('Get Inference')

    if sub:
        PANDASegmentation.get_inference(test, index_level, (x, y), confidence_level, tissue_thresh, seg_res)

app/pages/1_♋_Pseudo Segmentation of Prostate Tissue.py


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

from scikits.talkbox.features import mfcc
import numpy as np
import soundfile as sf
import os
from sklearn.ensemble import RandomForestClassifier
# from sklearn.svm import LinearSVC, SVC
# from xgboost import XGBClassifier
from sklearn.externals import joblib

from utils import import_wav_data_in_dir

random_state=24
label_dict = {'hu':0, 'ti':1, 'dc':2}
datapath = 'cry_data/devided_wav_data/'

def main():
    # import wav files
    files = import_wav_data_in_dir(datapath)

    # prepare for training
    # get feature vectors by mfcc
    X = []
    y = []
    for f in files:
        x, sample_rate = sf.read(datapath + f)
        x = np.clip(x, 1e-10, 1)
        ceps,mspec,spec = mfcc(x, nwin=256, nfft=512, fs=8000, nceps=13)
        X.append(np.mean(ceps, axis=0))
        if '-hu.' in f:
            y.append(label_dict['hu'])
        elif '-ti.' in f:
            y.append(label_dict['ti'])
        else:
            y.append(label_dict['dc'])

    X = np.array(X)
    y = np.array(y)

    # training
    clf = RandomForestClassifier(n_estimators=498, random_state=random_state)
    # clf = XGBClassifier(max_depth=8, learning_rate=0.05, n_estimators=700, seed=random_state)
    clf.fit(X, y)

    # save model
    joblib.dump(clf, 'trained_models/clf_rf2.pkl.cmp', compress=True)

if __name__ == '__main__':
    main()


import sys
#retreive the file name passed to the program
fileName = sys.arg[1]

#declare a count variable
count=0

#open the file and read it
with open(fileName) as f:
	for line in f:
		lineCount+=1

		if lineCount %2==0:
			print(line,end = "")

if lineCount>10:
	print("Big")

else:
	print("Small")


from selenium import webdriver
import time

website = webdriver.Chrome()
dgl_url= "https://www.daguanlian.com"
test_url = "http://bbs.51testing.com"
website.get(test_url)

sea=website.find_element_by_id("scbar_txt")
sea.send_keys("jemter")
sub=website.find_element_by_id("scbar_btn")
sub.click()

time.sleep(3)
website.close()
time.sleep(1)
website.quit()


def binary(arr, l, h, ele):
    if l <= h:
        mid = int((l+h) / 2)
        if arr[mid] == ele:
            return mid
        elif arr[mid] > ele:
            binary(arr, l, (mid - 1), ele)
        else:
            binary(arr, (mid + 1), h, ele)
    else:
        return -1

N = int(input())
power_s = [int(x) for x in input().split()]
Q = int(input())
count = 0
sum = 0
for i in range(Q):
    power_b = int(input())
    index = binary(power_s, 0, len(power_s), power_b)
    for j in range(index):
        while count < index:
            count += 1
            sum = sum + power_s[i]
    print(count, end=" ")
    print(sum)


# Magnet2 by Grom PE. Public domain.
import xmpp, random, time
from magnet_api import *
from magnet_utils import *

quote_db = {}

def getquote(bot, room, number):
  if not room in quote_db: return
  if number > len(quote_db[room]) or number < 1: return
  return quote_db[room][number-1]

def addquote(bot, room, quotedic):
  if not room in quote_db: quote_db[room] = []
  if quotedic:
    quote_db[room].append(quotedic)

def delquote(bot, room, number):
  if not room in quote_db: return
  if number > len(quote_db[room]) or number < 1: return
  del quote_db[room][number-1]

def command_quote(bot, room, nick, access_level, parameters, message):
  if not room in quote_db or len(quote_db[room]) == 0:
    return 'No quotes added yet!'
  if not parameters:
    number = random.randint(1, len(quote_db[room]))
  else:
    try:
      number = int(parameters)
    except:
      search = parameters.lower()
      found = []
      for i in xrange(len(quote_db[room])):
        if search in quote_db[room][i]['quote'].lower():
          found.append(i)
      if len(found) == 0:
        return "No such text found in quotes."
      elif len(found) == 1:
        number = found[0]+1
      else:
        return "Text found in quotes %s."%(', '.join(['#%d'%(x+1) for x in found]))

  existent_quote = getquote(bot, room, number)
  if not existent_quote:
    return "There's no quote #%d, and there are %d quotes."%(number, len(quote_db[room]))

  res = 'Quote #%d: %s'%(number, existent_quote['quote'])
  if message.getType() != 'groupchat' and access_level >= LEVEL_ADMIN:
    t = timeformat(time.time()-existent_quote['time'])
    res = '%s\n(added by %s %s ago)'%(res, existent_quote['jid'], t)

  return res

def command_addquote(bot, room, nick, access_level, parameters, message):
  if not parameters: return 'Expected quote text to add.'
  quote = parameters

  jid = bot.roster[room][nick][ROSTER_JID]
  if jid != None: jid = xmpp.JID(jid).getStripped().lower()

  quotedic = {
    'quote': quote,
    'jid': jid,
    'time': time.time(),
  }
  addquote(bot, room, quotedic)
  number = len(quote_db[room])
  return "Quote #%d added."%(number)

def command_delquote(bot, room, nick, access_level, parameters, message):
  try: number = int(parameters)
  except: return 'Expected quote number to delete.'

  jid = bot.roster[room][nick][ROSTER_JID]
  if jid != None: jid = xmpp.JID(jid).getStripped().lower()

  if not room in quote_db or len(quote_db[room]) == 0:
    return 'No quotes added yet!'

  existent_quote = getquote(bot, room, number)
  if not existent_quote:
    return "There's no quote #%d, and there is total of %d quotes."%(number, len(quote_db[room]))

  if access_level < LEVEL_ADMIN:
    if not jid or existent_quote['jid'] != jid or time.time() - existent_quote['time'] > 3600:
      return "You can't delete quote #%d."%(number)

  delquote(bot, room, number)
  return "Quote #%d deleted."%(number)

def load(bot):
  global quote_db
  quote_db = bot.load_database('quote') or {}
  bot.add_command('quote', command_quote, LEVEL_GUEST, 'quote')
  bot.add_command('addquote', command_addquote, LEVEL_MEMBER, 'quote')
  bot.add_command('delquote', command_delquote, LEVEL_MEMBER, 'quote')

def save(bot):
  bot.save_database('quote', quote_db)

def unload(bot):
  pass

def info(bot):
  return 'Quote plugin v1.0.3'


import math
from igraph import *

# from this module:
import pypath.colorgen as colorgen

def inter_group(g, groups):
    # group-group adjacency matrix weighted by connecting edges,
    # in nested dicts
    allGroups = {}
    for v in g.vs:
        allGroups[v[groups]] = 0
    interGroup = allGroups.copy()
    for key in allGroups.keys():
        interGroup[key] = allGroups.copy()
    for e in g.es:
        interGroup[g.vs[e.source][groups]][g.vs[e.target][groups]] += 1
        interGroup[g.vs[e.target][groups]][g.vs[e.source][groups]] += 1
    return interGroup

def meta_graph(interGroup):
    # returns graph where each node representing one group or module
    meta = Graph(len(interGroup.keys()))
    meta.vs["name"] = [None]
    gr = 0
    for key in interGroup.keys():
        meta.vs[gr]["name"] = key
        gr += 1
    metaEdges = []
    for one, others in interGroup.iteritems():
        for two, weight in others.iteritems():
            if one < two:
                grOne = meta.vs.find(name=one)
                grTwo = meta.vs.find(name=two)
                if weight > 0:
                    metaEdges.append((grOne.index, grTwo.index))
    meta.add_edges(metaEdges)
    return meta

def meta_weight(meta, interGroup):
    meta.es["weight"] = [None]
    for one, others in interGroup.iteritems():
        for two, weight in others.iteritems():
            grOne = meta.vs.find(name=one)
            grTwo = meta.vs.find(name=two)
            e = meta.es.select(_source=grOne.index, _target=grTwo.index)
            if len(e) == 0:
                e = meta.es.select(_source=grTwo.index, _target=grOne.index)
            if len(e) > 0:
                e[0]["weight"] = weight
                i = e[0].index
    meanDeg = sum(meta.vs.degree()) / float(len(meta.vs))
    for e in meta.es:
        degA = meta.vs[e.source].degree()
        degB = meta.vs[e.target].degree()
        e["weight"] = e["weight"] / \
            (math.log(float(min(degA, degB)), 2) + 1.0) ** 2
    return meta.es["weight"]

def meta_layout(g, groups, layout, **kwargs):
    groups = groups2attribute(g, groups)
    # TODO: overlapping groups; now assume discrete groups
    interGroup = inter_group(g, groups)
    meta = meta_graph(interGroup)
    if layout in set(["fr", "fruchterman_reingold"]):
        meta.es["weight"] = meta_weight(meta, interGroup)
        meta.lo = meta.layout(
            "fr",
            weights=meta.es["weight"],
            repulserad=meta.vcount()**2,
            **kwargs)
    else:
        meta.lo = meta.layout(layout, **kwargs)
    dist = layout_distances(meta.lo)
    cl = VertexClustering(g, membership=g.vs[groups])
    subGraphs = cl.subgraphs()
    g.vs["lo"] = [None]
    for i, gr in enumerate(subGraphs):
        thisGroupVs = filter(lambda x: g.vs[x][groups] == i, g.vs.indices)
        cntr = meta.lo[i]
        lo = gr.layout("fr", repulserad=gr.vcount()**2)
        loo = layout_norm(
            lo, [float(cntr[0] - dist[i]), float(cntr[0] + dist[i])],
            [float(cntr[1] - dist[i]), float(cntr[1] + dist[i])])
        for j, v in enumerate(thisGroupVs):
            g.vs[v]["lo"] = loo[j]
    return Layout(coords=g.vs["lo"], dim=2)

def layout_norm(lo, xlim, ylim):
    x = []
    y = []
    for i in lo.coords:
        x.append(i[0])
        y.append(i[1])
    minx = min(x)
    maxx = max(x)
    rangex = maxx - minx
    miny = min(y)
    maxy = max(y)
    rangey = maxy - miny
    scalex = (xlim[1] - xlim[0]) / rangex
    scaley = (ylim[1] - ylim[0]) / rangey
    movex = (xlim[1] + xlim[0]) / 2 - (minx + maxx) / 2
    movey = (ylim[1] + ylim[0]) / 2 - (miny + maxy) / 2
    xx = []
    yy = []
    nLayout = []
    for i, c in enumerate(lo.coords):
        nLayout.append([(c[0] - minx) * scalex + xlim[0],
                        (c[1] - miny) * scaley + ylim[0]])
    return Layout(coords=nLayout, dim=2)

def layout_distances(layout):
    minDs = []
    for i in range(0, len(layout)):
        minD = 100000
        for j in range(0, len(layout)):
            if i != j:
                d = math.sqrt((layout[i][0] - layout[j][0])**2 + (layout[i][
                    1] - layout[j][1])**2)
                minD = d if d < minD else minD
        minDs.append(minD * 0.3)
    return minDs

def groups2attribute(g, groups):
    groupType = groups.__class__.__name__
    if groupType != "str":
        g.vs["groups"] = [None]
        if groupType == "VertexDendrogram":
            g.vs["groups"] = groups.as_clustering().membership
        elif groupType == "VertexClustering":
            g.vs["groups"] == groups.membership
        elif groupType == "list":
            g.vs["groups"] = groups
        return "groups"
    else:
        return groups

def layout_intergroup(g, groups, **kwargs):
    groups = groups2attribute(g, groups)
    # TODO: overlapping groups; now assume discrete groups
    g.es["layout_weight"] = [None]
    for e in g.es:
        indA = e.source
        indB = e.target
        indE = e.index
        if g.vs[indA][groups] == g.vs[indB][groups]:
            g.es[indE]["layout_weight"] = 10.0
        else:
            g.es[indE]["layout_weight"] = 0.0001
    lo = g.layout(
        "fr",
        weights=g.es["layout_weight"],
        repulserad=g.vcount()**2.4,
        **kwargs)
    return Layout(coords=lo, dim=2)

def layout_modular_circle(g, groups, **kwargs):
    return meta_layout(g, groups, "circle", **kwargs)

def layout_modular_fr(g, groups, **kwargs):
    return meta_layout(g, groups, "fr", **kwargs)

def group_colors(g, groups, edges=False):
    groups = groups2attribute(g, groups)
    gr = set(g.vs[groups])
    n = len(gr)
    palette = colorgen.gethexrgbs(n)
    palette.reverse()
    grCol = {}
    for i in gr:
        grCol[i] = palette.pop()
    g.vs[groups + "_color"] = [None]
    for v in g.vs:
        i = v.index
        g.vs[i][groups + "_color"] = grCol[g.vs[i][groups]]
    if edges:
        g.es[groups + "_color"] = [None]
        for e in g.es:
            e[groups + "_color"] = colormix(g.vs[e.source][groups + "_color"],
                                            g.vs[e.target][groups + "_color"])
    return g.vs[groups + "_color"]


from assignment import *

def main():
    # -----
    # 1. Load corpus data using your load_corpus_data function.
    # 2. Use the save_pkl utility function to save this data to a file named
    #    data.pkl
    # 3. Obtain the word frequency dictionary using your get_word_freq function.
    # 4. Use the save_json utility function to save the word frequency
    #    dictionary to a file named wfd.json
    # 5. Obtain two lists of words: top 100 and top 5000.
    # 6. Save the two lists in two files named top_100_list.txt and
    #    top_5000_list.txt respectively. Write plain text words, one word per
    #    line. You will need to write your own code for that (instead of using a
    #    function). Refer to your lecture notes or Python documentation for
    #    how to do that. The words should be ordered by decreasing frequency.
    # 7. Generate a frequency graph for the top 100 words, and use the
    #    graph_top_k function to save it to a file named top_100_fig.png
    # 8. Answer the question: What type of behavior do English words exhibit?
    #    What is the class of functions that describe such behavior? What is the
    #    name of this law in linguistics? Answers should be inside comments.
    #

    data = load_corpus_data("/Users/sam/python local repository/linguistic manifold/data/english-brown.txt")

    save_pkl("/Users/sam/python local repository/linguistic manifold/data/data.pkl", data)

    wfd = get_word_freq(data)

    save_json("/Users/sam/python local repository/linguistic manifold/data/wfd.jason", wfd)

    top_100_list = top_k_words(wfd, 100)
    top_5000_list = top_k_words(wfd, 5000)

    a = open("/Users/sam/python local repository/linguistic manifold/data/top_100_list.txt", "w")
    for w in top_k_words(wfd,100):
        a.write(w)
        a.write("\n")
    a.close()

    b = open("/Users/sam/python local repository/linguistic manifold/data/top_5000_list.txt", "w")
    for w in top_k_words(wfd,5000):
        b.write(w)
        b.write("\n")
    b.close()

    graph_top_k(wfd, top_k_words(wfd,100), "/Users/sam/python local repository/linguistic manifold/data/top_100_fig.png")
    #
    # It is the positive part of a reciprocal fuction; the law is called
    # Zipf's law.
    # -----
    return

if __name__ == "__main__":
    main()


import random
import re
import statistics
from graph import PercentPerGeneration
import sys
import argparse
import os

# Constants
ALPHABET = "abcdefghijklmnopqrstuvwxyz"
CIPHER_TEXT_FILE = "enc.txt"
PLAIN_TEXT_FILE = "plain.txt"
PERMUTATION_FILE = "perm.txt"
COMMON_WORD = "dict.txt"
FREQ_FILE = "Letter_Freq.txt"

# Genetic Algorithm Parameters
POPULATION_SIZE = 100
MUTATION_RATE = 0.05
MAX_GENERATIONS = 2000
# How much to take from the best solutions
SELECTION_BIASED = POPULATION_SIZE * 0.5
SELECTION_BIASED_PART2 = POPULATION_SIZE * 0.1
# How much to take from the best solutions for crossover
SELECTION_BIASED_CROSSOVER = POPULATION_SIZE * 0.8
CHANGE_LAMARCK = 0.5
COUNTER_CONVERGENCE = 200

def process_arguments():
    parser = argparse.ArgumentParser(description='Example script with command-line arguments')
    parser.add_argument('-a', '--algorithem', type=str,
                        help='algorithem to run, by defult run the main algorithem, enter 2 for darwin 3 for lamark')
    parser.add_argument('-e', '--enc', type=str, help='path to ciphper text')
    parser.add_argument('-f', '--freq', type=str, help='path to Letter_Freq')
    parser.add_argument('-c', '--common', type=str, help='path to common word text')
    parser.add_argument('-r', '--result', type=str, help='path to translatation text')
    parser.add_argument('-d', '--dict', type=str, help='path to translatation dict')
    args = parser.parse_args()
    return args

# return dict key=letter, val=num apper
def statistic_letter(text):
    conter = 0
    letter_count = {}
    for letter in text:
        if letter.isalpha():
            letter = letter.lower()
            letter_count[letter] = letter_count.get(letter, 0) + 1
            conter += 1
    for key, value in letter_count.items():
        letter_count[key] = value / conter
    return (letter_count)

def file_to_arr(file_path):
    data_dict = set()
    with open(file_path, "r") as file:
        for line in file:
            data_dict.add(line.strip())
    return data_dict

# for each line the first word is key the secound value
def file_to_dict(file_path):
    data_dict = {}
    with open(file_path, "r") as file:
        for line in file:
            words = line.lower().strip().split()
            if len(words) >= 2:
                key = words[1]
                value = words[0]
                data_dict[key] = float(value)
    return data_dict

def remove_special_characters(input_string):
    # Regular expression pattern to match special characters
    pattern = r'[^a-zA-Z0-9\s]'  # Matches any character that is not a letter, digit, or whitespace
    output_string = re.sub(pattern, '', input_string)
    return output_string

# delete duplicates and check that all the letters are found, if not add them at the end in random order
def missing_letters(letters):
    missing_letters = []
    combined_list_set = list(set(letters))
    # Sort the combined list
    combined_list_set.sort()
    # Check if all letters are present
    if len(combined_list_set) != 26:
        # Create a list of missing letters
        missing_letters = [chr(i) for i in range(ord('a'), ord('z') + 1) if chr(i) not in combined_list_set]
    return missing_letters

# Generate initial population
def generate_population():
    population = []
    for _ in range(POPULATION_SIZE):
        permutation = list(ALPHABET)
        random.shuffle(permutation)
        population.append(permutation)
    return population

# Calculate fitness score
def calculate_fitness(permutation):
    decrypted_text = cipher_text.translate(str.maketrans(ALPHABET, "".join(permutation)))
    decrypted_text_arr = remove_special_characters(decrypted_text).lower().strip().split()
    # Checks how many common words appear in the decoded text
    set1 = set(decrypted_text_arr)
    set2 = set(common_word)
    intersection = set1.intersection(set2)
    res_word = len(intersection)
    res_letter = calculate_statisc_letter(permutation)
    return res_word * 3 + res_letter * 0.0001

def calculate_statisc_letter(permutation):
    res = 0
    for key, value in sulotionFreq.items():
        letter = permutation[ALPHABET.index(key)]
        try:
            add = 1 / abs(value - real_freq[letter])
            res += 100000000 if add > 100000000 else add
        except:
            res += 100000000
    return res

# Perform single-point crossover
def crossover(parent1, parent2):
    crossover_point = random.randint(0, 26)
    child = fix_cross(parent1[:crossover_point], parent2[crossover_point:])
    return child

def fix_cross(a, b):
    combined_list = list(set(a + b))
    missing_letter = missing_letters(combined_list)

    # Add missing letters randomly to the combined list
    random.shuffle(missing_letter)
    combined_list += missing_letter

    # Return the combination
    return combined_list

# Perform mutation
def mutate(permutation):
    for i in range(int(len(ALPHABET) * MUTATION_RATE)):
        j = random.randint(0, len(ALPHABET) - 1)
        z = random.randint(0, len(ALPHABET) - 1)
        permutation[z], permutation[j] = permutation[j], permutation[z]
    return permutation

def sort_by_grade(objects, grades):
    def myFunc(x):
        return x[1]

    # Combine objects and grades into pairs
    pairs = zip(objects, grades)

    # Sort the pairs based on the grade value
    sorted_pairs = sorted(pairs, key=lambda x: x[1], reverse=True)

    # Create a new array with pairs of object and grade
    result = [(obj, grade) for obj, grade in sorted_pairs]
    return result

# Main genetic algorithm loop
def genetic_algorithm():
    best_results = []
    worst_results = []
    average_results = []
    population = generate_population()
    generations = 0
    best_individual = None
    best_ans_for_generations = ""
    counter_convergence = COUNTER_CONVERGENCE
    while generations < MAX_GENERATIONS and counter_convergence:

        # Calculate fitness for each individual
        fitness_scores = [calculate_fitness(individual) for individual in population]
        # Find best individual
        best_individual = sort_by_grade(population, fitness_scores)
        x = best_individual

        final_ans = best_individual[0]

        print(final_ans)
        print("generations: ", generations)
        print("counter_convergence: ", counter_convergence)

        best_results.append(best_individual[0][1])
        worst_results.append(best_individual[-1][1])
        average_results.append(statistics.mean(fitness_scores))

        if best_ans_for_generations != "" and best_ans_for_generations == final_ans[1]:
            counter_convergence -= 1
        else:
            counter_convergence = COUNTER_CONVERGENCE

        best_ans_for_generations = final_ans[1]
        # Create new population through selection, crossover, and mutation
        new_population = create_population_part1(best_individual)

        population = new_population.copy()
        generations += 1

    writeRes(final_ans[0])
    graph_results(best_results, worst_results, average_results)
    return generations

def create_population_part1(best_individual):
    new_population = []
    size = 10
    size2 = 20
    for i in range(size):
        new_population.append(best_individual[0][0].copy())

    for i in range(size):
        new_population.append(mutate(best_individual[0][0].copy()))
    population = int(SELECTION_BIASED)
    if population > (POPULATION_SIZE - size) - size2:
        population = (POPULATION_SIZE - size) - size2
    new_population.extend([mutate(best[0]) for best in best_individual[:population]])

    for_crossover = best_individual[:int(SELECTION_BIASED_CROSSOVER)]
    while len(new_population) < POPULATION_SIZE:
        parent1 = random.choice(for_crossover)[0]
        parent2 = random.choice(for_crossover)[0]
        child = crossover(parent1, parent2)
        if len(child) != 26:
            print("error")
        child = mutate(child)
        if len(child) != 26:
            print("error 2")
        new_population.append(child)
    # new_population.append(list('yxintozjcebldukmsvpqrhwgaf'))
    return new_population

def lamarck_algorithm():
    # for graph - each generation information
    best_results = []
    worst_results = []
    average_results = []
    population = generate_population()  # generate random population
    generations = 0
    best_individual = None
    best_ans_for_generations = ""
    counter_convergence = COUNTER_CONVERGENCE
    while generations < MAX_GENERATIONS and counter_convergence:
        # Create new population through selection, crossover, and mutation
        [mutate(individual) for individual in population]

        if best_ans_for_generations != "":
            add = best_individual[0][0].copy()
            population[-1] = add

        # Calculate fitness for each individual
        fitness_scores = [calculate_fitness(individual) for individual in population]
        # Find best individual
        best_individual = sort_by_grade(population, fitness_scores)

        final_ans = best_individual[0]
        print(final_ans)
        print("generations: ", generations)
        print("counter_convergence: ", counter_convergence)
        # information for graph
        best_results.append((best_individual[0][1]))
        worst_results.append((best_individual[-1][1]))
        average_results.append(statistics.mean(fitness_scores))

        if best_ans_for_generations != "" and best_ans_for_generations == final_ans[1]:
            counter_convergence -= 1
        else:
            counter_convergence = 200

        best_ans_for_generations = final_ans[1]
        # Create new population through selection, crossover, and mutation
        new_population = create_population_lamarck(best_individual)

        population = new_population
        generations += 1
    PercentPerGeneration(best_results, worst_results, average_results)
    writeRes(final_ans[0])
    return generations

def darwin_algorithm():
    best_results = []
    worst_results = []
    average_results = []
    population = generate_population()
    generations = 0
    best_individual = None
    best_ans_for_generations = ""
    counter_convergence = COUNTER_CONVERGENCE
    while generations < MAX_GENERATIONS and counter_convergence:
        fitness_scores = [calculate_fitness(individual) for individual in population]

        results = beforAndAfterMutate(population)  # make mutation and calculate fitness
        # best_individual = sort_by_grade(population, fitness_scores)
        best_individual = (sorted(results.items(), key=lambda item: item[1], reverse=True))
        final_ans = best_individual[0]
        print(final_ans)
        print("generations: ", generations)
        print("counter_convergence: ", counter_convergence)
        # information for graph
        best_results.append((best_individual[0][1]))
        worst_results.append((best_individual[-1][1]))
        average_results.append(statistics.mean(fitness_scores))

        if best_ans_for_generations != "" and best_ans_for_generations == final_ans[1]:
            counter_convergence -= 1
        else:
            counter_convergence = 200
        best_ans_for_generations = final_ans[1]
        # Create new population through selection, crossover, and mutation
        new_population = create_population_darwin(best_individual).copy()
        population = new_population.copy()
        generations += 1
    PercentPerGeneration(best_results, worst_results, average_results)
    writeRes(final_ans[0])
    return generations

def writeRes(final_ans):
    decrypted_text = cipher_text.translate(str.maketrans(ALPHABET, "".join(final_ans)))
    with open(PLAIN_TEXT_FILE, "w") as file:
        file.write(decrypted_text)
    with open(PERMUTATION_FILE, "w") as file:
        text = ""
        for i in range(26):
            text += ALPHABET[i] + final_ans[i] + "\n"
        file.write(text)

# create new population with lamarck - duplicate the best individuals
def create_population_lamarck(best_individual):
    new_population = []
    count = int(SELECTION_BIASED_PART2)
    top_best_individual = best_individual[:10].copy()
    for best in top_best_individual:
        if len(new_population) >= POPULATION_SIZE:
            break
        for i in range(count):
            new_population.append(best[0].copy())
        count -= 1
    for_rest = best_individual
    # the rest of the population -> do crossover
    crossover_population(new_population, for_rest, "lamarck")
    return new_population

def create_population_darwin(best_individual):
    new_population = []
    count = int(SELECTION_BIASED_PART2)
    top_best_individual = best_individual[:10].copy()
    new_population.append(list(best_individual[0][0]).copy())
    for best in top_best_individual:
        for i in range(count):
            new_copy = mutate(list(best[0]))
            new_population.append(new_copy)
        count -= 1
    # creat new population
    new_group = new_population.copy()
    # add random individual
    size_left = POPULATION_SIZE - len(new_population)
    for i in range(size_left):
        new_group.append(mutate(list(random.choice(best_individual)[0])).copy())
    # new_group = crossover_population(new_group, best_individual, "darwin")
    return new_group

# take population and return new population after crossover
def crossover_population(dest_population, source_population, mode):
    if mode == "lamarck":
        # do this until we get the same size of population
        while len(dest_population) < POPULATION_SIZE:
            parent1 = random.choice(source_population)[0].copy()
            parent2 = random.choice(source_population)[0].copy()
            child = crossover(parent1, parent2)
            if len(child) != 26:
                print("error")
            child = mutate(child)
            if len(child) != 26:
                print("error 2")
            dest_population.append(child)
        return dest_population
    elif mode == "darwin":
        # do this until we get the same size of population
        while len(dest_population) < POPULATION_SIZE:
            parent1 = list(random.choice(source_population)[0])
            parent2 = list(random.choice(source_population)[0])
            child = mutate(crossover(parent1, parent2))
            if len(child) != 26:
                print("error")
            dest_population.append(child)
        return dest_population

# dict of population before And After Mutate, key=before, value=After
def beforAndAfterMutate(population):
    dict_map = {}
    for people in population:
        dict_map["".join(people)] = calculate_fitness(mutate(list(people)))
    return dict_map

def graph_results(best_results, worst_results, average_results):
    PercentPerGeneration(best_results, worst_results, average_results)
    return

if __name__ == "__main__":
    run = 1
    args = process_arguments()
    if args.algorithem:
        run = int(args.algorithem)
    if args.enc:
        CIPHER_TEXT_FILE = args.enc
    if args.freq:
        FREQ_FILE = args.freq
    if args.common:
        COMMON_WORD = args.common
    if args.result:
        PERMUTATION_FILE = args.result
    if args.dict:
        PLAIN_TEXT_FILE = args.dict

    with open(CIPHER_TEXT_FILE, "r") as file:
        cipher_text = file.read().lower()
    sum_enc_word = len((cipher_text.strip().split()))
    real_freq = file_to_dict(FREQ_FILE)
    # A sorted array of the most common letters according to the common letters file
    common_word = file_to_arr(COMMON_WORD)

    sulotionFreq = statistic_letter(cipher_text.strip())
    if (run == 2):
        total_steps = darwin_algorithm()
    elif (run == 3):
        total_steps = lamarck_algorithm()
    else:
        total_steps = genetic_algorithm()
    print(f"Total Steps: {str(total_steps)}")


from typing import Iterable, Union, Optional

from pydantic import BaseModel

import database.schema as schema
import sqlite3
from os.path import isfile
from datetime import datetime, timedelta
from threading import Lock

class WebKeyStatus(BaseModel):
    id: int
    key_expiration_date: datetime
    request_token: str
    request_token_expiration_date: datetime
    validated: bool
    key: Optional[str]

class DB:
    db_file_name = 'savedata.db'

    def __enter__(self):
        self.lock.acquire()
        self.con = sqlite3.connect(self.db_file_name)
        self.cur = self.con.cursor()
        return self

    def __exit__(self, exception_type, exception_value, tb):
        self.con.commit()
        self.con.close()
        self.con = None
        self.cur = None
        self.lock.release()

    def __init__(self):
        self.con: Union[sqlite3.Connection, None] = None
        self.cur: Union[sqlite3.Cursor, None] = None
        self.lock = Lock()
        if not isfile(self.db_file_name):
            self.create_database()

    def create_database(self):
        """
        Launches database queries to build all relevant tables
        """
        with self as d:
            d.cur = self.con.cursor()
            d.cur.executescript(schema.generate())

    def register_server(self, server_id: int, server_name: str, owner_id: int):
        # Verifiy connection to database
        assert self.con is not None and self.cur is not None

        owner_search = self.cur.execute(
            """
            SELECT * FROM users where discord_id = ?
            """
            , [str(owner_id)]
        )
        if owner_search.arraysize < 1:
            raise Exception(f"owner_id: {owner_id} not found in users table!")
        owner_fk = owner_search.fetchone()[0]

        self.cur.execute(
            """
            INSERT OR IGNORE INTO servers (discord_id, name, owner) VALUES (?,?,?)
            """
            , (server_id, server_name, owner_fk)
        )

    def register_users(self, users: Iterable[tuple[int, str]]):
        assert self.con is not None and self.cur is not None

        users = [(str(x[0]), x[1]) for x in users]
        self.cur.executemany(
            """
            INSERT OR IGNORE INTO users (discord_id, name) values (?,?)
            """
            , users
        )

    def register_memberships(self, server_id: int, users: Iterable[int]):
        assert self.con is not None and self.cur is not None

        server_fk = self.cur.execute(
            """
            SELECT id FROM servers where discord_id = ?
            """
            , [str(server_id)]
        ).fetchone()[0]
        users = [[str(u)] for u in users]
        users_fk = []
        for u in users:
            users_fk.append(self.cur.execute(
                """
                SELECT id FROM users where discord_id in (?)
                """
                , u
            ).fetchone()[0])

        users_fk = [(server_fk, u, 'Default') for u in users_fk]
        self.cur.executemany(
            """
            INSERT OR IGNORE INTO user_membership (server_id, user_id, perm_level) VALUES (?, ?, ?)
            """
            , users_fk
        )

    def remove_membership(self, server_id: int, user_id: int):
        assert self.con is not None and self.cur is not None

        server_fk = self.cur.execute(
            """
            SELECT id FROM servers where discord_id = ?
            """
            , [str(server_id)]
        ).fetchone()[0]
        user_fk = self.cur.execute(
            """
            SELECT id FROM users where discord_id in (?)
            """, [str(user_id)]
        ).fetchone()[0]

        self.cur.execute(
            """
            DELETE FROM user_membership
            where user_id = ? and server_id = ?
            """, [user_fk, server_fk]
        )

    def register_song(self, song, user_discord_id: int, server_discord_id: int):
        assert self.con is not None and self.cur is not None

        user_fk, server_fk = self.cur.execute(
            """
            SELECT u.id, s.id from user_membership
            join servers s on s.id = user_membership.server_id
            join users u on u.id = user_membership.user_id
            where u.discord_id = ? and s.discord_id = ? limit 1
            """
            , [str(user_discord_id), str(server_discord_id)]
        ).fetchone()

        self.cur.execute(
            """
            INSERT INTO songs (server, requestee, date_requested, video_id, video_name, video_len)
            VALUES (?, ?, ?, ?, ?, ?)
            """
            , [server_fk, user_fk, datetime.now().isoformat(), song.yt_id, song.name, song.duration]
        )
        return self.cur.lastrowid

    def log_command(self, command: str, user_discord_id: int, server_discord_id: int):
        assert self.con is not None and self.cur is not None

        user_fk, server_fk = self.cur.execute(
            """
            SELECT u.id, s.id from user_membership
            join servers s on s.id = user_membership.server_id
            join users u on u.id = user_membership.user_id
            where u.discord_id = ? and s.discord_id = ? limit 1
            """
            , [str(user_discord_id), str(server_discord_id)]
        ).fetchone()

        self.cur.execute(
            """
            INSERT INTO command_log (server, writer, command, date_issued) values (?, ?, ?, ?)
            """
            , [server_fk, user_fk, command, datetime.now().isoformat()]
        )

    def get_top_songs_local(self, user_discord_id: int, server_discord_id: int, amount=10):
        assert self.con is not None and self.cur is not None

        amount = amount if amount < 1000 else 10
        user_fk, server_fk = self.cur.execute(
            """
            SELECT u.id, s.id from user_membership
            join servers s on s.id = user_membership.server_id
            join users u on u.id = user_membership.user_id
            where u.discord_id = ? and s.discord_id = ? limit 1
            """
            , [str(user_discord_id), str(server_discord_id)]
        ).fetchone()

        return self.cur.execute(
            """
            SELECT songs.video_name, songs.video_id, count(video_id) from songs
                join users u on u.id = songs.requestee
                join servers s on s.id = songs.server
                where u.id = ? and s.id = ?
                group by video_id
                order by count(video_id) desc
                limit ?
            """
            , [user_fk, server_fk, amount]
        )

    def get_top_songs_global(self, user_discord_id: int, amount=10):
        assert self.con is not None and self.cur is not None

        amount = amount if amount < 1000 else 10
        user_fk = self.cur.execute(
            """
            SELECT id from users
            where discord_id = ? limit 1
            """
            , [str(user_discord_id)]
        ).fetchone()[0]

        return self.cur.execute(
            """
            SELECT songs.video_name, songs.video_id, count(video_id) from songs
                join users u on u.id = songs.requestee
                where u.id = ?
                group by video_id
                order by count(video_id) desc
                limit ?
            """
            , [user_fk, amount]
        )

    def get_top_songs_server(self, server_discord_id: int, amount=10):
        assert self.con is not None and self.cur is not None

        amount = amount if amount < 1000 else 10
        server_fk = self.cur.execute(
            """
            SELECT id from servers
            where discord_id = ? limit 1
            """
            , [str(server_discord_id)]
        ).fetchone()[0]

        return self.cur.execute(
            """
            select songs.video_name, songs.video_id, count(video_id) from songs
                join servers s on s.id = songs.server
                where s.id = ?
                group by video_id
                order by count(video_id) desc
                limit ?
            """
            , [server_fk, amount]
        )

    def get_all_user_servers(self, usr_db_id: int) -> list[int]:
        assert self.con is not None and self.cur is not None

        return [
            int(x[0]) for x in
            self.cur.execute(
                """
                SELECT s.discord_id from user_membership
                join servers s on s.id = user_membership.server_id
                where user_id = ?
                """, [usr_db_id]
            ).fetchall()
        ]

    def register_song_listeners(self, db_song_id: int, user_ids: tuple[int]):
        assert self.con is not None and self.cur is not None

        user_ids = [
            (r[0], db_song_id) for r in
            self.cur.execute(
                """
                SELECT id from users
                WHERE discord_id in (
                """ + ",".join(["?"] * len(user_ids)) + ")",
                user_ids
            ).fetchall()
        ]

        self.cur.executemany(
            """
            INSERT INTO song_listener (listener_user, song)
            VALUES (?, ?)
            """, user_ids
        )

    def register_new_web_key(self, user_id: int, key: str, token: str):
        """
        Returns false if no data was inserted
        """
        assert self.con is not None and self.cur is not None

        user_fk = self.cur.execute(
            """
            SELECT id from users
            where discord_id = ? limit 1
            """, [user_id]
        ).fetchone()[0]

        token_exp_date = datetime.now() + timedelta(minutes=5)
        key_exp_date = datetime.now() + timedelta(days=90)
        self.cur.execute(
            """
            INSERT into webui_session_keys (discord_user, key, key_expiration_date, request_token, request_token_expiration_date, key_validated)
            VALUES (?, ?, ?, ?, ?, ?)
            """, (user_fk, key, key_exp_date, token, token_exp_date, 0)
        )
        return True

    def get_web_keys_status(self, user_id: int) -> Optional[WebKeyStatus]:
        assert self.con is not None and self.cur is not None

        user_fk = self.cur.execute(
            """
            SELECT id from users
            where discord_id = ? limit 1
            """, [user_id]
        ).fetchone()[0]

        status = self.cur.execute(
            """
            SELECT id, key_expiration_date, request_token, request_token_expiration_date, key_validated from webui_session_keys
            WHERE discord_user = ? limit 1
            """, [user_fk]
        ).fetchone()
        if status is None:
            return None
        return WebKeyStatus(
            id=status[0],
            key_expiration_date=status[1],
            request_token=status[2],
            request_token_expiration_date=status[3],
            validated=status[4]
        )

    def regenerate_token(self, db_key_id: int, token: int):
        assert self.con is not None and self.cur is not None

        token_exp_date = datetime.now() + timedelta(minutes=5)
        self.cur.execute(
            """
            UPDATE webui_session_keys SET
            request_token = ?,
            request_token_expiration_date = ?
            WHERE id = ?
            """, (token, token_exp_date, db_key_id)
        )

    def regenerate_key(self, db_key_id: int, key: str):
        assert self.con is not None and self.cur is not None

        key_exp_date = datetime.now() + timedelta(days=90)
        self.cur.execute(
            """
            UPDATE webui_session_keys SET
            key = ?,
            key_validated = ?,
            key_expiration_date = ?
            WHERE id = ?
            """, (key, 0, key_exp_date, db_key_id)
        )

    def get_web_key_with_token(self, token: str):
        assert self.con is not None and self.cur is not None

        status = self.cur.execute(
            """
            SELECT id, key_expiration_date, request_token, request_token_expiration_date, key_validated, key from webui_session_keys
            WHERE request_token = ? limit 1
            """, [token]
        ).fetchone()
        if status is None:
            return None
        return WebKeyStatus(
            id=status[0],
            key_expiration_date=status[1],
            request_token=status[2],
            request_token_expiration_date=status[3],
            validated=status[4],
            key=status[5]
        )

    def validate_key(self, db_id: int):
        assert self.con is not None and self.cur is not None

        self.cur.execute(
            """
            UPDATE webui_session_keys SET
            key_validated = ?
            WHERE id = ?
            """, (1, db_id)
        )

    def auth_key(self, key: str) -> tuple[bool, Optional[WebKeyStatus]]:
        """
        Used to authenticate with key, checks for validity
        """
        assert self.con is not None and self.cur is not None

        search = self.cur.execute(
            """
            SELECT discord_user, key_expiration_date, request_token, request_token_expiration_date, key_validated from webui_session_keys
            where key = ? limit 1
            """, [key]
        ).fetchone()

        if search is None:
            return False, None
        if not bool(search[4]):
            return False, None
        if datetime.fromisoformat(search[1]) < datetime.now():
            return False, None
        return True, WebKeyStatus(
            id=search[0],
            key_expiration_date=search[1],
            request_token=search[2],
            request_token_expiration_date=search[3],
            validated=search[4],
            key=None
        )

database = DB()