COL_AWARD_HIGH = "col_award_high"
COL_AWARD_LOW  = "col_award_low"
COL_ERROR      = "col_error"

class TikzTable(object):
    COLORING_OPTIONS = (COL_AWARD_HIGH, COL_AWARD_LOW, COL_ERROR)

    def __init__(self, title, columns,
                 noncomp=[],
                 col_fmt_fn=None,
                 col_rule="ZColor2",
                 fmt_good=None,
                 fmt_bad=None,
                 fmt_ncomp=None,
                 transposed=False):
        assert type(title) is str
        assert type(columns) is list

        self.col_rule  = col_rule
        if fmt_good is None:
            self.fmt_good = lambda x: "{\\color{ZColorGreen}%s}" % x
        else:
            self.fmt_good = fmt_good
        if fmt_bad is None:
            self.fmt_bad = lambda x: "{\\color{ZColorRed}%s}" % x
        else:
            self.fmt_bad = fmt_bad
        if fmt_ncomp is None:
            self.fmt_ncomp = lambda x: "{\\color{ZGray3}%s}" % x
        else:
            self.fmt_ncomp = fmt_ncomp
        self.cat_title = title
        self.columns   = columns
        self.rows      = []
        self.competing = {c: c not in noncomp
                          for c in columns}
        self.transposed = transposed

        if col_fmt_fn is None:
            self.col_fmt_fn = lambda x: x
        else:
            self.col_fmt_fn = col_fmt_fn

    def add_row(self, title, data, format_fn, coloring, notes={}):
        assert type(title) is str
        assert type(data) is dict
        assert coloring is None or coloring in TikzTable.COLORING_OPTIONS

        competing_data = {col : item
                          for col, item in data.iteritems()
                          if col in self.columns and self.competing[col]}

        row = {"kind" : "row",
               "title" : title,
               "data"  : {}}
        for col, item in data.iteritems():
            if col not in self.columns:
                continue
            txt = format_fn(item)
            if not self.competing[col]:
                txt = self.fmt_ncomp(txt)
            elif coloring == COL_ERROR:
                if item == 0.0:
                    txt = self.fmt_good(txt)
                else:
                    txt = self.fmt_bad(txt)
            elif coloring == COL_AWARD_HIGH:
                if item == max(competing_data.itervalues()):
                    txt = self.fmt_good(txt)
            elif coloring == COL_AWARD_LOW:
                if item == min(competing_data.itervalues()):
                    txt = self.fmt_good(txt)
            if col in notes:
                txt += "$^%s$" % notes[col]
            row["data"][col] = txt

        self.rows.append(row)

    def start_footer(self):
        self.rows.append({"kind" : "rule"})

    def emit(self):
        def tr_x(x):
            if x == 0:
                return 0.0
            else:
                return 2.0 + float(x - 1) * 0.9

        def tr_y(y):
            return float(-y) * 0.35

        def emit_box(x, y, txt):
            if self.transposed:
                x, y = y, x

            title = (y == 0) and x > 0
            n_atr = ["anchor=west"]
            # n_atr.append("fill=black!10")
            if title:
                n_atr.append("rotate=65")
            n = r"\node[%s]" % ",".join(n_atr)

            final_x = tr_x(x)
            final_y = tr_y(y)
            if title:
                final_x += 0.25

            n += " at (%.3f, %.3f)" % (final_x, final_y)

            n += " {\\tiny %s};" % txt
            rv.append(n)

        def emit_hrule(after_y):
            if self.transposed:
                width = len(self.rows)
            else:
                width = len(self.columns)

            r = r"\draw[%s,thick]" % self.col_rule

            y = (tr_y(after_y) + tr_y(after_y + 1)) / 2.0 + 0.05
            r += " (%.3f, %.3f)" % (tr_x(0), y)
            r += " -- (%.3f, %.3f)" % (tr_x(width + 1), y)
            r += ";"

            rv.append(r)

        rv = [r"\begin{tikzpicture}"]
        emit_box(0, 0, self.cat_title)
        for col_id, col in enumerate(self.columns):
            emit_box(col_id + 1, 0, self.col_fmt_fn(col))
        emit_hrule(0)

        row_id = 0
        for row in self.rows:
            if row["kind"] == "row":
                row_id += 1
                emit_box(0, row_id, row["title"])
                for col, txt in row["data"].iteritems():
                    emit_box(self.columns.index(col) + 1,
                             row_id,
                             txt)
            elif row["kind"] == "rule":
                emit_hrule(row_id)

        rv.append(r"\end{tikzpicture}")
        return "\n".join(rv)

    def emit_plain(self, filename, cwidth=None):
        tbl = {}
        def put(x, y, txt):
            if self.transposed:
                x, y = y, x
            if y not in tbl:
                tbl[y] = {x: txt}
            else:
                tbl[y][x] = txt

        # Heading
        put(0, 0, self.cat_title)
        for i, txt in enumerate(self.columns):
            put(i+1, 0, self.col_fmt_fn(txt))

        # Rows
        row_id = 0
        for row in self.rows:
            if row["kind"] == "row":
                row_id += 1
                put(0, row_id, row["title"])
                for col, txt in row["data"].iteritems():
                    put(self.columns.index(col) + 1, row_id, txt)

        with open(filename, "w") as fd:
            width = len(tbl[0])
            na   = r"\noalign{\smallskip}"
            rule = r"\hline"

            if cwidth is None:
                fd.write("\\begin{tabular}{%s}\n" % ("l" * width))
            else:
                col = "p{%s}" % cwidth
                fd.write("\\begin{tabular}{l|%s}\n" % (col * (width - 1)))
            fd.write(rule + na + "\n")
            for row_id in xrange(len(tbl)):
                for col_id in xrange(width):
                    if col_id > 0:
                        fd.write(" & ")
                    if col_id not in tbl[row_id]:
                        fd.write("")
                    else:
                        fd.write(tbl[row_id][col_id])
                fd.write("\\\\\n")
                if row_id == 0:
                    fd.write(na + rule + na + "\n")
            fd.write(rule + "\n")
            fd.write("\\end{tabular}\n")


import pandas as pd
import numpy as np
import pickle

import eif
from hdbscan import HDBSCAN
from pyod.models.auto_encoder import AutoEncoder
from pyod.models.iforest import IForest
from pyod.models.knn import KNN
from pyod.models.lof import LOF
from pyod.models.pca import PCA

from scripts.Params import Params

class ModelSelector():
    '''
    Loads and trains the anomaly detection model according to the parameters given in input.

    '''

    def __init__(self, df: pd.DataFrame, seq_len:int = 1):
        '''
        Constructor. Calls the superclass constructor.

        :param df: dataframe to extract features from.
        '''
        super(ModelSelector, self).__init__()
        self.df = df.copy(deep=True)
        self.seq_len = seq_len

        print()
        print('###########################################')
        print(' Step 3: Training model')
        print()

    def train_model(self, model_name):
        '''
        Calls the feature engineering operations made available within the class in a sequential way. This
        specific sequence is currently considered as default for this step.

        Applies pearson correlation feature selection, normalizes the base dataframe, extract transaction
        sequences as dataframes, normalizes them. Then extracts umap visualization for each dataframe and
        saves it on the file system.

        :param seq_lens: list of lengths for sequences to be generated.

        '''

        self.model_name = model_name
        self.select_model(model_name, self.df)
        self.save_model_data()

    def select_model(self, model_name, data):
        print(f'> Training {model_name}...')
        train_model_method = getattr(self, f'train_{model_name}')
        model, labels = train_model_method(data)
        self.model = model
        self.outliers, self.inliers = labels

    #################################################################################################
    ## SELECTED MODELS

    def train_knn(self, data):
        knn_model = KNN(
            contamination = Params.CONTAMINATION.value,
            #n_neighbors = 15,
            method = 'median',
            random_state = Params.RANDOM_STATE.value
        )
        knn_model.fit(data)
        knn_outliers = np.where(knn_model.labels_ == 1)[0]
        knn_inliers = np.where(knn_model.labels_ == 0)[0]

        return knn_model, (knn_outliers, knn_inliers)

    def train_local_outlier_factor(self, data):
        lof_model = LOF(
            contamination = Params.CONTAMINATION.value,
            random_state = Params.RANDOM_STATE.value
        )
        lof_model.fit(data)
        lof_outliers = np.where(lof_model.labels_ == 1)[0]
        lof_inliers = np.where(lof_model.labels_ == 0)[0]

        return lof_model, (lof_outliers, lof_inliers)

    def train_pca(self, data):
        pca_model = PCA(
            contamination = 0.1, #Params.CONTAMINATION.value,
            whiten = True,
            random_state = Params.RANDOM_STATE.value
        )
        pca_model.fit(data)
        pca_outliers = np.where(pca_model.labels_ == 1)[0]
        pca_inliers = np.where(pca_model.labels_ == 0)[0]

        return pca_model, (pca_outliers, pca_inliers)

    def train_hdbscan(self, data):
        clusterer = HDBSCAN(min_cluster_size=15).fit(data)

        self.glosh = False
        if self.glosh:
            threshold = pd.Series(clusterer.outlier_scores_).quantile(1 - Params.CONTAMINATION.value)
            labels = (clusterer.outlier_scores_ > threshold).astype(int)
        else:
            labels = (clusterer.labels_ == -1).astype(int)
        hdbscan_outliers = np.where(labels == 1)[0]
        hdbscan_inliers = np.where(labels == 0)[0]

        return clusterer, (hdbscan_outliers, hdbscan_inliers)

    def train_isolation_forests(self, data):
        ifs_model = IForest(
            contamination = Params.CONTAMINATION.value,
            random_state = Params.RANDOM_STATE.value
        )
        ifs_model.fit(data)
        ifs_outliers = np.where(ifs_model.labels_ == 1)[0]
        ifs_inliers = np.where(ifs_model.labels_ == 0)[0]

        return ifs_model, (ifs_outliers, ifs_inliers)

    def train_extended_isolation_forest(self, data):
        eif_model = eif.iForest(
            data,
            ntrees = 200,
            sample_size = 256,
            ExtensionLevel = 1
        )
        eif_outliers_probs = eif_model.compute_paths(X_in=data)
        n_outliers = Params.CONTAMINATION.value * Params.ROW_SLICE_SIZE.value

        eif_outliers = eif_outliers_probs.argsort()[-n_outliers:][::-1]
        eif_inliers = eif_outliers_probs.argsort()[:-n_outliers][::-1]

        return eif_model, (eif_outliers, eif_inliers)

    def train_autoencoders(self, data):
        ae_model = AutoEncoder(
            hidden_neurons = [17,12,12,17],
            epochs = 15,
            contamination = 0.1,  # Params.CONTAMINATION.value,
            random_state = Params.RANDOM_STATE.value
        )
        ae_model.fit(data)
        ae_outliers = np.where(ae_model.labels_ == 1)[0]
        ae_inliers = np.where(ae_model.labels_ == 0)[0]

        return ae_model, (ae_outliers, ae_inliers)

    #################################################################################################
    ## UTILITIES

    def save_model_data(self, filepath: str = Params.OUTPUT_FILEPATH.value, filename: str ='model_data_1trans'):
        '''
        Encodes the data related to the model, including the metadata about the model name, the model itself,
        the outliers and inliers identified with it

        :param filepath: location path of the object to be stored.
        :param filename: filename of the object to be stored.

        '''
        model_data = {
            'model_name': self.model_name,
            'model': self.model,
            'outliers': self.outliers,
            'inliers': self.inliers
        }

        try:
            with open(f'{filepath}{filename}.pickle', 'wb') as handle:
                pickle.dump(model_data, handle, protocol=pickle.HIGHEST_PROTOCOL)
            print('> Model data saved successfully!')
        except:
            print('> Issue meanwhile trying to save the model data...')

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


import numpy as np
import math

class Cell:

    def __init__(self, rowindex, colindex, dem_ng, cellsize, flux, z_delta, parent, alpha, exp, flux_threshold, max_z_delta, startcell):
        '''This class handles the spreading over the DEM!
        Depending on the process different alpha angles are used for energy dissipation.'''
        self.rowindex = rowindex
        self.colindex = colindex
        self.altitude = dem_ng[1, 1]
        self.dem_ng = dem_ng
        self.cellsize = cellsize
        self.tan_beta = np.zeros_like(self.dem_ng)
        self.dist = np.zeros_like(self.dem_ng)
        self.persistence = np.zeros_like(self.dem_ng)
        self.r_t = np.zeros_like(self.dem_ng)
        self.no_flow = np.ones_like(self.dem_ng)
        self.flux = flux
        self.z_delta = z_delta
        self.alpha = float(alpha)
        self.exp = int(exp)
        self.max_z_delta = float(max_z_delta)
        self.flux_threshold = float(flux_threshold)
        self.min_distance = 0
        self.max_distance = 0
        self.min_gamma = 0
        self.max_gamma = 0
        self.sl_gamma = 0

        if type(startcell) == bool:  # check, if start cell exist (start cell is release point)
            self.is_start = True  # set is_start to True
        else:
            self.startcell = startcell  # give startcell to cell
            self.is_start = False  # set is_start to False

        self.parent = []
        if type(parent) == Cell:
            self.parent.append(parent)

    def add_os(self, flux):
        self.flux += flux

    def add_parent(self, parent):
        self.parent.append(parent)

    def calc_fp_travelangle(self):
        dist_min = []
        dh = self.startcell.altitude - self.altitude
        for parent in self.parent:
            dx = abs(parent.colindex - self.colindex)
            dy = abs(parent.rowindex - self.rowindex)
            dist_min.append(math.sqrt(dx ** 2 + dy ** 2) * self.cellsize + parent.min_distance)
        self.min_distance = np.amin(dist_min)
        self.max_gamma = np.rad2deg(np.arctan(dh / self.min_distance))

    def calc_sl_travelangle(self):
        dx = abs(self.startcell.colindex - self.colindex)
        dy = abs(self.startcell.rowindex - self.rowindex)
        dh = self.startcell.altitude - self.altitude

        ds = math.sqrt(dx ** 2 + dy ** 2) * self.cellsize
        self.sl_gamma = np.rad2deg(np.arctan(dh / ds))

    def calc_z_delta(self):
        self.z_delta_neighbour = np.zeros((3, 3))
        self.z_gamma = self.altitude - self.dem_ng
        ds = np.array([[np.sqrt(2), 1, np.sqrt(2)], [1, 0, 1], [np.sqrt(2), 1, np.sqrt(2)]])
        tan_alpha = np.tan(np.deg2rad(self.alpha))
        self.z_alpha = ds * self.cellsize * tan_alpha
        self.z_delta_neighbour = self.z_delta + self.z_gamma - self.z_alpha
        self.z_delta_neighbour[self.z_delta_neighbour < 0] = 0
        self.z_delta_neighbour[self.z_delta_neighbour > self.max_z_delta] = self.max_z_delta

    def calc_tanbeta(self):
        ds = np.array([[np.sqrt(2), 1, np.sqrt(2)], [1, 1, 1], [np.sqrt(2), 1, np.sqrt(2)]])
        distance = ds * self.cellsize

        beta = np.arctan((self.altitude - self.dem_ng) / distance) + np.deg2rad(90)
        self.tan_beta = np.tan(beta/2)

        self.tan_beta[self.z_delta_neighbour <= 0] = 0
        self.tan_beta[self.persistence <= 0] = 0
        self.tan_beta[1, 1] = 0
        if abs(np.sum(self.tan_beta)) > 0:
            self.r_t = self.tan_beta ** self.exp / np.sum(self.tan_beta ** self.exp)

    def calc_persistence(self):
        self.persistence = np.zeros_like(self.dem_ng)
        if self.is_start:
            self.persistence += 1
        elif self.parent[0].is_start:
            self.persistence += 1
        else:
            for parent in self.parent:
                dx = (parent.colindex - self.colindex)
                dy = (parent.rowindex - self.rowindex)

                self.no_flow[dy + 1,dx + 1] = 0  # 3x3 Matrix of ones, every parent gets a 0, so no flow to a parent field.

                maxweight = parent.z_delta
                # Old Calculation
                if dx == -1:
                    if dy == -1:
                        self.persistence[2, 2] += maxweight
                        self.persistence[2, 1] += 0.707 * maxweight
                        self.persistence[1, 2] += 0.707 * maxweight
                    if dy == 0:
                        self.persistence[1, 2] += maxweight
                        self.persistence[2, 2] += 0.707 * maxweight
                        self.persistence[0, 2] += 0.707 * maxweight
                    if dy == 1:
                        self.persistence[0, 2] += maxweight
                        self.persistence[0, 1] += 0.707 * maxweight
                        self.persistence[1, 2] += 0.707 * maxweight

                if dx == 0:
                    if dy == -1:
                        self.persistence[2, 1] += maxweight
                        self.persistence[2, 0] += 0.707 * maxweight
                        self.persistence[2, 2] += 0.707 * maxweight
                    if dy == 1:
                        self.persistence[0, 1] += maxweight
                        self.persistence[0, 0] += 0.707 * maxweight
                        self.persistence[0, 2] += 0.707 * maxweight

                if dx == 1:
                    if dy == -1:
                        self.persistence[2, 0] += maxweight
                        self.persistence[1, 0] += 0.707 * maxweight
                        self.persistence[2, 1] += 0.707 * maxweight
                    if dy == 0:
                        self.persistence[1, 0] += maxweight
                        self.persistence[0, 0] += 0.707 * maxweight
                        self.persistence[2, 0] += 0.707 * maxweight
                    if dy == 1:
                        self.persistence[0, 0] += maxweight
                        self.persistence[0, 1] += 0.707 * maxweight
                        self.persistence[1, 0] += 0.707 * maxweight

# =============================================================================
#                 # New Calculation:
#                 theta_child = np.array([[np.pi*5/4, np.pi*3/2 , np.pi*7/4], [np.pi, 0, 0], [np.pi*3/4, np.pi/2 , np.pi/4]])
#                 theta_parent = (np.arctan2(dy, dx))
#
#                 pers1 = theta_parent - theta_child - np.pi
#                 pers = np.zeros((3,3))
#
#                 for idx, element in np.ndenumerate(pers1):
#                     pers[idx] = max(0, np.cos(element))
#                     if pers[idx] < 2*np.finfo(np.float64).eps:
#                         pers[idx] = 0
#                 pers[1, 1] = 0
#                 self.persistence += pers * maxweight
# =============================================================================

    def calc_distribution(self):

        self.calc_z_delta()
        self.calc_persistence()
        self.persistence *= self.no_flow
        self.calc_tanbeta()
        #print(self.persistence)

        if not self.is_start:
            self.calc_fp_travelangle()
            self.calc_sl_travelangle()

        threshold = self.flux_threshold
        if np.sum(self.r_t) > 0:
            self.dist = (self.persistence * self.r_t) / np.sum(self.persistence * self.r_t) * self.flux
        # This lines handle if a distribution to a neighbour cell is lower then the threshold, so we don´t lose
        # flux.
        # The flux of this cells will then spread equally to all neighbour cells
        count = ((0 < self.dist) & (self.dist < threshold)).sum()
        mass_to_distribute = np.sum(self.dist[self.dist < threshold])
        '''Checking if flux is distributed to a field that isn't taking in account, when then distribute it equally to
         the other fields'''
        if mass_to_distribute > 0 and count > 0:
            self.dist[self.dist > threshold] += mass_to_distribute / count
            self.dist[self.dist < threshold] = 0
        if np.sum(self.dist) < self.flux and count > 0:
            self.dist[self.dist > threshold] += (self.flux - np.sum(self.dist))/count

        row_local, col_local = np.where(self.dist > threshold)

        return self.rowindex - 1 + row_local, self.colindex - 1 + col_local, self.dist[row_local, col_local], self.z_delta_neighbour[row_local, col_local]


from image import Image
from numpy import clip
from itertools import product

class Dithering:
    def __init__(self, image: Image, colors_qty: int):
        self.image = image
        self.factor = image.colors_per_channel/(colors_qty - 1)

    def dither(self) -> []:
        for (y, x) in product(range(0, self.image.width - 1),
                              range(1, self.image.height - 1)):
            self._quantize_pixel(x, y)

    def _quantize_pixel(self, x: int, y: int) -> None:
        old_pixel = self.image.raw_image[x][y]
        new_pixel = self._find_closest_colors(old_pixel)
        quant_error = old_pixel - new_pixel
        self.image.raw_image[x][y] = new_pixel

        self._propagate_error(x + 1, y, quant_error * 0.4375)
        self._propagate_error(x - 1, y + 1, quant_error * 0.1875)
        self._propagate_error(x, y + 1, quant_error * 0.3125)
        self._propagate_error(x + 1, y + 1, quant_error * 0.0625)

    def _find_closest_colors(self, pixel: []) -> []:
        return [round(color/self.factor)*self.factor for color in pixel]

    def _propagate_error(self, x: int, y: int, quant_error: []) -> None:
        clip(self.image.raw_image[x][y] + quant_error,
             0, self.image.colors_per_channel,
             out=self.image.raw_image[x][y])


# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def isPalindrome(self, head: ListNode) -> bool:
        nodes = []
        while True:
            if head==None: break
            else:
                nodes.append(head.val)
                head = head.next
        if len(nodes) == 0: return

        return nodes == list(reversed(nodes))


first_image = True

while True :
    num_line = int(input())

    if num_line == 0 :
        break

    if not first_image :
        print()

    first_image = False

    size = 0
    initialized_size = False
    error = False

    for _ in range(num_line):
        input_values = input().split()
        char_type = input_values[0]
        line_data = list(map(int,input_values[1:]))
        count = 0
        for data in line_data :
            print(char_type*data, end='')
            char_type = '.' if char_type == '#' else '#'
            count += data
        print()
        if initialized_size :
            if size != count :
                error = True
        else :
            initialized_size = True
            size = count

    if error :
        print('Error decoding image')


import os
import tkinter as tk
from tkinter import messagebox, filedialog
from PIL import Image, ImageTk, ImageFilter, ImageEnhance
import shutil
from image_processing import load_images_from_directory, apply_filter_blur, apply_filter_sharpen, apply_filter_edges, apply_filter_emboss, apply_filter_contour, apply_filter_greyscale

print('loaded image_viewer_app.py')

class ImageViewerApp(tk.Tk):
    def __init__(self):
        super().__init__()

        self.title("Image Viewer")
        self.geometry("1400x800")

        self.current_image = None
        self.image_list = load_images_from_directory()
        self.current_index = 0

        self.create_widgets()
        self.load_image()
        self.crop_rectangle = None

    def create_widgets(self):
        button_styles = {
            "width": 30,
            "height": 3,
            "bg": "#197fd4",
            "fg": "black",
            "relief": tk.RAISED,
            "bd": 2,
            "font": ("Arial", 12, "bold"),
        }

        self.thumbnail_frame = tk.Frame(self)
        self.thumbnail_frame.pack(side=tk.LEFT, padx=2, fill=tk.Y)

        self.thumbnail_canvas = tk.Canvas(self.thumbnail_frame, width=150)
        self.thumbnail_canvas.pack(side=tk.LEFT, fill=tk.BOTH)

        self.scrollbar = tk.Scrollbar(self.thumbnail_frame, orient="vertical", command=self.thumbnail_canvas.yview, width=20)
        self.scrollbar.pack(side=tk.LEFT, fill=tk.Y)

        self.thumbnail_canvas.configure(yscrollcommand=self.scrollbar.set)
        self.thumbnail_canvas.bind('<Configure>', lambda e: self.thumbnail_canvas.configure(scrollregion=self.thumbnail_canvas.bbox('all')))

        self.inner_thumbnail_frame = tk.Frame(self.thumbnail_canvas)
        self.thumbnail_canvas.create_window((0, 0), window=self.inner_thumbnail_frame, anchor='nw')

        self.button_frame = tk.Frame(self)
        self.button_frame.pack(side=tk.LEFT, padx=5, fill=tk.Y)

        self.main_frame = tk.Frame(self)
        self.main_frame.pack(side=tk.LEFT, padx=5, fill=tk.BOTH, expand=True)

        self.label = tk.Label(self.main_frame)
        self.label.pack()

        self.reset_button = tk.Button(self.button_frame, text="Възстанови", command=self.reset_image)
        self.reset_button.pack(pady=5)

        self.info_button = tk.Button(self.button_frame, text="Информация", command=self.show_image_info)
        self.info_button.pack(pady=5)

        self.rotate_button = tk.Button(self.button_frame, text="Завърти на 90 градуса", command=self.rotate_image)
        self.rotate_button.pack(pady=5)

        self.flip_horizontal_button = tk.Button(self.button_frame, text="Хоризонтално огледално обръщане",
                                                command=self.flip_image_horizontal)
        self.flip_horizontal_button.pack(pady=5)

        self.flip_vertical_button = tk.Button(self.button_frame, text="Вертикално огледално обръщане",
                                              command=self.flip_image_vertical)
        self.flip_vertical_button.pack(pady=5)

        self.right_button_frame = tk.Frame(self)
        self.right_button_frame.pack(side=tk.RIGHT, fill=tk.Y)

        self.selected_filter = tk.StringVar(self.button_frame)
        self.selected_filter.set("Избери филтър")

        self.filter_functions = {
            "Blur": apply_filter_blur,
            "Sharpen": apply_filter_sharpen,
            "Find Edges": apply_filter_edges,
            "Emboss": apply_filter_emboss,
            "Contour": apply_filter_contour,
            "Greyscale": apply_filter_greyscale,
        }

        self.filter_menu = tk.OptionMenu(self.right_button_frame, self.selected_filter, *self.filter_functions.keys())
        self.filter_menu.config(width=22, height=3)
        self.filter_menu.pack(pady=2)

        self.apply_filter_button = tk.Button(self.right_button_frame, text="Приложи филтър",
                                             command=self.apply_selected_filter)
        self.apply_filter_button.pack(pady=5)

        self.open_button = tk.Button(self.button_frame, text="Отвори", command=self.open_image)
        self.open_button.pack(pady=5)

        self.save_button = tk.Button(self.right_button_frame, text="Запази снимката", command=self.save_image)
        self.save_button.pack(pady=5)

        self.delete_button = tk.Button(self.right_button_frame, text="Изтрий", command=self.delete_image)
        self.delete_button.pack(pady=5)

        for index, image_path in enumerate(self.image_list):
            thumbnail = self.create_thumbnail(image_path, fixed_width=100)
            thumbnail_label = tk.Label(self.inner_thumbnail_frame, image=thumbnail, cursor="hand2")
            thumbnail_label.image = thumbnail
            thumbnail_label.bind('<Button-1>', lambda event, idx=index: self.select_image(event, idx))
            thumbnail_label.pack(side=tk.TOP, pady=1)

        self.crop_button = tk.Button(self.button_frame, text="Изрежи", command=self.enable_crop_mode)
        self.crop_button.pack(pady=5)

        self.zoom_in_button = tk.Button(self.button_frame, text="Увеличи", command=self.zoom_in)
        self.zoom_in_button.pack(pady=5)

        self.zoom_out_button = tk.Button(self.button_frame, text="Намали", command=self.zoom_out)
        self.zoom_out_button.pack(pady=5)

        self.brightness_scale = tk.Scale(self.right_button_frame, from_=-255, to=255, orient=tk.HORIZONTAL, command=self.adjust_brightness, length=300)

        self.brightness_scale.set(0)
        self.brightness_scale.pack(pady=5)

        self.contrast_scale = tk.Scale(self.right_button_frame, from_=0.1, to=3.0, resolution=0.01,
                                       orient=tk.HORIZONTAL, command=self.adjust_contrast, length=300)
        self.contrast_scale.set(1)
        self.contrast_scale.pack(pady=5)

        self.image_label = tk.Label(self, image=None)
        self.image_label.pack()

        #Конфигурация на бутоните
        self.reset_button.config(**button_styles)
        self.info_button.config(**button_styles)
        self.rotate_button.config(**button_styles)
        self.flip_horizontal_button.config(**button_styles)
        self.flip_vertical_button.config(**button_styles)
        self.apply_filter_button.config(**button_styles)
        self.open_button.config(**button_styles)
        self.save_button.config(**button_styles)
        self.delete_button.config(**button_styles)
        self.crop_button.config(**button_styles)
        self.zoom_in_button.config(**button_styles)
        self.zoom_out_button.config(**button_styles)

    def create_thumbnail(self, image_path, fixed_width=100):
        img = Image.open(image_path)
        aspect_ratio = img.height / img.width
        new_height = int(fixed_width * aspect_ratio)
        img = img.resize((fixed_width, new_height), Image.ANTIALIAS)
        thumbnail = ImageTk.PhotoImage(img)
        return thumbnail

    def select_image(self, event, index):
        self.current_index = index
        self.load_image()

    def load_image(self):
        image_path = self.image_list[self.current_index]
        self.current_image = Image.open(image_path)

        # Resize the image while maintaining its aspect ratio
        fixed_width = 500  # Set the fixed width
        aspect_ratio = self.current_image.height / self.current_image.width
        new_height = int(fixed_width * aspect_ratio)
        self.current_image = self.current_image.resize((fixed_width, new_height), Image.ANTIALIAS)

        self.update_image()

    def show_image_info(self):
        image_path = self.image_list[self.current_index]
        image_name = os.path.basename(image_path)
        image_size = self.current_image.size
        image_mode = self.current_image.mode

        info_text = f"Име: {image_name}\nРазмер: {image_size}\nРежим на цветовете: {image_mode}"
        messagebox.showinfo("Информация за изображението", info_text)

    def rotate_image(self):

        self.current_image = self.current_image.rotate(90)
        self.update_image()

    def flip_image_horizontal(self):

        self.current_image = self.current_image.transpose(Image.FLIP_LEFT_RIGHT)
        self.update_image()

    def flip_image_vertical(self):

        self.current_image = self.current_image.transpose(Image.FLIP_TOP_BOTTOM)
        self.update_image()

    def apply_filter_blur(self):
        self.current_image = self.current_image.filter(ImageFilter.BLUR)
        self.update_image()

    def apply_filter_sharpen(self):
        self.current_image = self.current_image.filter(ImageFilter.SHARPEN)
        self.update_image()

    def apply_filter_edges(self):
        self.current_image = self.current_image.filter(ImageFilter.FIND_EDGES)
        self.update_image()

    def apply_filter_emboss(self):
        self.current_image = self.current_image.filter(ImageFilter.EMBOSS)
        self.update_image()

    def apply_filter_contour(self):
        self.current_image = self.current_image.filter(ImageFilter.CONTOUR)
        self.update_image()

    def apply_filter_greyscale(self):
        self.current_image = self.current_image.convert('L')
        self.update_image()

    def update_image(self, new_image=None):
        if new_image is not None:
            self.current_image = new_image

        self.tk_image = ImageTk.PhotoImage(self.current_image)
        self.image_label.config(image=self.tk_image)
        self.image_label.image = self.tk_image

    def reset_image(self):
        self.brightness_scale.set(0)  # Reset the brightness scale
        self.contrast_scale.set(1)  # Reset the contrast scale
        self.update_image()
        self.load_image()

    def apply_selected_filter(self):
        filter_name = self.selected_filter.get()

        if filter_name in self.filter_functions:
            self.current_image = self.filter_functions[filter_name](self.current_image)
            self.update_image()
        else:
            messagebox.showerror("Error", "Please select a valid filter.")

    def save_image(self):
        img_directory = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'img')
        initialdir = img_directory

        file_path = filedialog.asksaveasfilename(initialdir=initialdir, defaultextension=".png",
                                                 filetypes=[("PNG", "*.png"), ("JPEG", "*.jpg"), ("BMP", "*.bmp"),
                                                            ("All files", "*.*")])

        if file_path:
            self.current_image.save(file_path)
            self.refresh_thumbnail_list()

    def clear_thumbnail_list(self):
        for child in self.inner_thumbnail_frame.winfo_children():
            child.destroy()

    def refresh_thumbnail_list(self):
        self.clear_thumbnail_list()
        self.image_list = load_images_from_directory(img_folder='img')

        for index, image_path in enumerate(self.image_list):
            thumbnail = self.create_thumbnail(image_path)
            thumbnail_label = tk.Label(self.inner_thumbnail_frame, image=thumbnail, cursor="hand2")
            thumbnail_label.image = thumbnail
            thumbnail_label.bind('<Button-1>', lambda event, idx=index: self.select_image(event, idx))
            thumbnail_label.pack(side=tk.TOP, pady=1)

        self.thumbnail_canvas.update_idletasks()

    def open_image(self):
        file_path = filedialog.askopenfilename(
            filetypes=[("Images", ("*.jpg", "*.jpeg", "*.png", "*.bmp", "*.gif", "*.tiff", "*.ico")),
                       ("All files", "*.*")])
        if file_path:
            # Copy the image to the project folder
            file_name = os.path.basename(file_path)
            img_directory = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'img')
            new_file_path = os.path.join(img_directory, file_name)
            shutil.copy(file_path, new_file_path)

            # Add the new file path to the image list and update the current index
            self.image_list.append(new_file_path)
            self.current_index = len(self.image_list) - 1
            self.load_image()

            # Refresh the thumbnail list
            self.refresh_thumbnail_list()

    def delete_image(self):
        if not self.image_list:
            messagebox.showwarning("Внимание", "Няма изображения за изтриване.")
            return

        image_path = self.image_list[self.current_index]
        try:
            os.remove(image_path)
        except Exception as e:
            messagebox.showerror("Грешка", f"Изтриването на изображението не успя: {e}")
            return

        # Refresh the thumbnail list and scrollbar
        self.refresh_thumbnail_list()

        # Update the current index and load the next image
        self.current_index = min(self.current_index, len(self.image_list) - 1)
        if self.image_list:
            self.load_image()
        else:
            self.label.config(image="")

    def start_crop(self, event):
        if self.crop_rectangle:
            self.label.delete(self.crop_rectangle)
        self.crop_start_x = event.x
        self.crop_start_y = event.y

    def end_crop(self, event):
        x1, y1, x2, y2 = self.crop_start_x, self.crop_start_y, event.x, event.y
        self.crop_rectangle = (x1, y1, x2, y2)
        self.crop_image()

    def crop_image(self):
        if self.crop_rectangle:
            x1, y1, x2, y2 = self.crop_rectangle
            self.current_image = self.current_image.crop((x1, y1, x2, y2))
            self.update_image()
            self.crop_rectangle = None

    def enable_crop_mode(self):
        if not self.image_list:
            messagebox.showwarning("Внимание", "Няма изображения за изрязване.")
            return

        if self.crop_button['text'] == "Изрежи":
            self.crop_button.config(text="Изход")
            self.label.bind("<ButtonPress-1>", self.start_crop)
            self.label.bind("<ButtonRelease-1>", self.end_crop)
        else:
            self.crop_button.config(text="Изрежи")
            self.label.unbind("<ButtonPress-1>")
            self.label.unbind("<ButtonRelease-1>")

    def zoom_image(self, scale_factor):
        width, height = self.current_image.size
        new_width = int(width * scale_factor)
        new_height = int(height * scale_factor)
        self.current_image = self.current_image.resize((new_width, new_height), Image.ANTIALIAS)
        self.update_image()

    def zoom_in(self):
        self.zoom_image(1.25)

    def zoom_out(self):
        self.zoom_image(0.8)

    def adjust_brightness(self, value):
        self.load_image()
        enhancer = ImageEnhance.Brightness(self.current_image)
        self.current_image = enhancer.enhance(float(value) / 50 + 1)
        self.update_image()

    def adjust_contrast(self, contrast_value):
        contrast_value = float(contrast_value)
        enhancer = ImageEnhance.Contrast(self.current_image)
        enhanced_image = enhancer.enhance(contrast_value)
        self.update_image(enhanced_image)

if __name__ == "__main__":
    app = ImageViewerApp()
    app.mainloop()


import json

from pylxd.deprecated import base
from pylxd.deprecated import exceptions

class LXDContainer(base.LXDBase):
    # containers:

    def container_list(self):
        (state, data) = self.connection.get_object('GET', '/1.0/containers')
        return [container.split('/1.0/containers/')[-1]
                for container in data['metadata']]

    def container_running(self, container):
        (state, data) = self.connection.get_object(
            'GET',
            '/1.0/containers/%s/state' % container)
        data = data.get('metadata')
        container_running = False
        if data['status'].upper() in ['RUNNING', 'STARTING', 'FREEZING',
                                      'FROZEN', 'THAWED']:
            container_running = True
        return container_running

    def container_init(self, container):
        return self.connection.get_object('POST', '/1.0/containers',
                                          json.dumps(container))

    def container_update(self, container, config):
        return self.connection.get_object('PUT', '/1.0/containers/%s'
                                          % container, json.dumps(config))

    def container_defined(self, container):
        _, data = self.connection.get_object('GET', '/1.0/containers')
        try:
            containers = data["metadata"]
        except KeyError:
            raise exceptions.PyLXDException("no metadata in GET containers?")

        container_url = "/1.0/containers/%s" % container
        for ct in containers:
            if ct == container_url:
                return True
        return False

    def container_state(self, container):
        return self.connection.get_object(
            'GET', '/1.0/containers/%s/state' % container)

    def container_start(self, container, timeout):
        action = {'action': 'start', 'force': True, 'timeout': timeout}
        return self.connection.get_object('PUT', '/1.0/containers/%s/state'
                                          % container,
                                          json.dumps(action))

    def container_stop(self, container, timeout):
        action = {'action': 'stop', 'force': True, 'timeout': timeout}
        return self.connection.get_object('PUT', '/1.0/containers/%s/state'
                                          % container,
                                          json.dumps(action))

    def container_suspend(self, container, timeout):
        action = {'action': 'freeze', 'force': True, 'timeout': timeout}
        return self.connection.get_object('PUT', '/1.0/containers/%s/state'
                                          % container,
                                          json.dumps(action))

    def container_resume(self, container, timeout):
        action = {'action': 'unfreeze', 'force': True, 'timeout': timeout}
        return self.connection.get_object('PUT', '/1.0/containers/%s/state'
                                          % container,
                                          json.dumps(action))

    def container_reboot(self, container, timeout):
        action = {'action': 'restart', 'force': True, 'timeout': timeout}
        return self.connection.get_object('PUT', '/1.0/containers/%s/state'
                                          % container,
                                          json.dumps(action))

    def container_destroy(self, container):
        return self.connection.get_object('DELETE', '/1.0/containers/%s'
                                          % container)

    def get_container_log(self, container):
        (state, data) = self.connection.get_object(
            'GET', '/1.0/containers/%s?log=true' % container)
        return data['metadata']['log']

    def get_container_config(self, container):
        (state, data) = self.connection.get_object(
            'GET', '/1.0/containers/%s?log=false' % container)
        return data['metadata']

    def get_container_websocket(self, container):
        return self.connection.get_status(
            'GET',
            '/1.0/operations/%s/websocket?secret=%s'
            % (container['operation'], container['fs']))

    def container_info(self, container):
        (state, data) = self.connection.get_object(
            'GET', '/1.0/containers/%s/state' % container)
        return data['metadata']

    def container_migrate(self, container):
        action = {'migration': True}
        return self.connection.get_object(
            'POST', '/1.0/containers/%s' % container,
            json.dumps(action))

    def container_migrate_sync(self, operation_id, container_secret):
        return self.connection.get_ws(
            '/1.0/operations/%s/websocket?secret=%s'
            % (operation_id, container_secret))

    def container_local_copy(self, container):
        return self.connection.get_object(
            'POST',
            '/1.0/containers', json.dumps(container))

    def container_local_move(self, instance, config):
        return self.connection.get_object(
            'POST',
            '/1.0/containers/%s' % instance, json.dumps(config))

    # file operations
    def get_container_file(self, container, filename):
        return self.connection.get_raw(
            'GET',
            '/1.0/containers/%s/files?path=%s' % (container, filename))

    def put_container_file(self, container, src_file,
                           dst_file, uid, gid, mode):
        with open(src_file, 'rb') as f:
            data = f.read()
        return self.connection.get_object(
            'POST',
            '/1.0/containers/%s/files?path=%s' % (container, dst_file),
            body=data,
            headers={'X-LXD-uid': uid, 'X-LXD-gid': gid, 'X-LXD-mode': mode})

    def container_publish(self, container):
        return self.connection.get_object('POST', '/1.0/images',
                                          json.dumps(container))

    # misc operations
    def run_command(self, container, args, interactive, web_sockets, env):
        env = env or {}
        data = {'command': args,
                'interactive': interactive,
                'wait-for-websocket': web_sockets,
                'environment': env}
        return self.connection.get_object('POST', '/1.0/containers/%s/exec'
                                          % container, json.dumps(data))

    # snapshots
    def snapshot_list(self, container):
        (state, data) = self.connection.get_object(
            'GET',
            '/1.0/containers/%s/snapshots' % container)
        return [snapshot.split('/1.0/containers/%s/snapshots/%s/'
                               % (container, container))[-1]
                for snapshot in data['metadata']]

    def snapshot_create(self, container, config):
        return self.connection.get_object('POST',
                                          '/1.0/containers/%s/snapshots'
                                          % container,
                                          json.dumps(config))

    def snapshot_info(self, container, snapshot):
        return self.connection.get_object('GET',
                                          '/1.0/containers/%s/snapshots/%s'
                                          % (container, snapshot))

    def snapshot_rename(self, container, snapshot, config):
        return self.connection.get_object('POST',
                                          '/1.0/containers/%s/snapshots/%s'
                                          % (container, snapshot),
                                          json.dumps(config))

    def snapshot_delete(self, container, snapshot):
        return self.connection.get_object('DELETE',
                                          '/1.0/containers/%s/snapshots/%s'
                                          % (container, snapshot))


# %%
import paho.mqtt.client as mqtt
from time import time
import math

T0 = T1 = T4 = None
counter0 = None
counter1 = None

# The callback for when the client receives a CONNACK response from the server.
def on_connect(client, userdata, flags, rc):
    print("Connected with result code "+str(rc))

    # Subscribing in on_connect() means that if we lose the connection and
    # reconnect then subscriptions will be renewed.
    print("Subscribing...")
    client.subscribe("/cc32xx/ButtonPressEvtSw2", 2)
    client.subscribe("ADC0", 0)
    client.subscribe("ADC1", 0)
    print("Done.")

# The callback for when a PUBLISH message is received from the server.
def on_message(client, userdata, msg):
    global T1, T4, counter0, counter1
    #print(msg.topic+" "+str(msg.payload))

    if msg.topic == "ADC0":
        counter0 += 1
        if counter0 % 1000 == 0:
            T2 = time()
            print('ADC0 receiving', math.ceil(1000/ (T2 - T1)), 'messages per sec')
            T1 = T2
    if msg.topic == "ADC1":
        counter1 += 1
        if counter1 % 1000 == 0:
            T3 = time()
            print('ADC1 receiving', math.ceil(1000/ (T3 - T4)), 'messages per sec')
            T4 = T3

client = mqtt.Client()
client.on_connect = on_connect
client.on_message = on_message

#client.username_pw_set("username1", "pwd1")
client.connect("mqtt.eclipse.org", 1883, 60)

T0 = T1 = T4 = time()
counter0 = 0
counter1 = 0

# Blocking call that processes network traffic, dispatches callbacks and
# handles reconnecting.
# Other loop*() functions are available that give a threaded interface and a
# manual interface.
client.loop_forever()

# %%


# Create your views here.
from django import forms
from django.contrib.auth.decorators import login_required
from django.shortcuts import render
from .forms import AnalysisForm
from main import AnalyseData
from .models import Analyses
from .config_templates import templates
AnalysisForm = AnalysisForm

@login_required
def run_pytar(request):
    user_analyses = Analyses.objects.filter(user=request.user)
    if request.method == 'POST':
        form = AnalysisForm(request.POST)
        if form.is_valid():
            Analyses.objects.get_or_create(user=request.user,
                                    **form.cleaned_data)
            # clean up grouping to pass as python obj
            value = form.cleaned_data['case_group']
            form.cleaned_data['case_group'] = [i.strip() for i in value.split(',')]
            analysis = AnalyseData(**form.cleaned_data)
            analysis.main()
    elif 'id' in request.GET:
            tar = Analyses.objects.get(pk=int(request.GET['id']))
            #check if allowed user enters tar
            assert tar.user==request.user, 'Brak dostępu :P'
            form = AnalysisForm(data=tar.__dict__)
            for i in form.fields:
                # if loads save analysis set to readonly
                form.fields[i].widget.attrs['readonly']=True

    else:
        data = {}
        if 'load_template' in request.GET:
            data = templates[request.GET['load_template']]

        form = AnalysisForm(data=data)

    context = {'form': form,
               'user_analyses': user_analyses,
               'config_templates':templates,}

    return render(request, 'analysis/index.html', context)

def home_page(request):
    context = {}
    return render(request, 'index.html', context)


COCO_CLASSES = (
    "Fruits"
    "Apple"
    "Apricot"
    "Avocado"
    "Banana"
    "Beetroot"
    "Blueberry"
    "Cactus"
    "Cantaloupe"
    "Carambula"
    "Cauliflower"
    "Cherry"
    "Chestnut"
    "Clementine"
    "Cocos"
    "Dates"
    "Eggplant"
    "Ginger"
    "Granadilla"
    "Grape"
    "Grapefruit"
    "Guava"
    "Hazelnut"
    "Huckleberry"
    "Kaki"
    "Kiwi"
    "Kohlrabi"
    "Kumquats"
    "Lemon"
    "Limes"
    "Lychee"
    "Mandarine"
    "Mango"
    "Mangostan"
    "Maracuja"
    "Melon"
    "Mulberry"
    "Nectarine"
    "Nut"
    "Onion"
    "Orange"
    "Papaya"
    "Passion"
    "Peach"
    "Pear"
    "Pepino"
    "Pepper"
    "Physalis"
    "Pineapple"
    "Pitahaya"
    "Plum"
    "Pomegranate"
    "Pomelo"
    "Potato"
    "Quince"
    "Rambutan"
    "Raspberry"
    "Redcurrant"
    "Salak"
    "Strawberry"
    "Tamarillo"
    "Tangelo"
    "Tomato"
    "Walnut"
)


import numpy as np
from pathlib import Path
import os
import re
import yaml
import pickle
import keras.models
import json

def save_numpy_array_sliced(filename, data, data_dir='data', max_size_mb=90):
    """
    save and load numpy array
    split them into multiple files to keep the file size below 100MB,
    since GitHub does not support files >100MB
    """

    assert data.ndim == 2

    data_dir = Path(data_dir)

    max_size_bytes = max_size_mb*1024*1024
    size_of_row = data[0, :].nbytes
    max_rows = int(max_size_bytes/size_of_row)

    rows_processed = 0
    rows_total = data.shape[0]

    n_iter = 0

    print("Saved file to slices", filename)

    while rows_processed < rows_total:
        n_iter += 1
        n_rows = min(max_rows, data.shape[0])
        rows_processed += n_rows
        f_name = f'{filename}_{n_iter:03d}'
        print("   saved slice {n:03d} to ".format(n=n_iter), f_name)
        np.save(data_dir / f_name, data[:n_rows, :])
        data = data[n_rows:, :]

    if rows_total != rows_processed:
        raise IOError("Failed writing all rows of array to file")

    return n_iter

def load_sliced_numpy_array(filename, data_dir = 'data'):
    """
    Load the slices back, not guaranteed to be in the order as the slices have been saved
    """
    data_dir = Path(data_dir)
    regex_pattern = filename + '_[0-9]*.npy'

    file_names = []
    for file in filter(lambda d: os.path.isfile(data_dir/d), os.listdir(data_dir)):
        if re.match(regex_pattern, file):
            file_names.append(file)

    data = None
    for file in sorted(file_names):
        if data is None:
            data = np.load(data_dir/file)
        else:
            data = np.vstack([data, np.load(data_dir/file)])
        print(f"Load slice from file {file}")

    print(f"Loaded {len(file_names)} files as slices, resulting shape: {data.shape}")

    return data

def test_load_save_routine():
    """
    Check if array after sliced saving and loading is still equal
    """
    array_before = np.random.randint(0, 100, (10000, 500))

    n_iter = save_numpy_array_sliced('tmp_array', array_before, max_size_mb=1)
    array_after = load_sliced_numpy_array('tmp_array')

    assert np.abs(array_after - array_before).sum() == 0

    for i in range(n_iter):
        os.remove(f'data/tmp_array_{(i+1):03}.npy')

def save_training(to_dump: dict, name:str, dir='models'):
    """
    dump the training results to the 'dir', in order to maitain a uniform naming convention
    """
    dir = Path(dir)

    model = to_dump['model']
    model.save_weights(dir/f'{name}_trained_weights')
    model.save(dir/f'{name}_trained')

    with open(dir/f'{name}_history', 'wb') as f:
        pickle.dump(to_dump['history'], f)

    with open(dir/f'{name}_config.yaml', 'w') as f:
        yaml.dump(to_dump['config'], f, default_flow_style=False)

def load_history(name, dir='models'):
    """
    Get the saved hostory object as 'dict'
    """
    dir = Path(dir)
    with open(dir/f'{name}_history', 'rb') as f:
        return pickle.load(f)

def load_model(name, dir='models'):
    """
    Loads the saved model from directory
    """
    dir = Path(dir)
    return keras.models.load_model(dir/f'{name}_trained')

def get_class_names():
    """
    returns the class names as strings
    """
    with open('data/class_label_index_mapping.json', 'r') as f:
        return json.load(f).keys()

def get_class_mapping():
    """
    returns the mapping from string class names to the label id
    """
    with open('data/class_label_index_mapping.json', 'r') as f:
        return json.load(f)

def audio_file_iterator(mute=False):
    """
    Iteratable generator object to iterate over all wav-audio files in the 'wav_data' directory
        mute: if true, all output is suppressed
        returns: each audio file with the relative file path in the project
    """
    wav_dir = Path('wav_data')
    for directory in filter(lambda d: os.path.isdir(wav_dir/d), os.listdir(wav_dir)):
        genre_directory = wav_dir / directory
        if not mute:
            print('Processing genre directory \'{dir}\''.format(dir=directory))
        file_counter = 0
        for audio_file in filter(lambda f: os.path.isfile(genre_directory/f) and f.endswith('.wav'), os.listdir(genre_directory)):
            file_counter += 1
            if not mute:
                print("   Processed {n} files          ".format(n=file_counter), end='\r')
            yield genre_directory/audio_file
        if not mute:
            print('')

def get_config(name):
    """
    Get the yaml config by name from the 'config' folder
    """
    with open(f'configs/{name}_config.yaml', 'r') as f:
        return yaml.safe_load(f)

def get_label_distribution(labels, as_normalized=False):
    """
    Routine to return the distribution of classes in the label array
    if as_normalized, it return relative fractions (rounded on 2 decimals) instead of absolut numbers
    """
    labels_unique, amounts = np.unique(labels, return_counts=True, axis=0)

    if as_normalized:
        amounts = np.round(amounts/np.sum(amounts), 2)

    labels_to_id = get_class_mapping()

    id_to_labels = {}
    for key in labels_to_id:
        id_to_labels[labels_to_id[key]] = key

    class_distribution = {}
    for l in zip(labels_unique, amounts):
        class_name = id_to_labels[np.argmax(l[0])]
        class_distribution[class_name] = l[1]

    return class_distribution


class UnionFind():
    def __init__(self, n):
        self.n = n
        self.parents = [-1] * n
        self.sz = [1] * n

    def find(self, x):
        if self.parents[x] < 0:
            return x
        else:
            self.parents[x] = self.find(self.parents[x])
            return self.parents[x]

    def union(self, x, y):
        x = self.find(x)
        y = self.find(y)

        if x == y:
            return

        if self.sz[x] > self.sz[y]:
            x, y = y, x

        self.sz[x] += self.sz[y]
        self.parents[y] = x

    def size(self, x):
        return self.sz[self.find(x)]

    def same(self, x, y):
        return self.find(x) == self.find(y)

    def sizes(self):
        isCalc = [0] * self.n
        csize = []
        for i in range(self.n):
            x = self.find(i)
            # print('uf: ', i, x)

            if isCalc[x] == 0:
                isCalc[x] = 1
                csize.append(self.size(x))
        return csize

    def eval(self):
        t = 0
        isCalc = [0] * self.n
        for i in range(self.n):
            x = self.find(i)
            if isCalc[x] == 0:
                isCalc[x] = 1

                t += self.size(x) * (self.size(x) - 1) / 2

        return t


from flask import Blueprint, jsonify, abort
from .auth.auth import requires_auth
from .models.list import List
from .models.challenge import Challenge

bp = Blueprint('user', __name__, url_prefix='/user')

@bp.route('/<int:user_id>/lists')
@requires_auth()
def get_user_lists(payload, user_id):
    if payload['id'] != user_id:
        return abort(403)

    lists = [li.to_dict() for li in List.query.filter_by(owner_id=user_id)]

    return jsonify({'lists': lists})

@bp.route('/<int:user_id>/challenges')
@requires_auth()
def get_user_challenges(payload, user_id):
    if payload['id'] != user_id:
        return abort(403)

    challenges = [c.to_dict()
                  for c in Challenge.query.filter_by(creator_id=user_id)]
    return jsonify({'challenges': challenges})


import sys
input = sys.stdin.readline

n = int(input())
arr = []
# 1. 맵입력
for i in range(n):
    arr.append(list(map(int,input().split())))
# 2. 숫자 쌓기
for i in range(1, n):
    for j in range(i+1):
        # 0열이면
        if j==0:
            arr[i][0] = arr[i-1][0] + arr[i][0]
        # 맨 끝열이면
        elif i==j:
            arr[i][j] = arr[i-1][j-1] + arr[i][j]
        # 중간이면
        else:
            arr[i][j] = max(arr[i-1][j-1], arr[i-1][j]) + arr[i][j]
print(max(arr[n-1]))


# Um jogo de blackjack deve possuir:
# Um jogador vs um dealer (automático)
# O jogador pode:
#   Stand (Não pedir mais cartas)
#   Hit (Pedir mais cartas)
#   Double (Dobra a aposta para receber SOMENTE UMA carta adicional, opção só oferecida nas duas primeiras cartas)
#   Split (Se as primeiras duas cartas da mão do jogador forem de mesmo valor em pontos, ele pode divir em duas mãos. Cada carta se tornará a primeira carta de uma nova mão. Também DEVE fazer uma outra aposta de valor igual da primeira mão para a segunda mão)
#       O split pode ocorrer de duas a três vezes consecutivas
#   Surrender (Opção de render-se nas duas primeiras cartas. Se o jogador não gostar de suas cartas e quiser render-se ele perde 1/2 da aposta. Opção oferecida após o dealer verificar se há blackjack)
# O jogador deve poder escolher o seu valor de apostas
# É preciso acompanhar o dinheiro total do jogador
# É preciso alertar o jogador de vitórias e derrotas
# Não há cartas coringas
# O ás pode valor 1 ou 11 se estiver junto de uma carta J, Q ou K (deve favorecer o jogador ou computador)
# 10, J, Q e K valem 10
# O total de pontos é 21 (ao passar, perde-se o jogo)
# *Para o projeto é necessário usar POO

def geral():
    from random import choice
    from os import system
    # Classe para a criação dos jogadores
    class Jogador(object):
        def __init__(self, nome, posicao = 1, saldo=100, vitorias=0, derrotas=0):
            self.nome = nome
            self.posicao = posicao
            self.saldo = saldo
            self.vitorias = vitorias
            self.derrotas = derrotas

        # Função para retornar retornar o nome em formato de string ao invés de endereço de memória (usado para o dictionary)
        def __repr__(self):
            return '{0}'.format(self.nome)

    # Função de criação das cartas
    def criar_cartas():
        '''
        Função que cria o baralho de cartas e retorna  8 baralhos idênticos. Retorna list
        '''
        cartas = [i for i in range(2, 11)]
        cartas.insert(0, 'Ás')
        cartas.append('J')
        cartas.append('Q')
        cartas.append('K')
        return cartas*8

    # Função que recebe e verifica a quantidade de jogadores (tratando erro se necessário)
    def quantidade_de_jogadores():
        '''
        Função que pede por um input int que retornará a quantidade de jogadores que participarão da partida. Retorna int
        '''
        while True:
            try:
                qtd_jogadores = int(input('Quantas pessoas jogarão? (Escolha um número de 1 a 7)'))
                if qtd_jogadores > 0 and qtd_jogadores <= 7:
                    break
                else:
                    print('O limite de 7 jogadores deve ser respeitado. Escolha a quantidade de jogadores de 1 a 7.')
            except ValueError:
                print('ERRO: Digite apenas quantos jogadores irão jogar.')
        return qtd_jogadores

    # Função que atribui um nome ou apelido ao jogador, justamente criando instâncias da classe Jogador. Armazena o jogador em um dictionary e os jogadores em uma lista.
    def atribuir_nomes_aos_jogadores(numero_de_jogadores):
        '''
        Função que recebe como atributo a quantidade de jogadores que participarão do jogo e os separam em dictonaries com valores que possibilitam uma fácil identificação como nome/apelido e sua posição no jogo. Retorna list
        '''
        jogadores = []
        for numero in range(1, numero_de_jogadores+1):
            jogador = {'Nome' : str, 'Posicao' : numero, 'Saldo' : 20000, 'Vitorias' : 0, 'Derrotas' : 0, 'Cartas' : []}
            jogador['Nome'] = Jogador(nome = input('Jogador {0}, digite seu nome ou apelido: '.format(numero)))
            jogadores.append(jogador)
        return jogadores

    # Simples função para criar o dealer, seria mesmo necessária?
    def atribuir_dealer():
        dealer_list = []
        dealer = {'Nome' : 'Dealer', 'Cartas' : []}
        dealer_list.append(dealer)
        return dealer_list

    # Função que retorna uma int (valor da aposta declarada pelo jogador).
    def apostas(qtd_jogadores, informacao_jogadores):
        '''
        Função que recebe a quantidade de jogadores e a lista dos jogadores retornando assim a aposta que o jogador declarou através do input
        '''
        while True:
            try:
                aposta = int(input('Caro jogador neste momento você possui [SALDO: {0}], faça sua aposta: '.format(informacao_jogadores[qtd_jogadores-1]['Saldo'])))
                if informacao_jogadores[qtd_jogadores-1]['Saldo'] - aposta >= 0:
                    print('R$', aposta)
                    informacao_jogadores[qtd_jogadores-1]['Saldo'] -= aposta
                    break
            except ValueError:
                print('Digite um valor inteiro e válido.')
            else:
                print('SEM SALDO, NESTE CASO DIGITE 0 e depois 7 para sair do jogo. Então comece um novo jogo :)')
        return aposta

    # Função que atribui cartas aos jogadores
    def atribuir_cartas(qtd_jogadores, informacao_jogadores, cartas, vezes = 1):
        '''
        Função que recebe a quantidade de jogadores, a lista dos jogadores, o baralho do jogo e a quantidade de vezes que as cartas serão distribuídas
        '''
        for i in range(0, vezes):
            informacao_jogadores[qtd_jogadores-1]['Cartas'].append(choice(cartas))

    # Função que retorna a jogada escolhida pelo jogador para ser usado na função dealer(qtd_jogadores).
    def escuta_jogada(qtd_jogadores, informacao_jogadores):
        '''
        Função que recebe o jogador que está jogando no momento e retorna um int(input()) que será usado como decisão de jogada. Retorna int
        '''
        while True:
            try:
                jogada = int(input('Escolha de jogadas:\n{0}, qual jogada gostaria de realizar?\n1-)Stand\n2-)Hit\n3-)Double\n4-)Split\n5-)Insurance\n6-)Surrender\n7-)Sair'.format(informacao_jogadores[qtd_jogadores-1]['Nome'])))
                if jogada > 0 and jogada <= 7:
                    break
                else:
                    print('Existem 5 opções numeradas de 1 a 5. Para escolher a jogada, escolha uma entre elas.')
            except ValueError:
                print('ERRO: Use o teclado numérico para escolher apenas uma das jogadas citadas.')

        if jogada == 1:
            print('Stand.')
            return 1

        elif jogada == 2:
            print('Hit.')
            return 2

        elif jogada == 3:
            print('Double.')
            return 3

        elif jogada == 4:
            system('cls') # Remover depois
            print('Split.')
            print('WIP\nÉ uma jogada que o jogador que possui duas cartas iguais na mão inicial pode fazer.\nEle divide sua mão em dois, aposta para cada mão e no fim compara as duas mãos com a mesma mão do dealer') # Remover depois
            return 4

        elif jogada == 5:
            system('cls') # Remover depois
            print('Insurance.')
            print('WIP\nÉ uma jogada que é "nosciva" para não contadores de cartas. Geralmente favorece a casa') # Remover depois
            return 5

        elif jogada == 6:
            system('cls') # Remover depois
            print('Surrender.')
            print('WIP\nEm essência funciona mais para aplicações com persistência de dados ou na vida real.\nÉ uma escolha que o jogador para de jogar, porém matém metade do valor de sua aposta.\n Logo, não será implementado') # Remover depois
            return 6

        elif jogada == 7:
            system('cls')
            print('Saindo...')
            print('Obrigado por jogar!')
            return 7

    # Dependendo do ponto de vista, é uma função 50% desnecessária uma vez que se eu colocasse verificações para uma carta
    # que vale 1 (Ás), dependendo da ocasião, 1 poderia ser igual a 11 e as cartas J Q K poderiam simplesmente valer 10
    # sem precisar de verificação para transformar a carta símbolo em número
    def verifica_soma(cartas):
        '''
        Recebe a mão tanto do jogador quanto do dealer e retorna a soma da mesma
        '''
        soma = 0
        soma2 = 0
        for carta in range(len(cartas)):
            if cartas[carta] == 'J':
                cartas[carta] = 10
            elif cartas[carta] == "Q":
                cartas[carta] = 10
            elif cartas[carta] == 'K':
                cartas[carta] = 10

            if cartas[carta] == 'Ás':
                if soma == 10:
                    cartas[carta] = 11
                elif soma < 10:
                    cartas[carta] = 11
                elif soma > 10:
                    cartas[carta] = 1
            soma += cartas[carta]
        for as_11 in range(len(cartas)):
            if (soma - 10) > 11 and cartas[as_11] == 11:
                cartas[as_11] = 1
            soma2 += cartas[as_11]
        return int(soma2)

    # Função que paga as jogadas bem sucedidas dos jogadores
    def pagar(qtd_jogadores, informacao_jogadores, aposta, blackjack : bool, double = False):
        '''
        Função que recebe a quantidade de jogadores, a lista dos jogadores, a aposta realizada, blackjack (bool) e double (bool)
        '''
        # Double False:
        if double == False:
            if blackjack:
                informacao_jogadores[qtd_jogadores-1]['Saldo'] += int(aposta) + (3/2)*int(aposta)
            else:
                informacao_jogadores[qtd_jogadores-1]['Saldo'] += int(aposta) * 2
        # Double True
        if double:
            if blackjack:
                informacao_jogadores[qtd_jogadores-1]['Saldo'] += int(aposta*2) + (3/2)*int(aposta*2)
            else:
                informacao_jogadores[qtd_jogadores-1]['Saldo'] += int(aposta*2) * 2

    # Função que distribui as cartas iniciais e/ou reinicia as mãos existentes
    def acoes_dealer(qtd_jogadores, dealer, informacao_jogadores, cartas):
        '''
        Função que recebe quantidade de jogadores, uma lista do dealer, uma lista dos jogadores e o baralho de cartas do jogo
        '''
        # Bloco if, atribui cartas ao dealer e ao jogador caso ambos não possuam cartas ainda.
        if dealer[0]['Cartas'] == [] and informacao_jogadores[qtd_jogadores-1]['Cartas'] == []:
            print('Distribuindo cartas...')
            atribuir_cartas(1, dealer, cartas, 2)
            atribuir_cartas(qtd_jogadores, informacao_jogadores, cartas, 2)
        else:
            print('Distribuindo outra mão')
            dealer[0]['Cartas'] = []
            informacao_jogadores[qtd_jogadores-1]['Cartas'] = []
            atribuir_cartas(1, dealer, cartas, 2)
            atribuir_cartas(qtd_jogadores, informacao_jogadores, cartas, 2)

    # Função que verifica as cartas nas mãos do dealer e dos jogadores. Retorna vb (bool ou string)
    def verificar_blackjack(dealer, jogador):
        '''
        Recebe o dealer que está em uma lista e jogador que é a lista de cartas do jogador
        '''
        if verifica_soma(dealer[0]['Cartas']) == verifica_soma(jogador):
            print('Empate!')
            return 'Empate'
        elif verifica_soma(dealer[0]['Cartas']) != 21 and verifica_soma(jogador) == 21:
            print('Blackjack para o jogador!')
            return 'Blackjack'
        elif verifica_soma(jogador) != 21 and verifica_soma(dealer[0]['Cartas']) == 21:
            print('Blackjack para o dealer!')
            return False
        elif verifica_soma(jogador) > 21:
            print('Dealer vence porque o jogador tem uma mão que passa de 21!')
            return False
        elif verifica_soma(dealer[0]['Cartas']) > 21:
            print('Jogador vence porque o dealer tem uma mão que passa de 21!')
            return True
        elif verifica_soma(dealer[0]['Cartas']) < 21 and verifica_soma(dealer[0]['Cartas']) > verifica_soma(jogador):
            print('Dealer vence por ter uma mão maior que a do jogador!')
            return False
        elif verifica_soma(jogador) < 21 and verifica_soma(jogador) > verifica_soma(dealer[0]['Cartas']):
            print('Jogador vence por ter uma mão maior que a do dealer!')
            return True

    # Função que realiza pagamentos e atribui vitórias e derrotas e reinicia as cartas
    def acao_verificar_blackjack(vb, dealer, informacao_jogadores, qtd_jogadores, aposta, cartas, double = False):
        '''
        Recebe vb(bool ou string), lista dos jogadores, quantidade de jogadores, aposta feita e double (bool)
        '''
        if vb == 'Blackjack':
            informacao_jogadores[qtd_jogadores-1]['Vitorias'] += 1
            if double:
                pagar(qtd_jogadores, informacao_jogadores, aposta, True, True)
            else:
                pagar(qtd_jogadores, informacao_jogadores, aposta, True, False)
            print('Parabéns {0}, você ganhou e estes são seus seguintes status: {1}'.format(informacao_jogadores[qtd_jogadores-1]['Nome'], informacao_jogadores[qtd_jogadores-1]))
            acoes_dealer(qtd_jogadores, dealer, informacao_jogadores, cartas)
        elif vb == 'Empate':
            if double:
                informacao_jogadores[qtd_jogadores-1]['Saldo'] += aposta*2
            else:
                informacao_jogadores[qtd_jogadores-1]['Saldo'] += aposta
            print('Como empatou, você recebe o valor de sua aposta de volta e uma nova mão será distribuida')
            acoes_dealer(qtd_jogadores, dealer, informacao_jogadores, cartas)
        elif vb == True:
            informacao_jogadores[qtd_jogadores-1]['Vitorias'] += 1
            if double:
                pagar(qtd_jogadores, informacao_jogadores, aposta, False, True)
            else:
                pagar(qtd_jogadores, informacao_jogadores, aposta, False, False)
            print('Parabéns {0}, você ganhou e estes são seus seguintes status: {1}'.format(informacao_jogadores[qtd_jogadores-1]['Nome'], informacao_jogadores[qtd_jogadores-1]))
            acoes_dealer(qtd_jogadores, dealer, informacao_jogadores, cartas)
        else:
            informacao_jogadores[qtd_jogadores-1]['Derrotas'] += 1
            print('Que pena {0}! Você perdeu e estes são seus seguintes status: {1}'.format(informacao_jogadores[qtd_jogadores-1]['Nome'], informacao_jogadores[qtd_jogadores-1]))
            acoes_dealer(qtd_jogadores, dealer, informacao_jogadores, cartas)

    # Função que engloba todas as outras e executa as jogadas.
    def iniciar():
        print('Bem vindo ao Blackjack versão texto!')
        cartas = criar_cartas()
        qtd_jogadores = quantidade_de_jogadores()
        informacao_jogadores = atribuir_nomes_aos_jogadores(qtd_jogadores)
        dealer = atribuir_dealer()
        acoes_dealer(qtd_jogadores, dealer, informacao_jogadores, cartas)
        while True:
            aposta = apostas(qtd_jogadores, informacao_jogadores)
            print('{0}, essa é a sua mão: {1}\n{0}, essa é a carta do dealer que está virada para cima: {2}'.format(informacao_jogadores[qtd_jogadores-1]['Nome'], informacao_jogadores[qtd_jogadores-1]['Cartas'], dealer[0]['Cartas'][0]))
            jogada = escuta_jogada(qtd_jogadores, informacao_jogadores)
            # Caso 7, sair! O jogador não quer mais jogar, logo, fecha o programa
            if jogada == 7:
                break
            # Caso 1, stand! O jogador não recebe mais cartas enquanto o dealer revela a sua e se necessário compra mais cartas.
            if jogada == 1:
                if verifica_soma(dealer[0]['Cartas']) < 17:
                    while verifica_soma(dealer[0]['Cartas']) < 17:
                        atribuir_cartas(1, dealer, cartas, 1)
                system('cls')
                print('O dealer revelou a segunda carta: [{0}, {1}]'.format(dealer[0]['Cartas'][0], dealer[0]['Cartas'][1]))
                print('A mão do dealer ficou: {0}\nA mão do jogador ficou: {1}'.format(dealer[0]['Cartas'], informacao_jogadores[qtd_jogadores-1]['Cartas']))
                vb = verificar_blackjack(dealer, informacao_jogadores[qtd_jogadores-1]['Cartas'])

                acao_verificar_blackjack(vb, dealer, informacao_jogadores, qtd_jogadores, aposta, cartas)

            # Caso 2, hit! O jogador pegará mais cartas
            if jogada == 2:
                parar = 0
                while parar == 0:
                    if verifica_soma(informacao_jogadores[qtd_jogadores-1]['Cartas']) > 21:
                        print('Não pode comprar mais cartas, perdeu por passar de 21')
                        informacao_jogadores[qtd_jogadores-1]['Derrotas'] += 1
                        acoes_dealer(qtd_jogadores, dealer, informacao_jogadores, cartas)
                        break
                    else:
                        print('A sua mão é: {0}'.format(informacao_jogadores[qtd_jogadores-1]['Cartas']))
                        try:
                            parar = int(input('Digite 1 para parar ou 0 para pedir mais uma carta: '))
                            if parar == 0:
                                atribuir_cartas(qtd_jogadores, informacao_jogadores, cartas, 1)
                        except ValueError:
                            print('ERRO: Use o teclado numérico para escolher apenas entre 0 e 1.')

                if parar == 1:
                    if verifica_soma(dealer[0]['Cartas']) < 17:
                        while verifica_soma(dealer[0]['Cartas']) < 17:
                            atribuir_cartas(1, dealer, cartas, 1)

                system('cls')
                print('O dealer revelou a segunda carta: [{0}, {1}]'.format(dealer[0]['Cartas'][0], dealer[0]['Cartas'][1]))
                print('A mão do dealer ficou: {0}\nA mão do jogador ficou: {1}'.format(dealer[0]['Cartas'], informacao_jogadores[qtd_jogadores-1]['Cartas']))
                vb = verificar_blackjack(dealer, informacao_jogadores[qtd_jogadores-1]['Cartas'])
                acao_verificar_blackjack(vb, dealer, informacao_jogadores, qtd_jogadores, aposta, cartas)

            # Caso 3, double! O jogador pagará dobrado e comprara apenas uma carta a mais
            if jogada == 3:
                if informacao_jogadores[qtd_jogadores-1]['Saldo'] - aposta >= 0:
                    informacao_jogadores[qtd_jogadores-1]['Saldo'] -= aposta
                    atribuir_cartas(qtd_jogadores, informacao_jogadores, cartas, 1)
                    if verifica_soma(dealer[0]['Cartas']) < 17:
                        while verifica_soma(dealer[0]['Cartas']) < 17:
                            atribuir_cartas(1, dealer, cartas, 1)
                else:
                    print('Saldo insuficiente para um double.')

                system('cls')
                print('O dealer revelou a segunda carta: [{0}, {1}]'.format(dealer[0]['Cartas'][0], dealer[0]['Cartas'][1]))
                print('A mão do dealer ficou: {0}\nA mão do jogador ficou: {1}'.format(dealer[0]['Cartas'], informacao_jogadores[qtd_jogadores-1]['Cartas']))
                vb = verificar_blackjack(dealer, informacao_jogadores[qtd_jogadores-1]['Cartas'])
                acao_verificar_blackjack(vb, dealer, informacao_jogadores, qtd_jogadores, aposta, cartas, True)
    iniciar()

geral()

Seção 10 - Projeto 2/60~63-Segundo Projeto.py


import logging
from typing import TYPE_CHECKING, List

from quart import jsonify, abort

from propsd.sourcemanager import SourceManager

logger = logging.getLogger(__name__)

if TYPE_CHECKING:
    from quart import Response  # pylint: disable=ungrouped-imports

async def properties() -> 'Response':
    return jsonify(SourceManager.properties())

async def nested_properties(subpath) -> 'Response':
    logger.debug('API/Properties: Received sub-path %s', subpath)
    props = SourceManager.properties()
    paths: List[str] = list(filter(None, subpath.split('/')))
    paths.reverse()
    while paths:
        path = paths.pop()
        if path not in props:
            abort(404)
        props = props.get(path)  # type: ignore
    return jsonify(props)


# 268. Missing Number (leetcode)
class Solution:
    def missingNumber(self, nums: List[int]) -> int:
        a=0
        if a not in nums:
            return(a)

        for i in range(len(nums)):
            a=a+1
            if a not in nums:
                return(a)


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Wed Feb 15 11:49:59 2023

@author: michaelka
"""
import random
from collections import Counter

# Enter student number here
# 33662797
#----------------------------------------------------------------------

#TASK 1

def English_to_Morse(text):
    """
    Take a string of characters (words) in English and coverts the string to Morse code.
    Parameters
    ----------
    text : string
        The input string of English characters to convert to Morse code.
    Returns
    -------
    result: string
        The input string converted to Morse code.
        Words are separated by a single space character.
    """
    # Define a dictionary that maps English characters to their Morse code equivalents
    eng_to_morse_dict = {'A': '.-', 'B': '-...', 'C': '-.-.', 'D': '-..', 'E': '.', 'F': '..-.',
                       'G': '--.', 'H': '....', 'I': '..', 'J': '.---', 'K': '-.-', 'L': '.-..',
                       'M': '--', 'N': '-.', 'O': '---', 'P':    '.--.', 'Q': '--.-', 'R': '.-.',
                       'S': '...', 'T': '-', 'U': '..-', 'V': '...-', 'W': '.--', 'X': '-..-',
                       'Y': '-.--', 'Z': '--..', '0': '-----', '1': '.----', '2': '..---',
                       '3': '...--', '4': '....-', '5': '.....', '6': '-....', '7': '--...',
                       '8': '---..', '9': '----.', '.': '.-.-.-', ',': '--..--', '?': '..--..',
                       "'": '.----.', '!': '-.-.--', '/': '-..-.', '(': '-.--.', ')': '-.--.-',
                       '&': '.-...', ':': '---...', ';': '-.-.-.', '=': '-...-', '+': '.-.-.',
                       '-': '-....-', '_': '..--.-', '"': '.-..-.', '$': '...-..-', '@': '.--.-.',
                       ' ': ' '}
    # Initialize an empty list to store the Morse code symbols
    morse_text = []
    # Iterate over each character in the input text
    for char in text.upper():
        # If the character is in the dictionary, append its Morse code symbol to the list
        if char in eng_to_morse_dict:
            morse_text.append(eng_to_morse_dict[char])
    # Join the Morse code symbols together with spaces between them
    result = ' '.join(morse_text)
    return result

#----------------------------------------------------------------------

#TASK 2
def run_regional_election(prob_A_wins):
    """
    Simulates a regional election given the probability of candidate A winning.
    Parameters
    ----------
    prob_A_wins : float
        The probability of candidate A winning the election. Must be between 0 and 1.
    Returns
    -------
    result: boolean
        Returns True if candidate A wins the simulated election, and False otherwise.
    """
    # Initialize the result variable to False
    result = False
    # Generate a random number between 0 and 1, and compare it to the given probability of A winning
    if random.random() < prob_A_wins:
        # If the random number is less than the probability of A winning, set result to True
        result = True
        return result
    else:
        return result

def run_election(regional_chances):
    """
    Simulates the election given the chances of candidate A winning in each region.
    Candidate A wins the election if they win at least 3 regions.
    Parameters
    -----------
    regional_chances : list of floats
        A list containing the probability of candidate A winning in each region. Each value must be between 0 and 1.
    Returns
    -------
    result: boolean
        Returns True if candidate A wins in at least 3 regions, and False otherwise.
    """
    # Initialize the number of wins for candidate A to 0 and the result to False
    num_wins_A = 0
    result = False
    # Iterate through the regional chances
    for prob_A in regional_chances:
        # Simulate a regional election with the given probability for candidate A
        if run_regional_election(prob_A):
            num_wins_A += 1
        # If candidate A has won in at least 3 regions, set the result to True and return it
        if num_wins_A == 3:
            result = True
            return result
    # If candidate A has not won in at least 3 regions, return False
    return result

def percentage_A(N):
    """
    By using the idea of Monte Carlo simulation，simulates N elections using run_election() function,
    and calculates the percentage of elections that candidate A wins.
    The regional probabilities of candidate A winning are fixed to:
    Region 1: 84% chance
    Region 2: 60% chance
    Region 3: 10% chance
    Region 4: 35% chance
    Region 5: 40% chance
    Parameters
    ----------
    N : int
        The number of elections to simulate.
    Returns
    -------
    percentage : float
        The percentage of simulated elections that candidate A wins.
    """
    # Initialize a counter for the number of times candidate A wins
    num_wins_A = 0
    # Simulate N elections with fixed regional probabilities and count the number of times candidate A wins
    for i in range(N):
        if run_election([0.84, 0.6, 0.1, 0.35, 0.4]):
            num_wins_A += 1
    # Calculate the percentage of simulated elections that candidate A wins
    percentage = (num_wins_A / N)
    return percentage

#----------------------------------------------------------------------

#TASK 3

def lettersFrequency(file_name):
    """
    Finds the letter with the highest and lowest number of occurrences in the given file.
    Parameters
    -----------
    file_name : string
        The name of the text file.
    Returns
    -------
    letter_highest : string
    freq_highest : int
    letter_lowest : string
    freq_lowest : int
        Returns four variables: letter highest, freq highest, letter lowest, freq lowest.
    """
    # Read the file
    with open(file_name, 'r') as file:
        contents = file.read()

    # Convert all letters to lowercase to ensure case-insensitivity
    contents = contents.lower()
    # Count the occurrences of each letter
    letter_counts = Counter(char for char in contents if char.isalpha())

    # Find the letter with the highest and lowest frequency
    letter_highest, freq_highest = letter_counts.most_common(1)[0]
    letter_lowest, freq_lowest = letter_counts.most_common()[-1]

    return letter_highest, freq_highest, letter_lowest, freq_lowest

#----------------------------------------------------------------------

#TASK 4

def rock_paper_scissors():
    """
    Simulates a game of rock-paper-scissors between the user and the computer. Prompts the user to input their choice and validates it.
    1. If the user enters 'exit', the function returns a message thanking the user for the game
    2. If the user's choice is valid, the function randomly selects the computer's choice, determines the outcome of the game and returns a sentence describing the outcome of the game
    3. If the user's selection is invalid then loop 1.2
    Returns:
    --------
    str_resul : string
        A sentence describing the outcome of the game.
    """
    # define the possible choices
    game_choices = ['rock', 'paper', 'scissors']

    # ask the user to input their choice or exit, if choices that validate it
    while True:
        user_choice = input("Please choose rock, paper or scissors(type 'exit' to exit the game): ").lower()
        if user_choice in game_choices:
            break
        elif user_choice == 'exit':
            return "Thanks for playing!"
        print("Oops!! Invalid choice.")

    # randomly select the computer's choice
    comp_choice = random.choice(game_choices)

    # determine the user outcome of the game using a dictionary
    outcomes = {'rock': {'rock': 'tie', 'paper': 'lose', 'scissors': 'win'},
                'paper': {'rock': 'win', 'paper': 'tie', 'scissors': 'lose'},
                'scissors': {'rock': 'lose', 'paper': 'win', 'scissors': 'tie'}}
    result = outcomes[user_choice][comp_choice]

    # return the outcome of the game as a sentence
    str_result = f"You chose {user_choice}. The computer chose {comp_choice}. You {result}!"
    return str_result


awal = int(input("Masukan awal bilangan : "))
akhir = int(input("Masukan akhir bilangan : "))

import math

def prima(x):
    if x == 2:
        return True

    if x < 2 or x % 2 == 0:
        return False

    for x in range(3, int(math.sqrt(i)) + 1):
        if i % x == 0:
            return False

    return True

for i in range(awal, akhir + 1):
    if prima(i):
        print ("bilangan prima : ", (i))


# HackerEarth (Hiring Challenge)
# FIND MINIMUM SPEED TO THROW A BALL , CONSIDER A=10m/s^2
# Person standing at a height of Y meters from ground
# Tower at a height of Z meters from ground
# Distance between them is X meters
import math

T = int(input())
while T != 0:
    x, y, z = map(int, input().split())
    a = 10
    t = math.sqrt((2 * (y - z)) / a)
    s = x / t
    # if(len(str(s))<4):
    print("%.2f" % (round(s, 2)))
    # else:
    #    print(round(s,2))
    T = T - 1


import json
import os
import random
import requests
import time

from config import *
from util import mocking_case

class Bot:
    def __init__(self, bot_id, token=AUTH_TOKEN):
        self.token = AUTH_TOKEN
        self.id = bot_id

    def _send_message(self, msg):
        url = "https://api.groupme.com/v3/bots/post?token="+self.token
        payload = {'bot_id': self.id,
                   'text': msg}
        time.sleep(1)
        r = requests.post(url, data = json.dumps(payload))
        if r.status_code != 202:
            print("Msg sending failed with code: "+str(r.status_code))

    def on_receive_message(self, content):
        pass

class HenryBreyneBot(Bot):
    def on_receive_message(self, content):
        status_msg = "Breyne Bot running.\nEnv: {env}\nVersion: {version}".format(env=ENV,version=VERSION)

        generic_choices = ["Only I can say faggot, faggot.",
                           "Honestly, shut the fuck up, this is a Chick Fil A.",
                           "I am a massive pussy.",
                           "Those are my titties",
                           "~resepects woman~",
                           "~gets mad pussy~",
                           "YALL CLOSED??",
                           "WHERE IS MY BIKINI PICTURE?",
                           "I\'M PUTTING THE PUSSY BACK IN PUSSY LIPS, BITCH.",
                           "Hillary Clinton is one thicc bitch.",
                           "My respect woman meter is off the charts right now.",
                           "~falls in love with neonatzi~",
                           "~drowns in gamer fuel~",
                           "I'm so horny.",
                           "Is it normal to pull a muscle playing Mario Party?"]

        predefined = {'female': "THOT",
                      'california': "fucking libtards",
                      'woman': "THOT"}

        dick_quote = 'My penis is sore'
        boomer_quote = 'Is that boomer still talking about fIrSt RoBoTiCs?'
        llama_quote = 'If she doesn\'t love a llama onsie, she doesn\'t love me'
        backForth_quote = 'I\'m not another one of your thots, don\'t say that'
        backForthL_quote = 'Degenerate libtard.'
        que_quote = 'QUE PASA???'

        guarenteed_predefined = {'!hb': status_msg,
                                 '!status': status_msg,
                                 'dick': dick_quote,
                                 'penis': dick_quote,
                                 'Pat': boomer_quote,
                                 'McCarthy': boomer_quote,
                                 'onsie': llama_quote,
                                 'llama': llama_quote,
                                 'I\'m just trying to keep you on your toes': backForth_quote,
                                 'What is that supposed to me? I\'m a good holy boy.': backForthL_quote,
                                 'que pasa': que_quote
                                 }

        person_specific = {
            "42403488" : "Klug, shut the fuck up."
        }

        predefined_chance = 25
        generic_chance = 3
        person_specific_chance = 1
        mocking_case_chance = 2
        sender_type = content['sender_type']
        if sender_type != "user":
           return
        msg = content['text']
        sender_id = content['sender_id']
        if sender_id in person_specific:
            print("Found sender in person_specific mapping")
            if random.randint(0,100) <= person_specific_chance:
                self._send_message(person_specific[sender_id])
                return
        for key in guarenteed_predefined:
            if key.lower() in msg.lower():
                self._send_message(guarenteed_predefined[key])
                return

        if random.randint(0,100) <= mocking_case_chance:
            self._send_message(mocking_case(msg))
            return

        for key in predefined:
            print("Searching for: "+key)
            if key.lower() in msg.lower():
                print("Found: "+key)
                if random.randint(0,100) <= predefined_chance:
                    self._send_message(predefined[key])
                    return

        if random.randint(0,100) <= generic_chance:
            response_msg = generic_choices[random.randint(0, len(generic_choices)-1)]
            self._send_message(response_msg)
        return

class MichaelKlugBot(Bot):
    def on_receive_message(self, content):
        status_msg = "Klug Bot running.\nEnv: {env}\nVersion: {version}".format(env=ENV,version=VERSION)

        generic_choices = ["Dude, I love cancer.",
                           "Where the fuck is Carl?",
                           "DiD yOu KnOw I\'m In BmE?",
                           "I just love big personalities",
                           "~tilts head and says we\'ll see~",
                           "~sips daquirriiiiiii and looks dissappointed~",
                           "Fucking pigeons bro, fucking pigeons.",
                           "I'm a masochistic.",
                           "That\'s for me to know and you to find out.",
                           "Demisexuals for the win brah",
                           "~greases up Matt Davis~",
                           "Ok, boomer.",
                           "I\'m a fake, I\'m a fraud",
                           "Anybody got handcuffs?",
                           "WHERE IS NATE???",
                           "~enters in nothing but a towel~",
                           "~jizzes for memes~",
                           "Do you have a boyfriend?",
                           "That\'s why they call me Magic Mike",
                           "Don\'t give me pleasure"]

        predefined = {'female': "Yeah, I did that.",
                      'Fortnite': "WANNA PLAY FORT?",
                      'california': "DID YOU KNOW IM FROM CALI????",
                      'Klug, shut the fuck up.': "I\'m just trying to keep you on your toes"}

        weed_quote = 'BRO DONT SMOKE ON MY FLOOR'
        mia_quote = 'I LIKE MIA'
        alc_quote = 'Daquiriiiiiiiiiiiiiiiiiiiiii'
        sex_quote = 'I AM A DEMIXSEXUAL'
        nk_quote = 'Imma have to Nate-Kerr you on that one'
        toes_quote = 'I\'m just trying to keep you on your toes.'
        sig_quote = '~walks to sig delts at 3am to cuddle with Mia~'
        big_quote = 'I like big tits and big brains'
        age_quote = 'Age is only a number'
        church_quote = 'You wanna go to confession?'
        shoes_quote = 'The sig delts stole my shoes. I just know it.'
        basektball_quote = '~loses to Henry in 2K~'
        strip_quote = "~swings on removable stripper pole~"
        pole_quote = "~inserts removable stripper pole~"
        exl_quote = 'Yeah mothafucka, it\'s me'
        backOne_quote = 'What is that supposed to me? I\'m a good holy boy.'

        guarenteed_predefined = {'!mk': status_msg,
                                 '!status': status_msg,
                                 'weed': weed_quote,
                                 'room 31': weed_quote,
                                 'sex': sex_quote,
                                 'drink': alc_quote,
                                 'mia': mia_quote,
                                 'kerr': nk_quote,
                                 'toes': toes_quote,
                                 'cuddle': sig_quote,
                                 'tits': big_quote,
                                 'ass': big_quote,
                                 'boobs': big_quote,
                                 'old': age_quote,
                                 'age': age_quote,
                                 'church': church_quote,
                                 'christian': church_quote,
                                 'god': church_quote,
                                 'shoe': shoes_quote,
                                 'basketball': basektball_quote,
                                 'room': pole_quote,
                                 'pole': strip_quote,
                                 'wtf': exl_quote,
                                 'wth': exl_quote,
                                 'I\'m not another one of your thots, don\'t say that': backOne_quote}

        person_specific = {
            "22727730" : "Hi Henry, my name is the Michael Klug Bot."
        }

        predefined_chance = 25
        generic_chance = 3
        person_specific_chance = 1
        mocking_case_chance = 2
        sender_type = content['sender_type']
        if sender_type != "user":
            return
        msg = content['text']
        sender_id = content['sender_id']
        if sender_id in person_specific:
            print("Found sender in person_specific mapping")
            if random.randint(0,100) <= person_specific_chance:
                self._send_message(person_specific[sender_id])
                return
        for key in guarenteed_predefined:
            if key.lower() in msg.lower():
                self._send_message(guarenteed_predefined[key])
                return

        if random.randint(0,100) <= mocking_case_chance:
            self._send_message(mocking_case(msg))
            return

        for key in predefined:
            print("Searching for: "+key)
            if key.lower() in msg.lower():
                print("Found: "+key)
                if random.randint(0,100) <= predefined_chance:
                    self._send_message(predefined[key])
                    return

        if random.randint(0,100) <= generic_chance:
            response_msg = generic_choices[random.randint(0, len(generic_choices)-1)]
            self._send_message(response_msg)
        return


from time import sleep
from kivy.lib import osc

serviceport = 3001
activityport = 3002

# str(asctime(localtime()))
def service_callback(message, *args):
    #print("got a message! %s" % message)
    osc.sendMsg('/some_api', [str(message[2])], port=activityport)

if __name__ == '__main__':
    osc.init()
    oscid = osc.listen(ipAddr='127.0.0.1', port=serviceport)
    osc.sendMsg('/some_api', ['Init'], port=activityport)
    try:
        osc.bind(oscid, service_callback, '/some_api')

        while True:
            osc.readQueue(oscid)
            sleep(.3)
    except:
        osc.sendMsg('/some_api', ['error'], port=activityport)


# -*- coding: utf-8 -*-
"""
Created on Wed Feb 17 17:50:17 2021

@author: SHANDCRUZ
"""
import cv2

im = cv2.imread("source/monocropped.jpg")
j = int((im.shape[1])/7)
h = int(im.shape[0])
z=0
for i in range(0,7):
    crop = im[0:92 , z:z+j]
    crop =cv2.resize(crop,(224,224))
    cv2.imwrite('source/ '+str(i)+".jpg",crop)
    z+=j
    cv2.imshow("crop"+str(i),crop)
    cv2.waitKey(0)

cv2.destroyAllWindows()


alphabets = [[], ["a", "b", "c"], ["d", "e", "f"], ["g", "h", "i"],
             ["j", "k", "l"], ["m", "n", "o"], ["p", "q", "r", "s"], ["t", "u", "v"], ["w", "x", "y", "z"]]

class Solution:
    def letterCombinations(self, digits):
        self.dict = {"1":"", "2":"abc", "3":"def", "4":"ghi", "5":"jkl", "6":"mno", "7":"pqrs","8":"tuv","9":"wxyz","10":" "}
        result = [""]
        for digit in digits:
            lst = self.dict[digit]
            newresult = []
            for char in lst:
                for str in result:
                    newresult.append(str+char)
            result = newresult
        return result

if __name__ == "__main__":
    a = Solution()
    print(a.letterCombinations("239"))