import os
import json as json
from focalnet.focalnet import FocalNet
from focalnet.download_weights import download_checkpoint, FOLDER_WEIGHTS
from tensorflow.keras import Model
from tensorflow.keras.layers import Input
IMAGENET_DEFAULT_MEAN = (0.485, 0.456, 0.406)
IMAGENET_DEFAULT_STD = (0.229, 0.224, 0.225)

def imagenet_1k():
    root_dir = os.path.sep.join(os.path.abspath(__file__).split(os.path.sep)[:-1])
    data = json.load(open(os.path.join(root_dir, "imagenet-1k.json"), 'r'))
    idx2label = [data[str(k)][1] for k in range(len(data))]
    return idx2label

def imagenet_22k():
    root_dir = os.path.sep.join(os.path.abspath(__file__).split(os.path.sep)[:-1])
    data = json.load(open(os.path.join(root_dir, "imagenet-22k-reorder.json"), 'r'))
    idx2label = [data[str(k)]  for k in range(len(data))]
    return idx2label

imagenet1k = imagenet_1k()
imagenet22k = imagenet_22k()

def load_focalnet(model_name, input_shape=(224, 224, 3), pretrained=False, return_model=False, num_classes=None, **kwargs):
    #print(kwargs)
    focal_levels=[2,2,2,2]
    focal_windows = [3, 3, 3, 3]
    use_conv_embed = False
    use_postln = False
    use_layerscale = False
    normalize_modulator = False
    use_postln_in_modulation=False

    if model_name == "focalnet_tiny_srf":
        depths = [2, 2, 6, 2]
        embed_dim=96
        default_classes = 1000
    elif model_name == "focalnet_tiny_lrf":
        depths = [2, 2, 6, 2]
        embed_dim = 96
        focal_levels=[3, 3, 3, 3]
        default_classes = 1000
    elif model_name == "focalnet_small_srf":
        depths = [2, 2, 18, 2]
        embed_dim=96
        default_classes = 1000
    elif model_name == "focalnet_small_lrf":
        depths = [2, 2, 18, 2]
        embed_dim = 96
        focal_levels=[3, 3, 3, 3]
        default_classes = 1000
    elif model_name == "focalnet_base_srf":
        depths = [2, 2, 18, 2]
        embed_dim = 128
        default_classes = 1000
    elif model_name == "focalnet_base_lrf":
        depths = [2, 2, 18, 2]
        embed_dim = 128
        focal_levels=[3, 3, 3, 3]
        default_classes = 1000
    elif model_name == "focalnet_large_fl3":
        depths = [2, 2, 18, 2]
        embed_dim = 192
        focal_levels=[3, 3, 3, 3]
        focal_windows = [5, 5, 5, 5]
        use_conv_embed = True
        use_postln = True
        use_layerscale =   True
        default_classes = 21842
    elif model_name == "focalnet_large_fl4":
        depths = [2, 2, 18, 2]
        embed_dim = 192
        focal_levels = [4, 4, 4, 4]
        focal_windows =[3, 3, 3, 3]
        use_conv_embed = True
        use_postln = True
        use_layerscale = True
        normalize_modulator = True
        default_classes = 21842
    elif model_name == "focalnet_xlarge_fl3":
        depths = [2, 2, 18, 2]
        embed_dim = 256
        focal_levels=[3, 3, 3, 3]
        focal_windows = [5, 5, 5, 5]
        use_conv_embed = True
        use_postln = True
        use_layerscale = True
        default_classes = 21842
    elif model_name == "focalnet_xlarge_fl4":
        depths = [2, 2, 18, 2]
        embed_dim = 256
        focal_levels=[4, 4, 4, 4]
        focal_windows =[3, 3, 3, 3]
        use_conv_embed = True
        use_postln = True
        use_layerscale = True
        default_classes = 21842
    elif model_name == "focalnet_huge_fl3":
        depths = [2, 2, 18, 2]
        embed_dim = 352
        focal_levels=[3, 3, 3, 3]
        focal_windows =[3, 3, 3, 3]
        use_conv_embed = True
        use_postln = True
        use_layerscale = True
        use_postln_in_modulation= True
        default_classes = 21842
    elif model_name == "focalnet_huge_fl4":
        depths = [2, 2, 18, 2]
        embed_dim = 352
        focal_levels=[4, 4, 4, 4]
        focal_windows =[3, 3, 3, 3]
        use_conv_embed = True
        use_postln = True
        use_layerscale = True
        use_postln_in_modulation= True
        default_classes = 21842
    else:
        raise("model name not found")

    if "use_layerscale" in kwargs:
        use_layerscale = kwargs["use_layerscale"]
        del kwargs["use_layerscale"]

    if "use_conv_embed" in kwargs:
        use_conv_embed = kwargs["use_conv_embed"]
        del kwargs["use_conv_embed"]

    if "use_postln" in kwargs:
        use_postln = False
        del kwargs["use_postln"]

    if "normalize_modulator" in kwargs:
        normalize_modulator = kwargs["normalize_modulator"]
        del kwargs["normalize_modulator"]

    if "use_postln_in_modulation" in kwargs:
        use_postln_in_modulation= kwargs["use_postln_in_modulation"]
        del kwargs["use_postln_in_modulation"]

    if num_classes is None and pretrained:
        num_classes = default_classes
    elif num_classes is None:
        num_classes = 0

    backbone = FocalNet(depths=depths, embed_dim=embed_dim, focal_windows=focal_windows, focal_levels=focal_levels, use_conv_embed=use_conv_embed, use_postln=use_postln,
                        use_layerscale=use_layerscale, normalize_modulator=normalize_modulator, use_postln_in_modulation=use_postln_in_modulation, num_classes=num_classes, **kwargs)
    if pretrained:
        root_dir = os.path.sep.join(os.path.abspath(__file__).split(os.path.sep)[:-1])
        filename = f"{root_dir}/{FOLDER_WEIGHTS}/{model_name}.h5"
        #print(filename)
        if not os.path.exists(filename):
            # download
            download_checkpoint(model_name)
            #print("file not here")

        backbone.load_weights(filename, by_name=True, skip_mismatch=True)

    if return_model:
        inputs = Input(input_shape)
        outputs = backbone(inputs)
        model = Model(inputs=inputs, outputs=outputs)
        return model
    return backbone


def ladderLength(beginWord, endWord, wordList):
    if endWord not in wordList:
        return 0

    def twowords(wa, wb):
        res = 0
        if len(wa) != len(wb):
            return -1
        else:
            for i in range(len(wa)):
                if wa[i] != wb[i]:
                    res += 1
            return res

    stack = [beginWord]
    less = 0
    start = 0
    while endWord not in stack:
        less += 1
        le = len(stack)
        for i in range(start, le):
            for j in range(len(wordList)):
                if wordList[j] in stack:
                    continue
                if twowords(stack[i], wordList[j]) == 1 and wordList[j] not in stack:
                    stack.append(wordList[j])
        newle = len(stack)
        if newle == le and endWord not in stack:
            return 0
            break
        start = le
    return less + 1

beginWord = "hit"
endWord = "cog"
wordList = ["hot","dot","dog","lot","log","cog"]
print(ladderLength(beginWord, endWord, wordList))

# class Solution:  双向BFS 好难
#     def ladderLength(self, beginWord: str, endWord: str, wordList: List[str]) -> int:
#         if endWord not in wordList:
#             return 0
#         wordict = set(wordList)
#         s1 = {beginWord}
#         s2 = {endWord}
#         n = len(beginWord)
#         step = 0
#         wordict.remove(endWord)
#         while s1 and s2:
#             step += 1
#             if len(s1) > len(s2): s1, s2 = s2, s1
#             s = set()
#             for word in s1:
#                 nextword = [word[:i] + chr(j) + word[i + 1:] for j in range(97, 123) for i in range(n)]
#                 for w in nextword:
#                     if w in s2:
#                         return step + 1
#                     if w not in wordict: continue
#                     wordict.remove(w)
#                     s.add(w)
#             s1 = s
#         return 0
#
# 作者：powcai
# 链接：https://leetcode-cn.com/problems/word-ladder/solution/bfscong-wu-dao-you-by-powcai/
# 来源：力扣（LeetCode）
# 著作权归作者所有。商业转载请联系作者获得授权，非商业转载请注明出处。


from tkinter import*

root = Tk() # 메인 창
root.title("Nado GUI") # 제목 설정
root.geometry("640x480") # 화면 크기

###################################################
# 체크 박스 (체크/체크 해제 가능)

checkVariable = IntVar() # checkVariable에 int형으로 값을 저장.
checkbox = Checkbutton(root, text = "오늘 하루 보지 않기", variable = checkVariable)

# 프로그램 내에서 선택/해제 하기
checkbox.select() # 선택 함
checkbox.deselect() # 선택 해제

checkbox.pack()

# 체크박스를 만들때 var도 새로 만들어줘야 함
checkVariable2 = IntVar()
chkbox2 = Checkbutton(root, text = "일주일동안 보지 않기", variable = checkVariable2)
chkbox2.pack()

def btnCmd():
    # 프로그램 내에서 체크의 여부 확인
    print(checkVariable.get()) # 숫자 0 = 체크 x ; 숫자 1 = 체크 o

btn = Button(root, text = "클릭", command = btnCmd)
btn.pack()

root.mainloop() #pygame.init() 같이 초기화해줌


#!/usr/bin/env python3
"""Module with new authentication mechanism"""
from api.v1.auth.session_auth import SessionAuth
from os import getenv
from datetime import datetime, timedelta

class SessionExpAuth(SessionAuth):
    """A class that inherits from sessionAuth"""

    def __init__(self):
        """A function that initializes the instance of SessionExpAuth"""
        try:
            self.session_duration = int(getenv('SESSION_DURATION', 0))
        except ValueError:
            self.session_duration = 0

    def create_session(self, user_id=None):
        """A function that creates a Session ID for a user_id"""
        session_id = super().create_session(user_id)
        if session_id is None:
            return None

        SessionExpAuth.user_id_by_session_id[session_id] = {
            'user_id': user_id,
            'created_at': datetime.now()
        }

        return session_id

    def user_id_for_session_id(self, session_id=None):
        """A function that returns a User ID based on a Session ID"""
        if session_id is None:
            return None

        session_dict = SessionExpAuth.user_id_by_session_id.get(
            session_id, None)
        if session_dict is None:
            return None
        if 'created_at' not in session_dict:
            return None

        if self.session_duration <= 0:
            return session_dict.get('user_id')

        creation_time = session_dict.get('created_at')

        session_length = timedelta(seconds=self.session_duration)

        expiry_time = creation_time + session_length

        if expiry_time < datetime.now():
            return None
        return session_dict.get('user_id')


import os
import subprocess
import sys
import re
from collections import defaultdict

BWA = "bwa"
SAMTOOLS = "samtools"
CDHIT = "cd-hit"
BLASTN = "blastn"
TEMPDIR = "."

def checkDependencies():
    cmd = [BWA]
    try:
        p = subprocess.Popen(cmd, stderr=subprocess.PIPE, stdout=subprocess.PIPE)
    except:
        sys.exit("Error: bwa not installed!")

    cmd = [SAMTOOLS, "--version"]
    try:
        p = subprocess.Popen(cmd, stderr=subprocess.PIPE, stdout=subprocess.PIPE)
    except:
        sys.exit("Error: samtools not installed!")

    cmd = [CDHIT]
    try:
        p = subprocess.Popen(cmd, stderr=subprocess.PIPE, stdout=subprocess.PIPE)
    except:
        sys.exit("Error: CD-HIT not installed!")

    cmd = [BLASTN]
    try:
        p = subprocess.Popen(cmd, stderr=subprocess.PIPE, stdout=subprocess.PIPE)
    except:
        sys.exit("Error: Blastn not installed!")

def preprocess():
    os.chdir(TEMPDIR)

def readSoftClips(file):
    os.system("rm *.fa")
    # read softclip file
    f= open(file,'r')
    #leftDict stores the sequences that matched sequence is on right side and softclip is on left side
    leftDict_softclip=defaultdict(list)
    leftDict_virusSeq=defaultdict(list)
    #rightDict stores the sequences that matched sequence is on left side and softclip is on right side
    rightDict_softclip=defaultdict(list)
    rightDict_virusSeq=defaultdict(list)
    for line in open(file):
        line = f.readline()
        subStr= line.split('\t')
        match1 = re.search(r'^(\d+)M(\d+)S$', subStr[3])
        match2 = re.search(r'^(\d+)S(\d+)M$', subStr[3])
        if match1:
            pos1 = int(match1.group(1))
            pos2 = int(match1.group(2))
            if pos1>=15 and pos2>=15:
                softclip = subStr[4][pos1:]
                virusSeq = subStr[4][0:pos1]
                breakpoint = int(subStr[1])+pos1
                leftDict_softclip[breakpoint].append(softclip)
                if breakpoint in leftDict_virusSeq:
                    if len(virusSeq) > leftDict_virusSeq[breakpoint]:
                        leftDict_virusSeq[breakpoint] = virusSeq
                else:
                    leftDict_virusSeq[breakpoint].append(virusSeq)
        if match2:
            pos1 = int(match2.group(1))
            pos2 = int(match2.group(2))
            if pos1>=15 and pos2>=15:
                softclip = subStr[4][0:pos1]
                virusSeq = subStr[4][pos1:]
                breakpoint = int(subStr[1])
                rightDict_softclip[breakpoint].append(softclip)
                if breakpoint in rightDict_virusSeq:
                    if len(virusSeq) > rightDict_virusSeq[breakpoint]:
                        rightDict_virusSeq[breakpoint] = virusSeq
                else:
                    rightDict_virusSeq[breakpoint].append(virusSeq)
    f.close()

    # write breakpoints into fa files
    for keyname, seqList in rightDict_softclip.items():
        f2=open("right_breakpoint"+str(keyname)+".fa", 'w+')
        count2=1
        for seq in seqList:
            f2.writelines("> seq"+str(count2)+'\n')
            f2.writelines(seq+'\n')
            count2=count2+1
        f2.close()

    for keyname, seqList in leftDict_softclip.items():
        f2=open("left_breakpoint"+str(keyname)+".fa", 'w+')
        count2=1
        for seq in seqList:
            f2.writelines("> seq"+str(count2)+'\n')
            f2.writelines(seq+'\n')
            count2=count2+1
        f2.close()

def main():
    checkDependencies()
    preprocess()
    readSoftClips(file='HPV16.softclip.txt')

if __name__ == "__main__":
	main()


from http.client import responses

from django.http import JsonResponse
from django.shortcuts import get_object_or_404
from django.utils.decorators import method_decorator
from drf_spectacular.types import OpenApiTypes
from drf_spectacular.utils import extend_schema, OpenApiResponse
from rest_framework import generics, status
from rest_framework.exceptions import ParseError
from rest_framework.response import Response
from rest_framework.views import APIView

from users.models import CustomUser
from users.pagination import CustomPagination
from users.serializers import LoginUserSerializer, BasicUserSerializer, PatchUserSerializer
from utils.serializers import BadRequestSerializer, ValidationErrorSerializer, PaginatedResponceSerializer

class CurrentUserView(APIView):

    @extend_schema(
        responses={
            200: OpenApiResponse(response=LoginUserSerializer, description=responses[200]),
            401: OpenApiResponse(response=OpenApiTypes.STR, description=responses[200])})
    def get(self, request):
        serializer = LoginUserSerializer(request.user)
        return Response(serializer.data)

@method_decorator(
    name='get',
    decorator=extend_schema(
        responses={
            200: OpenApiResponse(response=PaginatedResponceSerializer, description=responses[200]),
            400: OpenApiResponse(response=BadRequestSerializer, description=responses[400]),
            401: OpenApiResponse(response=OpenApiTypes.STR, description=responses[401]),
            422: OpenApiResponse(response=ValidationErrorSerializer, description=responses[422])}))
class UsersListView(generics.ListAPIView):
    queryset = CustomUser.objects.all().order_by('id')
    pagination_class = CustomPagination

    def get_serializer(self, *args, **kwargs):
        serializer = BasicUserSerializer(self.paginate_queryset(self.queryset), many=True)
        return serializer

class UserUpdateView(APIView):
    @extend_schema(
        request=PatchUserSerializer,
        responses={
            200: OpenApiResponse(response=PatchUserSerializer, description=responses[200]),
            400: OpenApiResponse(response=BadRequestSerializer, description=responses[400]),
            401: OpenApiResponse(response=OpenApiTypes.STR, description=responses[401]),
            404: OpenApiResponse(response=OpenApiTypes.STR, description=responses[404]),
            422: OpenApiResponse(response=ValidationErrorSerializer, description=responses[422])})
    def patch(self, request, pk):
        get_object_or_404(CustomUser, pk=pk)

        user = request.user
        if user.id == pk:
            serializer = PatchUserSerializer(user, data=request.data, partial=True)
            if serializer.is_valid(raise_exception=True):
                serializer.save()
                return JsonResponse(data=serializer.data, status=status.HTTP_200_OK)
        else:
            raise ParseError('You cannot change other users data')


#!/usr/bin/env python
# coding: utf-8

import numpy as np
import os

os.system('source /home/jackalak/heartbeat_work/cdf38_0-dist/bin/definitions.B')
os.environ["CDF_LIB"] = '/home/jackalak/heartbeat_work/cdf38_0-dist/lib'

import pandas as pd
import seaborn as sns
from pandas.plotting import register_matplotlib_converters
register_matplotlib_converters()
import datetime
from os.path import isfile, join
from sys import getsizeof
import glob

from random import *
from sklearn import *
from scipy import interpolate
from ovationpyme import ovation_utilities
from ovationpyme.ovation_utilities import robinson_auroral_conductance
from ovationpyme.ovation_utilities import brekke_moen_solar_conductance
import geospacepy
from geospacepy import special_datetime,astrodynamics2,satplottools
import aacgmv2 #available on pip

import numpy as np
import matplotlib.pyplot as plt
from ovationpyme.ovation_prime import FluxEstimator,AverageEnergyEstimator,BinCorrector, SeasonalFluxEstimator
from ovationpyme.ovation_utilities import calc_avg_solarwind
from ovationpyme.ovation_plotting import latlt2polar,polar2dial,pcolor_flux
import ipywidgets
from collections import OrderedDict
from functools import partial

# Note ions are disabled for now
auroral_types = ['diff','mono','wave']#,'ions']
flux_types = [
                "energy",
                "number",
                "average energy"
            ]

import datetime
from collections import OrderedDict

import numpy as np
import functools

from geospacepy import omnireader, special_datetime, astrodynamics2

_ovation_prime_omni_cadence = 'hourly' #Ovation Prime was created using hourly SW

atype =auroral_types[0] #widgets['atype_select'].value
jtype = 'energy'#widgets['jtype_select'].value
bincorrect = True#widgets['bincorrect_toggle'].value
combine_hemispheres = True#widgets['combineNS_toggle'].value
manual_newell = -1#widgets['newell_float'].value

file_load_df_cumulative = 'ML_DB_subsamp_ext_full_dfCumulative_complexHemisphereCombine.csv'
DMSP_DATA_DIR=''
df_cumulative = pd.read_csv(os.path.join(DMSP_DATA_DIR,file_load_df_cumulative))
df_cumulative = df_cumulative.sort_values(by=[ 'Datetimes'])
df_cumulative = df_cumulative.set_index('Datetimes')
df_cumulative.index = pd.to_datetime(df_cumulative.index)

cols_to_drop_validation = [c for c in df_cumulative.columns if ('STD' in c) | ('AVG' in c)]#] | ('SC_AACGM_LTIME'==c)]

df_cumulative = df_cumulative.drop(columns=cols_to_drop_validation)

# Separate training and testing data
mask_val = [(df_cumulative.index.year == 2010) & (df_cumulative['ID_SC'].values==16)]
df_val = df_cumulative[mask_val[0]].copy(deep=True)
df_train = df_cumulative.copy(deep=True).drop( df_cumulative.index[mask_val[0]])
print('validation data shape = {}'.format(df_val.shape))
print('train data shape = {}'.format(df_train.shape))

ovation_input = [df_val.index,df_val['SC_AACGM_LAT'],df_val['SC_AACGM_LTIME']]

no_cdf_list = []

times = ovation_input[0]
lats = ovation_input[1]
longs = ovation_input[2]
ovation_fluxes_val = np.zeros((4,len(ovation_input[0])))

seasons = ['spring','summer','fall','winter']

for atype_index in range(len(auroral_types)):

    print(atype_index)
    dt = times[-1]
    jd = ovation_utilities.check_jd(dt)

    atype =auroral_types[atype_index] #widgets['atype_select'].value
    estimator = FluxEstimator(atype,jtype)
    seasonal_flux_estimators = {season:SeasonalFluxEstimator(season,atype,jtype) for season in seasons}
    print('starting ', atype_index)
    for i in range(0,len(times)):

        dt = times[i]
        lat = lats[i]
        long = longs[i]

        if lat < 50.:
            lat = 50.

        lat_index = int(round((lat - 50.)/.50632911))
        long_index = int(round(long/ 0.25263158))

        jd_last = jd.copy()
        try:
            #print(dt)
            jd = ovation_utilities.check_jd(dt)
        except Exception as e:
            print(str(e))
            print(dt)
            no_cdf_list.append(dt)

        if jd[0] != jd_last[0]:

            doy = dt.timetuple().tm_yday
            weights = estimator.season_weights(doy)
            try:
                dF = ovation_utilities.calc_dF(dt)
            except Exception as e:
                #print(str(e))
                #print(dt)
                no_cdf_list.append(dt)
            season_fluxes_outs = estimator.get_season_fluxes(dF)
            grid_mlats,grid_mlts,seasonfluxesN,seasonfluxesS = season_fluxes_outs

            gridflux = np.zeros_like(seasonfluxesN['summer'])
            for season,W in weights.items():
                gridfluxN,gridfluxS = seasonfluxesN[season],seasonfluxesS[season]
                if combine_hemispheres:
                    gridflux += W*(gridfluxN+gridfluxS)/2
                elif hemi=='N':
                    gridflux += W*gridfluxN
                elif hemi=='S':
                    gridflux += W*gridfluxS

        ovation_fluxes_val[atype_index,i] = gridflux[lat_index,long_index]
# below is with no corrections
#         seasonfluxesN,seasonfluxesS = {},{}
#         for season,s_estimator in seasonal_flux_estimators.items():
#             gridfluxN,gridfluxS = s_estimator.get_gridded_flux_i_j(dF,long_index, lat_index)
#             seasonfluxesN[season]=gridfluxN
#             seasonfluxesS[season]=gridfluxS

#         gridflux=0
#         #print(weights.items())
#         for season,W in weights.items():
#             gridfluxN,gridfluxS = seasonfluxesN[season],seasonfluxesS[season]
#             if combine_hemispheres:
#                 gridflux += W*(gridfluxN+gridfluxS)/2
#         ovation_fluxes_val[atype_index,i] = gridflux

        #print(i, ovation_fluxes[i], dt, lat,long,lat_index, long_index)

print('done')
import pickle
with open('ovation_fluxes_val','wb') as f: pickle.dump(ovation_fluxes_val, f)
#with open('ovation_fluxes_val','rb') as f: ovation_fluxes_val = pickle.load(f)

# Now for the training data

ovation_input = [df_train.index,df_train['SC_AACGM_LAT'],df_train['SC_AACGM_LTIME']]

no_cdf_list = []

times = ovation_input[0]
lats = ovation_input[1]
longs = ovation_input[2]
ovation_fluxes_train = np.zeros((4,len(ovation_input[0])))

seasons = ['spring','summer','fall','winter']

for atype_index in range(len(auroral_types)):

    print(atype_index)
    dt = times[-1]
    jd = ovation_utilities.check_jd(dt)

    atype =auroral_types[atype_index] #widgets['atype_select'].value
    estimator = FluxEstimator(atype,jtype)
    seasonal_flux_estimators = {season:SeasonalFluxEstimator(season,atype,jtype) for season in seasons}
    print('starting ', atype_index)
    for i in range(0,len(times)):

        dt = times[i]
        lat = lats[i]
        long = longs[i]

        if lat < 50.:
            lat = 50.

        lat_index = int(round((lat - 50.)/.50632911))
        long_index = int(round(long/ 0.25263158))

        jd_last = jd.copy()
        try:
            #print(dt)
            jd = ovation_utilities.check_jd(dt)
        except Exception as e:
            print(str(e))
            print(dt)
            no_cdf_list.append(dt)

        if jd[0] != jd_last[0]:

            doy = dt.timetuple().tm_yday
            weights = estimator.season_weights(doy)
            try:
                dF = ovation_utilities.calc_dF(dt)
            except Exception as e:
                #print(str(e))
                #print(dt)
                no_cdf_list.append(dt)
            season_fluxes_outs = estimator.get_season_fluxes(dF)
            grid_mlats,grid_mlts,seasonfluxesN,seasonfluxesS = season_fluxes_outs

            gridflux = np.zeros_like(seasonfluxesN['summer'])
            for season,W in weights.items():
                gridfluxN,gridfluxS = seasonfluxesN[season],seasonfluxesS[season]
                if combine_hemispheres:
                    gridflux += W*(gridfluxN+gridfluxS)/2
                elif hemi=='N':
                    gridflux += W*gridfluxN
                elif hemi=='S':
                    gridflux += W*gridfluxS

        ovation_fluxes_train[atype_index,i] = gridflux[lat_index,long_index]

print('done')
import pickle
with open('ovation_fluxes_train','wb') as f: pickle.dump(ovation_fluxes_train, f)
#with open('ovation_fluxes_train','rb') as f: ovation_fluxes_train = pickle.load(f)


#!/usr/bin/env python3
import matplotlib.pyplot as plt
import cartopy.crs as ccrs
import obspy.core.event.catalog, obspy.geodetics.base
from obspy.clients.fdsn import Client as fdsnClient
from numpy import mean,std
from sys import argv
golden = (1 + 5 ** 0.5) / 2

"""
Displaying WMTS tiled map data
------------------------------

This displays imagery from a web map tile service and seismic events from an FDSN web service. This result can also be interactively panned and zoomed.

"""

def plot_eq(ax,m,marker,color=None,**opts):

    o=m.origin_id.get_referred_object()
    desc='%.3g km deep %s%.2g\nat %s\nby %s (%s)'%(o.depth/1000,m.magnitude_type,m.mag,m.creation_info.creation_time,m.creation_info.author,m.creation_info.agency_id)
    ax.plot(o.longitude,o.latitude,marker,color='w',zorder=1,markeredgewidth=6,**opts)
    ax.plot(o.longitude,o.latitude,marker,color='k',zorder=2,markeredgewidth=1,**opts)
    if color is not None:
        opts['color']=color
    ax.plot(o.longitude,o.latitude,marker,zorder=3,markeredgewidth=0,**opts,label=desc)

def plot_wms(self,
             fdsnws_uri='ETH',
             wms = 'https://wms.geo.admin.ch',
             layers = ['ch.swisstopo.pixelkarte-farbe'],
             crs = ccrs.Orthographic,
             **kwargs):

    if self is not obspy.core.event.catalog.Catalog:
        self = fdsnClient(fdsnws_uri).get_events(**kwargs)

    longitude=[]
    latitude=[]
    for e in self:
        longitude+=[o.longitude for o in e.origins]
        latitude+=[o.latitude for o in e.origins]

    longitude+=[min(longitude)-std(longitude),
                   max(longitude)+std(longitude)]
    latitude+=[min(latitude)-std(latitude),
                   max(latitude)+std(latitude)]

    kmlo,az,baz=obspy.geodetics.base.gps2dist_azimuth(mean(latitude),mean(longitude),
                                                    mean(latitude),mean(longitude)+1)
    kmla,az,baz=obspy.geodetics.base.gps2dist_azimuth(mean(latitude),mean(longitude),
                                                    mean(latitude)+1,mean(longitude))
    y = latitude.copy()
    x = longitude.copy()
    if max(longitude)-min(longitude) > kmla/kmlo*golden*(max(latitude)-min(latitude)):
        # Too large
        m = mean(y)
        d = max(x)-min(x)
        latitude.append(m + d/(2*golden))
        latitude.append(m - d/(2*golden))
    else:
        # Too high
        m = mean(x)
        d = max(y)-min(y)
        longitude.append(m + kmla/kmlo*d*golden/2)
        longitude.append(m - kmla/kmlo*d*golden/2)

    # Create a Cartopy crs for plain and rotated lat-lon projections.
    projection = crs(central_longitude=mean(longitude),
                     central_latitude=mean(latitude))

    # Plot WMTS data in a specific region, over a plain lat-lon map.
    fig = plt.figure(figsize=(12*golden,12))
    ax = plt.axes([0, 0, 1, 1], projection=projection)
    ax.set_extent([min(longitude),
                   max(longitude),
                   min(latitude),
                   max(latitude)],
                  ccrs.PlateCarree())

    #ax.coastlines(resolution='50m', color='yellow')
    #ax.gridlines(color='lightgrey', linestyle='-')

    # Add WMS imaging.
    ax.add_wms(wms=wms,
               layers=layers,
               #wms_kwargs={'width':2160*2}
               )

    # Add earthquakes
    opts={'transform':ccrs.PlateCarree(),
          'solid_capstyle':'round',
          'markersize':16}
    # Breaks projection: cat.plot(fig=ax,method='cartopy',**opts)
    for e in self:
        m=e.preferred_magnitude()
        plot_eq(ax,m,'o',**opts)
        if len(self)==1:
            for m in e.magnitudes:
                if m is e.preferred_magnitude():
                    continue
                if m.magnitude_type != e.preferred_magnitude().magnitude_type :
                    continue
                plot_eq(ax,m,'P',**opts)

    if len(self)==1:
        ax.legend()

    fig.savefig('plot/map.png')
    plt.show()

## obspy integration should be:
#class Origin(...):
#
#    def delay(self, ...):
#        return utils._delay(self, ...)
## But the quick and dirty is:
obspy.core.event.catalog.Catalog.plot_wms = plot_wms
## Any instance of Catalog has the method plot_wms

if __name__ == '__main__':

    if '-h' in argv:
        print(' Try:\n%s "eventid=smi:ch.ethz.sed/sc20a/Event/2022rrcgvq" "includeallmagnitudes=1" "includeallorigins=1"'%argv[0])
    else:
        args={ arg.split('=')[0]:arg.split('=')[1] for arg in argv if "=" in arg}
        print('Arguments provided:')
        print(args)

        plot_wms(None,**args)


import sys
import time
import logging
from PySide2.QtWidgets import QMainWindow, QApplication
from PySide2.QtCore import Signal, QObject, QThread

class Worker(QObject):
    print_signal = Signal(str, int)
    exit_signal =Signal(object)
    def __init__(self):
        super().__init__()

    def ok(self):
            self.print_signal.emit("strings", 10)
            time.sleep(1)
            self.exit_signal.emit(None)

class Mainwindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.worker = Worker()
        self.workerThread = QThread()
        self.workerThread.started.connect(self.worker.ok)  # Init worker run() at startup (optional)
        self.worker.print_signal.connect(self.printing)  # Connect your signals/slots
        self.worker.moveToThread(self.workerThread)  # Move the Worker object to the Thread object
        self.workerThread.start()
        self.worker.exit_signal.connect(self.closing)

    def __del__(self):
        pass

    def closing(self):
        self.workerThread.exit()
        self.workerThread.wait()
        self.close()

    def printing(self, text, number):
        print(text)
        print(number)

if __name__== '__main__':
    app = QApplication()
    mainwindow = Mainwindow()
    sys.exit(app.exec_())


import json
import logging
import re

logger = logging.getLogger()
logger.setLevel(logging.INFO)

def hello_endpoint(event, context):
  logger.info(event)

  body = {
    "message": "Hello world!"
  }

  response = {
    "statusCode": 200,
    "body": json.dumps(body)
  }

  return response

def sum_endpoint(event, context):
  logger.info(event)

  # Default response
  body = {
    "error": "Please provide at least one number e.g. numbers=1,2,3"
  }

  if 'body' in event and event['body'] is not None:
    # Regex that matches "numbers=1,2,33"
    r = re.compile("^numbers=([-+]?([1-9]\\d*|0),?)+$")
    # Get numbers from post data
    numbers = list(filter(r.match, event['body'].split('&')))
    if len(numbers) > 0:
      numbers = numbers[0].replace('numbers=', '')
      numbers = numbers.split(',')
      body = {
        "sum": sum(map(int, numbers))
      }

  response = {
    "statusCode": 200,
    "body": json.dumps(body)
  }

  return response


"""
.. module:: GaussianDistribution
   :synopsis: A dataset with an array of patterns and corresponding labels

.. moduleauthor:: Ambra Demontis <ambra.demontis@unica.it>
.. moduleauthor:: Marco Melis <marco.melis@unica.it>

"""
from scipy.stats import multivariate_normal
from secml.array import CArray
from secml.core import CCreator

class CDistributionGaussian(CCreator):
    """A multivariate normal random variable.

    Parameters
    ----------
    mean : scalar, optional
        Mean of the distribution (default zero)
    cov : array_like or scalar, optional
        Covariance matrix of the distribution (default one)

    """

    def __init__(self, mean=0, cov=1):

        self.mean = mean
        self.cov = cov

    def pdf(self, data):
        """Probability density function.

        Parameters
        ----------
        data : CArray
            Quantiles, with the last axis of x denoting the components.

        Returns
        -------
        pdf: CArray
            Probability density function computed at input data.

        """
        cov = self.cov
        if isinstance(cov, CArray):
            cov = cov.tondarray()
        return CArray(multivariate_normal.pdf(data.tondarray(),
                                              self.mean, cov))

    def logpdf(self, data):
        """Log of the probability density function.

        Parameters
        ----------
        data : CArray
            Quantiles, with the last axis of x denoting the components.

        Returns
        -------
        pdf: CArray
            Probability density function computed at input data.

        """
        cov = self.cov
        if isinstance(cov, CArray):
            cov = cov.tondarray()
        return CArray(multivariate_normal.logpdf(data.tondarray(),
                                                 self.mean, cov))


from flask import g
import re

'''
This is a helper class to parse
CloudWatch slow query log events
'''

regexPerformance = re.compile(
    r"^# Query_time:\s+(\d+\.\d+)\s+Lock_time:\s+(\d+\.\d+)\s+Rows_sent:\s+(\d+)\s+Rows_examined:\s+(\d+)"
)

regexUserInfo = re.compile(
    r"^# User@Host:\s+(\S+)\s+@\s+(.*)\s+Id:\s+(\d+)"
)

regexLinesToIgnore = [
    re.compile(r"^#"),
    re.compile(r"^use ", re.I),
    re.compile(r"^set ", re.I)
]

class CWEvent:
    """
    static regex patterns used in the parse_log_entry function
    """

    def __init__(self, event):
        self._event = event

    @staticmethod
    def skip_line(line):
        for regex in regexLinesToIgnore:
            if bool(regex.match(line)):
                g.logger.debug("IGNORE: {}".format(line))
                return True
        return False

    def parse(self):
        cw_event = self._event
        query = None
        query_time = None
        lock_time = None
        sent = None
        rows = None
        host = None
        user = None
        log_session = None
        for line in cw_event['message'].splitlines():
            g.logger.debug("LINE: {}".format(line))
            user_info = regexUserInfo.match(line)
            if user_info:
                query = ""
                user = user_info.group(1)
                host = user_info.group(2)
                log_session = user_info.group(3)
                continue

            if bool(re.match('^# Query_time:', line)):
                query = ""
                g.logger.debug("QT LIKELY: {}".format(line))
                m = regexPerformance.match(line)
                if m:
                    query_time = float(m.group(1))
                    lock_time = float(m.group(2))
                    sent = int(m.group(3))
                    rows = int(m.group(4))
                    g.logger.debug("QT OK: {} {}".format(query_time, rows))
                else:
                    g.logger.debug("QT ERROR: {}".format(line))
                continue

            if self.skip_line(line):
                continue

            query = query + line + "\t"

        # done with the entry... do we have a pending query to output
        if any(x is None for x in [rows, query_time, lock_time, user, host]):
            g.logger.info("PARSE_FAILED: {}".format(cw_event))
            g.logger.info("PARSE_FAILED: {} {} {} {} {}".format(
                rows,
                query_time,
                lock_time,
                user,
                host
            ))
        return {
            'event': cw_event,
            'qtime': query_time,
            'session': log_session,
            'rows': rows,
            'sent': sent,
            'ltime': lock_time,
            'query': query,
            'raw': cw_event['message'],
            'timestamp': cw_event['timestamp']
        }


from indico.core.notifications import make_email, send_email
from indico.modules.events.editing.schemas import EditingConfirmationAction
from indico.web.flask.templating import get_template_module

def _get_commenting_users(revision, check_internal_access=False):
    return {
        c.user
        for c in revision.comments
        if not check_internal_access or revision.editable.can_use_internal_comments(c.user)
    }

def notify_comment(comment):
    """Notify about a new comments on a revision."""
    revision = comment.revision
    editable = revision.editable
    editor = editable.editor
    submitter = next((r.user for r in editable.revisions[::-1] if r.is_submitter_revision), None)
    author = comment.user
    if comment.internal:
        # internal comments notify the editor and anyone who commented + can see internal comments
        recipients = _get_commenting_users(revision, check_internal_access=True) | {editor}
    elif author == editor:
        # editor comments notify the submitter and anyone else who commented
        recipients = _get_commenting_users(revision) | {submitter}
    elif editable.can_perform_submitter_actions(author):
        # submitter comments notify the editor and anyone else who commented
        recipients = _get_commenting_users(revision) | {editor}
    else:
        # comments from someone else (managers) notify everyone
        recipients = _get_commenting_users(revision) | {editor, submitter}

    recipients.discard(None)  # in case there's no editor assigned
    recipients.discard(author)  # never bother people about their own comments
    for recipient in recipients:
        author_name = author.first_name if editable.can_see_editor_names(recipient, author) else None
        with recipient.force_user_locale():
            tpl = get_template_module('events/editing/emails/comment_notification.txt',
                                      author_name=author_name,
                                      timeline_url=editable.external_timeline_url,
                                      recipient_name=recipient.first_name)
            email = make_email(recipient.email, template=tpl)
        send_email(email, editable.event, 'Editing', log_metadata={'editable_id': editable.id})

def notify_editor_judgment(revision, editor):
    """Notify the submitter about a judgment made by an editor."""
    submitter = revision.user
    editable = revision.editable
    editor_name = editor.first_name if editable.can_see_editor_names(submitter) else None
    with submitter.force_user_locale():
        tpl = get_template_module('events/editing/emails/editor_judgment_notification.txt',
                                  editor_name=editor_name,
                                  timeline_url=editable.external_timeline_url,
                                  recipient_name=submitter.first_name)
        email = make_email(submitter.email, template=tpl)
    send_email(email, editable.event, 'Editing', log_metadata={'editable_id': editable.id})

def notify_submitter_upload(revision):
    """Notify the editor about the submitter uploading a new revision."""
    editable = revision.editable
    submitter = revision.user
    editor = revision.editable.editor
    if not editor:
        return
    with editor.force_user_locale():
        tpl = get_template_module('events/editing/emails/submitter_upload_notification.txt',
                                  submitter_name=submitter.first_name,
                                  timeline_url=editable.external_timeline_url,
                                  recipient_name=editor.first_name)
        email = make_email(editor.email, template=tpl)
    send_email(email, editable.event, 'Editing', log_metadata={'editable_id': editable.id})

def notify_submitter_confirmation(revision, submitter, action):
    """Notify the editor(s) about submitter accepting/rejecting revision changes."""
    editable = revision.editable
    current_editor = editable.editor
    prev_revision_editor = next(rev.user for rev in editable.valid_revisions[::-1] if rev.is_editor_revision)
    recipients = {current_editor, prev_revision_editor}
    recipients.discard(None)
    if action == EditingConfirmationAction.accept:
        template_path = 'events/editing/emails/submitter_confirmation_notification.txt'
    else:
        template_path = 'events/editing/emails/submitter_rejection_notification.txt'
    for recipient in recipients:
        with recipient.force_user_locale():
            tpl = get_template_module(template_path,
                                      submitter_name=submitter.first_name,
                                      timeline_url=revision.editable.external_timeline_url,
                                      recipient_name=recipient.first_name)
            email = make_email(recipient.email, template=tpl)
        send_email(email, editable.event, 'Editing', log_metadata={'editable_id': editable.id})


from numpy import asarray
from scipy.spatial import Delaunay

from compas.datastructures.mesh import Mesh

__author__    = 'Tom Van Mele'
__copyright__ = 'Copyright 2016, Block Research Group - ETH Zurich'
__license__   = 'MIT license'
__email__     = 'vanmelet@ethz.ch'

__all__ = [
    'delaunay_from_mesh',
    'delaunay_from_points',
    'delaunay_from_boundary',
]

def delaunay_from_mesh(mesh):
    """Return a Delaunay triangulation from a given mesh.

    Parameters:
        mesh (compas.datastructures.mesh.Mesh) :
            The original mesh.

    Returns:
        mesh :
            ...

    >>> ...

    """
    d = Delaunay(mesh.xy)
    return Mesh.from_vertices_and_faces(mesh.xyz, d.simplices)

def delaunay_from_points(points):
    """"""
    xyz = asarray(points)
    assert 2 <= xyz.shape[1], "At least xy xoordinates required."
    d = Delaunay(xyz[:, 0:2])
    return Mesh.from_vertices_and_faces(points, d.simplices)

# @see: _scripts
def delaunay_from_boundary(boundary):
    """"""
    raise NotImplementedError

# ==============================================================================
# Debugging
# ==============================================================================

if __name__ == "__main__":
    pass


import sys
import openai

SYSTEM_PROMPT = "You are an expert Python machine learning developer."

class MaxTokensExceeded(BaseException):
    pass

def set_openai_api_key(api_key):
    openai.api_key = api_key

def call_gpt(messages, *, temperature=0.5):
    if type(messages) == str:
        messages = [{"role": "user", "content": messages}]

    try:
        response = openai.ChatCompletion.create(
            model="gpt-4",  # gpt-4-32k
            messages=[
                {
                    "role": "system",
                    "content": SYSTEM_PROMPT,
                },
            ]
            + messages,
            n=1,
            stop=None,
            temperature=temperature,
            stream=True,
        )
    except openai.error.RateLimitError as e:
        time.sleep(10)
        print(
            "Exceeded OpenAI rate limit, sleeping for ten seconds and retrying...",
            file=sys.stderr,
        )
        return call_gpt(messages, temperature=temperature)
    except openai.error.InvalidRequestError as e:
        if "This model's maximum context length is" in str(e):
            raise MaxTokensExceeded()
        raise

    text = ""
    for chunk in response:
        if not chunk:
            continue
        chunk_text = chunk["choices"][0]["delta"].get("content", None)
        if chunk_text == None:
            continue
        text += chunk_text
        sys.stderr.write(chunk_text)
        sys.stderr.flush()

    sys.stderr.write("\n")

    return text


import os

import tenacity

def retry_check_function_return_value_condition(
        f, check_condition, error_msg=None, retry_interval=1,
        retry_attempts=20):
    """Check if function f returns value s.t check_condition(value) is True."""

    @tenacity.retry(stop=tenacity.stop_after_attempt(retry_attempts),
                    wait=tenacity.wait_fixed(retry_interval))
    def retried_function():
        r = f()
        if not check_condition(r):
            raise Exception(error_msg or
                            'Actual return value ({}) does not satisfy '
                            'provided condition'.format(r))
        return r

    return retried_function()

def retry_check_function_return_value(f, expected_value, error_msg=None):
    """Check if function f returns expected value."""
    if not error_msg:
        error_msg = 'Expected value "%s" not found' % expected_value
    retry_check_function_return_value_condition(
        f, lambda v: v == expected_value, error_msg)

def retry_on_exception(f):
    """Decorator to retry on an exception."""
    def wrapper():
        try:
            return f()
        except Exception:
            return False
    return wrapper

def root_path():
    """Return path to root of source code."""
    x = os.path.realpath(__file__)
    x, y = os.path.split(x)  # drop "helper.py"
    x, y = os.path.split(x)  # drop "scenario"
    x, y = os.path.split(x)  # drop "tests"
    x, y = os.path.split(x)  # drop "congress_tempest_plugin"
    return x


"""
breyo.io
========

I/O code.

"""
import os
import astropy.units as u

def get_rawdir(night):
    return os.path.join(os.getenv('BREYO_DATA_DIR'), 'raw', night)

def get_reduxdir(night=None):
    reduxdir = os.path.join(os.getenv('BREYO_DATA_DIR'), 'reduced')
    if night:
        reduxdir = os.path.join(reduxdir, night)
    if not os.path.isdir(reduxdir):
        os.makedirs(reduxdir, exist_ok=True)
    calibdir = os.path.join(reduxdir, 'calib')
    if not os.path.isdir(calibdir):
        os.makedirs(calibdir, exist_ok=True)
    return reduxdir, calibdir

def read_config(verbose=False):
    import yaml

    # not sure why this doesn't work
    #import pkg_resources
    #configfile = pkg_resources.resource_filename('breyo', os.path.join('data', 'SBIG-STL-11000M.yaml'))

    configfile = os.path.join(os.getenv('BREYO_DIR'), 'py', 'breyo', 'data', 'SBIG-STL-11000M.yaml')

    if verbose:
        print('Reading configuration file {}'.format(configfile))
    with open(configfile, 'r') as ff:
        params = yaml.safe_load(ff)

    # attach units (see config file for comments)
    params['ccd']['pixsize'] *= u.micron
    params['ccd']['gain'] *= u.electron / u.adu
    params['ccd']['readnoise'] *= u.electron

    return params


# Backspace String Compare
# Given two strings s and t, return true if they are equal when both are typed into empty text editors. '#' means a backspace character.
# Note that after backspacing an empty text, the text will continue empty.

def backspaceCompare (s, t) :
    def buildStr (temp) :
        result = []
        for ch in temp :
            if ch != "#" :
                result.append(ch)
            elif result :
                result.pop()
        return result
    return buildStr(s) == buildStr(t)
print(backspaceCompare(s = "a#c", t = "b"))


import unittest

import numpy as np
from generator import generator

from mo.graph.graph import Node
from mo.ops.unsqueeze import Unsqueeze
from mo.utils.unittest.graph import build_graph, compare_graphs

@generator
class TestUnsqueezeOp(unittest.TestCase):
    nodes_attributes = {
        'data_1': {
            'kind': 'data',
            'shape': None,
            'value': None,
        },
        'unsq': {
            'op': 'Unsqueeze',
            'kind': 'op',
            'unsqueeze_dims': None,
        },
        'data_2': {
            'kind': 'data',
            'shape': None,
            'value': None,
        }
    }

    def test_unsqueeze_infer(self):
        graph = build_graph(self.nodes_attributes,
                            [('data_1', 'unsq'),
                             ('unsq', 'data_2')],
                            {'data_1': {'shape': np.array([1, 3, 64, 64])},
                             'unsq': {'unsqueeze_dims': np.array([0, 4])}
                             })

        graph_ref = build_graph(self.nodes_attributes,
                                [('data_1', 'unsq'),
                                 ('unsq', 'data_2')],
                                {'data_1': {'shape': np.array([1, 3, 64, 64])},
                                 'unsq': {'unsqueeze_dims': np.array([0, 4])},
                                 'data_2': {'shape': np.array([1, 1, 3, 64, 1, 64])}
                                 })

        unsqueeze_node = Node(graph, 'unsq')
        Unsqueeze.infer(unsqueeze_node)

        (flag, resp) = compare_graphs(graph, graph_ref, 'data_2')
        self.assertTrue(flag, resp)


import time
import websocket
from datetime import datetime

from PySide6.QtCore import QRunnable

from globals import Globals

class Conditioner(QRunnable):
    """
    Conditioner thread
    """

    def run(self):

        while True:
            microTime = int(datetime.now().strftime('%S'))
            if microTime == 35:
                try:
                    """sessionTime = int(datetime.now().strftime('%H'))
                    if not (sessionTime >= Globals.INSTRUMENTS[Globals.PAIR]['SESSION'][0] and sessionTime <
                            Globals.INSTRUMENTS[Globals.PAIR]['SESSION'][1]):
                        Globals.instrumentAllowed = False
                        continue"""

                    Globals.availableAssets = Globals.iqoapi.get_all_open_time()
                    if not Globals.availableAssets['turbo']['EURUSD']['open']:
                        Globals.instrumentAllowed = False
                        continue

                    """availableLeverage = Globals.iqoapi.get_available_leverages(Globals.INSTRUMENTS[Globals.PAIR]['TYPE'], Globals.INSTRUMENTS[Globals.PAIR]['ID'])
                    if not availableLeverage[1]['leverages'][0]['regulated'].count(Globals.INSTRUMENTS[Globals.PAIR]['LEVERAGE']) > 0:
                        Globals.instrumentAllowed = False
                        continue"""

                    Globals.instrumentAllowed = True
                    continue

                except (TypeError, websocket.WebSocketException) as e:
                    Globals.isConnected = False
                except:
                    Globals.instrumentAllowed = False
                    pass
            time.sleep(Globals.HIGH_PRIORITY_MS)


import pickle

# 모델 가져오기
with open('xor_model.pkl', 'rb') as f:
    model = pickle.load(f)

# 검사 문제
x_test = [ [1, 1], [0, 0], [0, 1], [1, 0] ]

# 모델 예측
y_predict = model.predict(x_test)
print('y_predict=>', y_predict)


import cv2
import numpy as np

def calculateArea(pathOfImage):
    originalImage = cv2.imread(pathOfImage)
    cv2.imshow('Original Image', originalImage)
    hsvImage = cv2.cvtColor(originalImage, cv2.COLOR_BGR2HSV)

    #Blue Color Segment
    blueLower = np.array([110, 50, 50])
    blueUpper = np.array([130, 255, 255])
    mask1 = cv2.inRange(hsvImage, blueLower, blueUpper)
    detected1 = cv2.bitwise_and(originalImage, originalImage, mask=mask1)
    cnts1, _ = cv2.findContours(mask1, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

    maxWidth1 = 0
    maxLength1 = 0
    for c in cnts1:
        x, y, w, h = cv2.boundingRect(c)
        maxWidth1 = max(maxWidth1, w)
        maxLength1 = max(maxLength1, h)
        cv2.drawContours(originalImage, [c], 0, (0, 255, 0), 2)
    print("Width of blue segment :", maxWidth1)
    print("Length of blue segment :", maxLength1)

    cv2.imshow('Blue Color Image', detected1)

    #Green Color Segment
    greenLower = np.array([50, 100, 100])
    greenUpper = np.array([70, 255, 255])
    mask2 = cv2.inRange(hsvImage, greenLower, greenUpper)
    detected2 = cv2.bitwise_and(originalImage, originalImage, mask=mask2)
    cnts2, _ = cv2.findContours(mask2, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

    maxWidth2 = 0
    maxLength2 = 0
    for c in cnts2:
        x, y, w, h = cv2.boundingRect(c)
        maxWidth2 = max(maxWidth2, w)
        maxLength2 = max(maxLength2, h)
        cv2.drawContours(originalImage, [c], 0, (0, 255, 0), 2)
    print("\nWidth of green segment :", maxWidth2)
    print("Length of green segment :", maxLength2)

    cv2.imshow('Green Color Image', detected2)

    #Yellow Color Segment
    yellowLower = np.array([20, 100, 100])
    yellowUpper = np.array([30, 255, 255])
    mask3 = cv2.inRange(hsvImage, yellowLower, yellowUpper)
    detected3 = cv2.bitwise_and(originalImage, originalImage, mask=mask3)
    cnts3, _ = cv2.findContours(mask3, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

    maxWidth3 = 0
    maxLength3 = 0
    for c in cnts3:
        x, y, w, h = cv2.boundingRect(c)
        maxWidth3 = max(maxWidth3, w)
        maxLength3 = max(maxLength3, h)
        cv2.drawContours(originalImage, [c], 0, (0, 255, 0), 2)
    print("\nWidth of yellow segment :", maxWidth3)
    print("Length of yellow segment :", maxLength3)

    cv2.imshow('Yellow Color Image', detected3)

    #Light Blue Color Segment
    lightBlueLower = np.array([90, 100, 100])
    lightBlueUpper = np.array([110, 255, 255])
    mask4 = cv2.inRange(hsvImage, lightBlueLower, lightBlueUpper)
    detected4 = cv2.bitwise_and(originalImage, originalImage, mask=mask4)
    cnts4, _ = cv2.findContours(mask4, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

    maxWidth4 = 0
    maxLength4 = 0
    for c in cnts4:
        x, y, w, h = cv2.boundingRect(c)
        maxWidth4 = max(maxWidth4, w)
        maxLength4 = max(maxLength4, h)
        cv2.drawContours(originalImage, [c], 0, (0, 255, 0), 2)
    print("\nWidth of light blue segment :", maxWidth4)
    print("Length of light blue segment :", maxLength4)

    cv2.imshow('Light Blue Color Image', detected4)

    #Brown Color Segment
    brownLower = np.array([10, 100, 100])
    brownUpper = np.array([20, 255, 255])
    mask5 = cv2.inRange(hsvImage, brownLower, brownUpper)
    detected5 = cv2.bitwise_and(originalImage, originalImage, mask=mask5)
    cnts5, _ = cv2.findContours(mask5, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

    maxWidth5 = 0
    maxLength5 = 0
    for c in cnts5:
        x, y, w, h = cv2.boundingRect(c)
        maxWidth5 = max(maxWidth5, w)
        maxLength5 = max(maxLength5, h)
        cv2.drawContours(originalImage, [c], 0, (0, 255, 0), 2)
    print("\nWidth of brown segment :", maxWidth5)
    print("Length of brown segment :", maxLength5)

    cv2.imshow('Brown Color Image', detected5)

    cv2.waitKey(0)
    cv2.destroyAllWindows()

#Main Function
pathOfImage = './data/finger-bones.jpg'
calculateArea(pathOfImage)


#"Hi He Lied Because Boron Could Not Oxidize Fluorine. New Nations Might Also Sign Peace Security Clause. Arthur King Can."
# という文を単語に分解し，1, 5, 6, 7, 8, 9, 15, 16, 19番目の単語は先頭の1文字，それ以外の単語は先頭に2文字を取り出し，
# 取り出した文字列から単語の位置（先頭から何番目の単語か）への連想配列（辞書型もしくはマップ型）を作成せよ．
import re
string = "Hi He Lied Because Boron Could Not Oxidize Fluorine. New Nations Might Also Sign Peace Security Clause. Arthur King Can."
one_letter = [1, 5, 6, 7, 8, 9, 15, 16, 19]
words = re.sub("[,.]", "", string).split(" ")

chemical_symbols = {}

for i, word in enumerate(words, 1):
    chemical_symbols[word[0] if i in one_letter else word[:2]] = i

print(chemical_symbols)


# 1. import libraries and modules
from config import *
from tkinter import *
from tkinter import messagebox
from tkinter.filedialog import asksaveasfile, askopenfile
from PIL import ImageTk, Image
import cv2
import numpy as np
import json
from a_star import astar

# 2. init main variables
# cells data structure: { key( (row_index, col_index) ): value( canvas_rect_id ) }
wallCells = {}
exitCells = {}
humanCells = {}

# flags
wallsHighlighted = False
gridDisplayed = False
wallsDisplayed = True
childIsOpen = False

# variables for selecting multiple cells
selectionRect = None
startX, startY = 0, 0
endX, endY = 0, 0
startCol, endCol = 0, 0
startRow, endRow = 0, 0
modelFilepath = None

# 3. init supporting functions
def refreshCells():
    global canvas, wallCells, humanCells, exitCells, wallsHighlighted, sbWidthVar, sbHeightVar

    cellWidth, cellHeight = sbWidthVar.get(), sbHeightVar.get()

    for pos in wallCells.keys():
        col, row = pos
        canvas.delete(wallCells[(col, row)])
        x, y = col * cellWidth, row * cellHeight
        fill = 'black' if wallsHighlighted and wallsDisplayed else ''
        outline = 'black' if wallsDisplayed else ''
        wallCells[(col, row)] = canvas.create_rectangle((x, y), (x + cellWidth, y + cellHeight),
                                                        outline=outline, fill=fill, tag='cell')

    for pos in exitCells.keys():
        col, row = pos
        tp = exitCells[pos][1]
        canvas.delete(exitCells[(col, row)][0])
        x, y = col * cellWidth, row * cellHeight
        exitCells[(col, row)] = (canvas.create_rectangle((x, y), (x + cellWidth, y + cellHeight),
                                                         outline='black', fill='lime', tag='cell'), tp)

    for pos in humanCells.keys():
        col, row = pos
        canvas.delete(humanCells[(col, row)])
        x, y = col * cellWidth, row * cellHeight
        humanCells[(col, row)] = canvas.create_rectangle((x, y), (x + cellWidth, y + cellHeight),
                                                         outline='black', fill='red', tag='cell')

def markingCell(col, row):
    global canvas, wallCells, exitCells, humanCells, sbWidthVar, sbHeightVar, rbVar

    cellWidth, cellHeight = sbWidthVar.get(), sbHeightVar.get()

    try:
        if rbVar.get() == 0:  # is wall
            canvas.delete(wallCells[(col, row)])
            del wallCells[(col, row)]
        elif rbVar.get() == 2:  # is exit
            canvas.delete(exitCells[(col, row)][0])
            del exitCells[(col, row)]
        elif rbVar.get() == 3:  # is human
            canvas.delete(humanCells[(col, row)])
            del humanCells[(col, row)]
    except KeyError:
        x, y = col * cellWidth, row * cellHeight
        if rbVar.get() == 0:  # is wall
            fill = 'black' if wallsHighlighted and wallsDisplayed else ''
            outline = 'black' if wallsDisplayed else ''
            wallCells[(col, row)] = canvas.create_rectangle((x, y), (x + cellWidth, y + cellHeight),
                                                            outline=outline, fill=fill, tag='cell')
        elif rbVar.get() == 2:  # is exit
            tpVar = []
            setThroughput(tpVar)
            tp = tpVar[0]
            if tp > 0:
                exitCells[(col, row)] = (canvas.create_rectangle((x, y), (x + cellWidth, y + cellHeight),
                                                                 outline='black', fill='lime', tag='cell'), tp)
        elif rbVar.get() == 3:  # is human
            humanCells[(col, row)] = canvas.create_rectangle((x, y), (x + cellWidth, y + cellHeight),
                                                             outline='black', fill='red', tag='cell')

def canvasRefresh():
    global arrayImage, panel, canvasImage, imagePosition
    imageTK = ImageTk.PhotoImage(Image.fromarray(obj=arrayImage, mode='RGBA'))  # convert numpy image to tkinter image
    canvas.delete(canvasImage)
    canvasImage = canvas.create_image(imagePosition, image=imageTK, anchor=NW)
    panel = Label(window, image=imageTK)
    panel.image = imageTK

def cellsFill():
    global wallsHighlighted
    wallsHighlighted = not wallsHighlighted
    refreshCells()

def displayGrid(isRefresh=None):
    global canvas, cursorCell, CANVAS_WIDTH, CANVAS_HEIGHT, gridDisplayed, sbWidthVar, sbHeightVar

    cellWidth, cellHeight = sbWidthVar.get(), sbHeightVar.get()

    if isRefresh:
        canvas.delete('grid_line')
        for i in range(0, CANVAS_WIDTH, cellWidth):
            canvas.create_line([(i, 0), (i, CANVAS_HEIGHT)], fill='gray', tag='grid_line')

        for i in range(0, CANVAS_HEIGHT, cellHeight):
            canvas.create_line([(0, i), (CANVAS_WIDTH, i)], fill='gray', tag='grid_line')
    else:
        if gridDisplayed:
            canvas.delete('grid_line')
            gridDisplayed = False
        else:
            for i in range(0, CANVAS_WIDTH, cellWidth):
                canvas.create_line([(i, 0), (i, CANVAS_HEIGHT)], fill='gray', tag='grid_line')

            for i in range(0, CANVAS_HEIGHT, cellHeight):
                canvas.create_line([(0, i), (CANVAS_WIDTH, i)], fill='gray', tag='grid_line')

            gridDisplayed = True

        canvas.delete((cursorCell))
        cursorCell = canvas.create_rectangle((0, 0), (cellWidth, cellWidth), outline='blue')
    refreshCells()

# 4. init basic UI event handlers
def mouseMove(event):
    global canvas, cursorCell, sbWidthVar, sbHeightVar

    cellWidth, cellHeight = sbWidthVar.get(), sbHeightVar.get()
    col, row = event.x // cellWidth, event.y // cellHeight
    x, y = col * cellWidth - 1, row * cellHeight - 1

    if rbVar.get() != 1:
        canvas.delete(cursorCell)
        cursorCell = canvas.create_rectangle((0, 0), (sbWidthVar.get(), sbHeightVar.get()), outline='blue')
        canvas.moveto(cursorCell, x, y)
    else:
        canvas.moveto(cursorCell, -cellWidth, -cellHeight)

def mousePress(event):
    global canvas, wallCells, wallsHighlighted, sbWidthVar, sbHeightVar, startX, startY, rbVar

    cellWidth, cellHeight = sbWidthVar.get(), sbHeightVar.get()
    startX, startY = event.x, event.y
    col, row = event.x // cellWidth, event.y // cellHeight

    canvas.delete('select_grid_line')
    if wallsDisplayed and rbVar.get() != 1:
        markingCell(col, row)

def mousePressMove(event):
    global canvas, selectionRect, startX, startY, endX, endY, sbWidthVar, sbHeightVar, imagePosition, arrayImage

    if rbVar.get() == 0:
        cellWidth, cellHeight = sbWidthVar.get(), sbHeightVar.get()
        endX, endY = event.x, event.y

        canvas.delete(selectionRect)
        selectionRect = canvas.create_rectangle((startX, startY), (endX, endY), outline='blue')

        try:
            col, row = startX // cellWidth, startY // cellHeight
            canvas.delete(wallCells[(col, row)])
            del wallCells[(col, row)]
        except KeyError:
            pass
    elif rbVar.get() == 1:
        h, w = arrayImage.shape[:2]
        imagePosition = event.x - w // 2, event.y - h // 2
        canvasRefresh()

def mouseUp(event):
    global canvas, CANVAS_WIDTH, CANVAS_HEIGHT, selectionRect, wallCells, startX, startY, endX, endY, \
        sbWidthVar, sbHeightVar, startCol, endCol, startRow, endRow

    if rbVar.get() == 0:
        cellWidth, cellHeight = sbWidthVar.get(), sbHeightVar.get()
        endX, endY = event.x, event.y

        canvas.delete(selectionRect)

        startCol = max(min(startX, endX), -cellWidth) // cellWidth + 1
        endCol = min(max(startX, endX), CANVAS_WIDTH) // cellWidth
        startRow = max(min(startY, endY), -cellHeight) // cellHeight + 1
        endRow = min(max(startY, endY), CANVAS_HEIGHT) // cellHeight

        if (endCol - startCol < 1) or (endRow - startRow < 1):
            return

        x1, x2 = startCol * cellWidth, endCol * cellWidth
        y1, y2 = startRow * cellHeight, endRow * cellHeight

        for i in range(x1, x2 + cellWidth, cellWidth):
            canvas.create_line([(i, y1), (i, y2)], fill='blue', tag='select_grid_line')

        for i in range(y1, y2 + cellHeight, cellHeight):
            canvas.create_line([(x1, i), (x2, i)], fill='blue', tag='select_grid_line')

def markingSelectionCells(event):
    global canvas, selectionRect, startRow, startCol, endRow, endCol

    if (endCol - startCol < 1) or (endRow - startRow < 1):
        return

    for row in range(startRow, endRow):
        for col in range(startCol, endCol):
            markingCell(col, row)

    startCol, endCol = 0, 0
    startRow, endRow = 0, 0

def resizeImage(event):
    global arrayImage, scaleValue, childIsOpen

    if childIsOpen:
        return

    scaleValue += event.delta // 120 * 0.01
    h, w = SOURCE_IMAGE.shape[:2]
    h, w = int(h * scaleValue), int(w * scaleValue)
    arrayImage = cv2.resize(SOURCE_IMAGE.copy(), (w, h))
    canvasRefresh()

def loadImage(event=None):
    global arrayImage, SOURCE_IMAGE, CANVAS_WIDTH, CANVAS_HEIGHT
    file = askopenfile(filetypes=(('PNG', '*png'), ('JPEG', '*jpeg *jpg'), ('All Files', '*.*')))
    image = np.asarray(Image.open(file.name))
    h, w = image.shape[:2]
    k = CANVAS_WIDTH / w if w > h else CANVAS_HEIGHT / h
    h, w = int(h * k), int(w * k)
    image = cv2.resize(image, (w, h))
    B, G, R = cv2.split(image)[:3]  # get color channels as lists
    alpha = 100  # transparency value
    A = np.ones(B.shape, dtype=B.dtype) * alpha  # image alpha-channel as list
    arrayImage = cv2.merge((R, G, B, A))  # merging channel lists into image
    SOURCE_IMAGE = arrayImage.copy()
    canvasRefresh()

def openFile(event=None):
    global imagePosition, arrayImage, scaleValue, SOURCE_IMAGE, canvasImage, wallCells, exitCells, humanCells, \
        sbWidthVar, sbHeightVar, modelFilepath

    if SOURCE_IMAGE is not None:
        ans = messagebox.askyesnocancel('Внимание', 'Сохранить открытый проект?')
        if ans is None:
            return
        else:
            if ans:
                save()
            else:
                pass

    file = askopenfile(filetypes=(('JSON Files', '*.json'), ('All Files', '*.*')))
    with open(file.name, 'r', encoding='utf-8') as j:
        data = json.loads(j.read())

    imageFilename = file.name.removesuffix('json') + 'png'
    SOURCE_IMAGE = np.asarray(Image.open(imageFilename, 'r'))
    if SOURCE_IMAGE is None:
        messagebox.showinfo('Ошибка', f'Изображение {imageFilename} не найдено')
        return

    canvas.delete(canvasImage)

    modelFilepath = file.name

    scaleValue = data['scale']
    imagePosition = data['image_position']['x'], data['image_position']['y']
    sbWidthVar.set(data['cell_size']['width'])
    sbHeightVar.set(data['cell_size']['height'])

    h, w = SOURCE_IMAGE.shape[:2]
    h, w = int(h * scaleValue), int(w * scaleValue)
    arrayImage = cv2.resize(SOURCE_IMAGE.copy(), (w, h))
    B, G, R = cv2.split(arrayImage)[:3]  # get color channels as lists
    alpha = 100  # transparency value
    A = np.ones(B.shape, dtype=B.dtype) * alpha  # image alpha-channel as list
    arrayImage = cv2.merge((R, G, B, A))  # merging channel lists into image
    SOURCE_IMAGE = arrayImage.copy()
    imageTK = ImageTk.PhotoImage(Image.fromarray(obj=arrayImage, mode='RGBA'))  # convert numpy image to tkinter image
    canvasImage = canvas.create_image(imagePosition, image=imageTK, anchor=NW)

    wallCells = {}
    exitCells = {}
    humanCells = {}
    canvas.delete('cell')

    for pos in data['walls']:
        col, row = pos['col'], pos['row']
        x, y = col * sbWidthVar.get(), row * sbHeightVar.get()
        fill = 'black' if wallsHighlighted and wallsDisplayed else ''
        outline = 'black' if wallsDisplayed else ''
        wallCells[(col, row)] = canvas.create_rectangle((x, y), (x + sbWidthVar.get(),
                                                                 y + sbHeightVar.get()),
                                                        outline=outline, fill=fill, tag='cell')
    for pos in data['exits']:
        col, row, tp = pos['col'], pos['row'], pos['throughput']
        x, y = col * sbWidthVar.get(), row * sbHeightVar.get()
        exitCells[(col, row)] = (canvas.create_rectangle((x, y), (x + sbWidthVar.get(),
                                                                  y + sbHeightVar.get()),
                                                         outline='black', fill='lime', tag='cell'), tp)

    canvasRefresh()
    refreshCells()

def save(event=None):
    global imagePosition, scaleValue, SOURCE_IMAGE, wallCells, exitCells, sbWidthVar, sbHeightVar

    data = {}
    data['image_position'] = {
        'x': imagePosition[0],
        'y': imagePosition[1]
    }
    data['scale'] = scaleValue
    data['cell_size'] = {
        'width': sbWidthVar.get(),
        'height': sbHeightVar.get()
    }

    data['walls'] = []
    for pos in wallCells.keys():
        col, row = pos
        data['walls'].append({
            'col': col,
            'row': row
        })
    data['exits'] = []
    for pos in exitCells.keys():
        col, row = pos
        tp = exitCells[pos][1]
        data['exits'].append({
            'col': col,
            'row': row,
            'throughput': tp
        })

    if SOURCE_IMAGE is None:
        messagebox.showinfo('Отмена', 'Сохранение невозможно. Отсутствует изображение проекта.')
        return

    if modelFilepath:
        with open(modelFilepath, 'w') as file:
            file.write(json.dumps(data, indent=4))
        imageFilename = file.name.removesuffix('json') + 'png'
        cv2.imwrite(imageFilename, SOURCE_IMAGE)
        messagebox.showinfo('Сохранение', f'Данные успешно сохранены в {modelFilepath}')
    else:
        file = asksaveasfile(initialfile='Untitled.json',
                             defaultextension='.json',
                             filetypes=(('All Files', '*.*'), ('JSON Files', '*.json')))

        imageFilename = file.name.removesuffix('json') + 'png'
        cv2.imwrite(imageFilename, SOURCE_IMAGE)
        file.write(json.dumps(data, indent=4))
        file.close()

def searchPaths():
    global canvas, wallCells, exitCells, humanCells, sbWidthVar, sbHeightVar
    cellSize = sbWidthVar.get(), sbHeightVar.get()

    exitTps = {pos: exitCells[pos][1] for pos in exitCells.keys()}
    if exitCells and humanCells:
        for human in humanCells.keys():
            variants = sorted([astar(wallCells, human, exit, cellSize) for exit in exitCells.keys()],
                              key=lambda item: item[2])
            path = []
            for v in variants:
                t, p, _ = v
                if exitTps[t] > 0:
                    path = p
                    exitTps[t] -= 1
                    break
                else:
                    continue

            # path = min([astar(wallCells, human, exit, cellSize) for exit in exitCells.keys()],
            #            key=lambda item: item[2])[1]

            for i in range(len(path) - 1):
                row1, col1 = path[i]
                row2, col2 = path[i + 1]
                x1, y1 = row1 * cellSize[0] + cellSize[0] // 2, col1 * cellSize[1] + cellSize[1] // 2
                x2, y2 = row2 * cellSize[0] + cellSize[0] // 2, col2 * cellSize[1] + cellSize[1] // 2
                canvas.create_line([(x1, y1), (x2, y2)], fill='darkgreen', width=2, tag='path')

def clearPaths():
    canvas.delete('path')
    canvasRefresh()

def openChildWindow():
    global window, rbVar, scaleValue, imagePosition, arrayImage, childIsOpen

    walls = set()
    childIsOpen = True

    rbVar.set(0)

    # set child window
    childWindow = Toplevel(window)
    childWindow.title('SEMI-AUTOMATIC BUILDING PLAN')
    childWindow.geometry(f'{WINDOW_WIDTH}x{WINDOW_HEIGHT}')
    childWindow.resizable(False, False)

    def update(a=None, b=None, c=None):
        global arrayImage, imagePosition

        if sbWidthVar2.get() < 2:
            sbWidthVar2.set(2)
        if sbWidthVar2.get() > 50:
            sbWidthVar2.set(50)

        if sbHeightVar2.get() < 2:
            sbHeightVar2.set(2)
        if sbHeightVar2.get() > 50:
            sbHeightVar2.set(50)

        offsetX, offsetY = abs(imagePosition[0]), abs(imagePosition[1])
        img = arrayImage[offsetY:offsetY + CANVAS_HEIGHT, offsetX:offsetX + CANVAS_WIDTH]
        img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
        _, thresh_img = cv2.threshold(img, scThreshVar2.get(), 255, cv2.THRESH_BINARY)

        childCanvas.delete('cell')

        walls.clear()
        stepX, stepY = sbWidthVar2.get(), sbHeightVar2.get()
        for x in range(0, CANVAS_WIDTH, stepX):
            for y in range(0, CANVAS_HEIGHT, stepY):
                cell = thresh_img[y:y + stepY, x:x + stepX]
                if len(cell[cell == 0]) / (stepX * stepY) > 0.5:
                    childCanvas.create_rectangle([(x, y), (x + stepX, y + stepY)], outline='black', tag='cell')
                    col, row = x // stepX, y // stepY
                    walls.add((col, row))

    # add canvas to child window
    childCanvas = Canvas(childWindow, width=CANVAS_WIDTH, height=CANVAS_HEIGHT, bg='white')
    childCanvas.place(x=CANVAS_OFFSET_X, y=CANVAS_OFFSET_Y)
    imageTK = ImageTk.PhotoImage(Image.fromarray(obj=arrayImage, mode='RGBA'))
    childCanvas.create_image(imagePosition, image=imageTK, anchor=NW)

    # add slider
    lbThresh2 = Label(childWindow, text='Пороговое значение')
    lbThresh2.place(x=818, y=230)
    scThreshVar2 = IntVar()
    scThreshVar2.set(50)
    scThresh2 = Scale(childWindow, from_=0, to=255, variable=scThreshVar2,
                      orient=HORIZONTAL, length=160, command=update)
    scThresh2.place(x=818, y=250)

    # add spinboxes
    lbSetCellWidth2 = Label(childWindow, text='Длина ячейки')
    lbSetCellWidth2.place(x=818, y=319)
    sbWidthVar2 = IntVar()
    sbWidthVar2.set(5)
    sbWidthVar2.trace('w', update)
    sbSetCellWidth2 = Spinbox(childWindow, from_=2, to=50, width=8, textvariable=sbWidthVar2, justify='center')
    sbSetCellWidth2.place(x=918, y=320)

    lbSetCellHeight2 = Label(childWindow, text='Высота ячейки')
    lbSetCellHeight2.place(x=818, y=349)
    sbHeightVar2 = IntVar()
    sbHeightVar2.set(5)
    sbHeightVar2.trace('w', update)
    sbSetCellHeight2 = Spinbox(childWindow, from_=2, to=50, width=8, textvariable=sbHeightVar2, justify='center')
    sbSetCellHeight2.place(x=918, y=350)

    # add buttons
    def apply():
        global sbWidthVar, sbHeightVar, wallCells

        sbWidthVar.set(sbWidthVar2.get())
        sbHeightVar.set(sbHeightVar2.get())

        wallCells = dict.fromkeys(walls, None)
        closingTop()
        refreshCells()

    def closingTop():
        global childIsOpen
        childIsOpen = False
        childWindow.destroy()

    btApply = Button(childWindow, text='Применить', command=lambda: apply(), width=20)
    btApply.place(x=830, y=511)

    btCancel = Button(childWindow, text='Отмена', command=lambda: closingTop(), width=20)
    btCancel.place(x=830, y=550)

    childWindow.protocol("WM_DELETE_WINDOW", closingTop)

    # first call
    update()

    childWindow.transient(window)
    childWindow.grab_set()
    childWindow.focus_set()
    childWindow.wait_window()

def setThroughput(tpVar: list):
    global window, childIsOpen

    childIsOpen = True

    # set child window
    childWindow = Toplevel(window)
    childWindow.title('INPUT THROUGHPUT')
    childWindow.geometry(f'300x150')
    childWindow.resizable(False, False)

    def update(a=None, b=None, c=None):
        if sbTPVar.get() < 1:
            sbTPVar.set(1)
        if sbTPVar.get() > 100:
            sbTPVar.set(100)

        if sbTPVar.get() < 1:
            sbTPVar.set(1)
        if sbTPVar.get() > 100:
            sbTPVar.set(100)

    # add spinbox
    lbSetTP = Label(childWindow, text='Введите пропускную способность:')
    lbSetTP.place(x=20, y=20)
    sbTPVar = IntVar()
    sbTPVar.set(1)
    sbTPVar.trace('w', update)
    sbSetTP = Spinbox(childWindow, from_=1, to=100, width=8, textvariable=sbTPVar, justify='center')
    sbSetTP.place(x=225, y=20)

    def apply():
        global childIsOpen
        tpVar.append(sbTPVar.get())
        childIsOpen = False
        childWindow.destroy()

    def closingTop():
        global childIsOpen
        tpVar.append(0)
        childIsOpen = False
        childWindow.destroy()

    btApply = Button(childWindow, text='Применить', command=lambda: apply(), width=20)
    btApply.place(x=80, y=65)

    btCancel = Button(childWindow, text='Отмена', command=lambda: closingTop(), width=20)
    btCancel.place(x=80, y=100)

    childWindow.protocol("WM_DELETE_WINDOW", closingTop)
    childWindow.transient(window)
    childWindow.grab_set()
    childWindow.focus_set()
    childWindow.wait_window()

# 5. init windows form elements and widgets
window = Tk()
window.title('BUILDING PLAN EDITOR')
window.geometry(f'{WINDOW_WIDTH}x{WINDOW_HEIGHT}')
window.resizable(False, False)

# add canvas
canvas = Canvas(window, width=CANVAS_WIDTH, height=CANVAS_HEIGHT, bg='white')
canvas.place(x=CANVAS_OFFSET_X, y=CANVAS_OFFSET_Y)
canvasImage = None
arrayImage: np.array = None
SOURCE_IMAGE: np.array = None
imagePosition = (0, 0)
panel = None
scaleValue: float = 1.00

# add checkboxes
cbShowGridVar = BooleanVar()
cbShowGridVar.set(gridDisplayed)
cbShowGrid = Checkbutton(window, text='Отображать сетку', variable=cbShowGridVar, command=displayGrid)
cbShowGrid.place(x=818, y=12)

cbShowWallsVar = BooleanVar()
cbShowWallsVar.set(wallsDisplayed)

def cbShowWallsCommand():
    global wallsDisplayed
    wallsDisplayed = not wallsDisplayed
    refreshCells()

cbShowWalls = Checkbutton(window, text='Отображать препятствия', variable=cbShowWallsVar, command=cbShowWallsCommand)
cbShowWalls.place(x=818, y=35)

cbFillWallsVar = BooleanVar()
cbFillWallsVar.set(wallsHighlighted)
cbFillWalls = Checkbutton(window, text='Закрашивать препятствия', variable=cbFillWallsVar, command=cellsFill)
cbFillWalls.place(x=818, y=58)

# add radiobuttons
rbVar = IntVar()
rbVar.set(0)

rbSetWalls = Radiobutton(window, text='Установить препятствия', value=0, variable=rbVar)
rbSetWalls.place(x=818, y=130)

rbSetImagePos = Radiobutton(window, text='Установить положение\nплана', value=1, variable=rbVar)
rbSetImagePos.place(x=818, y=170)

rbSetExits = Radiobutton(window, text='Установить\nэвакуационные выходы', value=2, variable=rbVar)
rbSetExits.place(x=818, y=210)

rbSetHumans = Radiobutton(window, text='Установить положение\nлюдей', value=3, variable=rbVar)
rbSetHumans.place(x=818, y=250)

# add spinboxes
def refreshCellSize(a=None, b=None, c=None):
    global sbWidthVar, sbHeightVar, sbSetCellHeight, sbSetCellWidth

    if sbWidthVar.get() < 2:
        sbWidthVar.set(2)
    if sbWidthVar.get() > 50:
        sbWidthVar.set(50)

    if sbHeightVar.get() < 2:
        sbHeightVar.set(2)
    if sbHeightVar.get() > 50:
        sbHeightVar.set(50)

    if cbShowGridVar.get():
        displayGrid(True)
    refreshCells()

lbSetCellWidth = Label(window, text='Длина ячейки')
lbSetCellWidth.place(x=818, y=319)
sbWidthVar = IntVar()
sbWidthVar.set(5)
sbWidthVar.trace('w', refreshCellSize)
sbSetCellWidth = Spinbox(window, from_=2, to=50, width=8, textvariable=sbWidthVar, justify='center')
sbSetCellWidth.place(x=918, y=320)

lbSetCellHeight = Label(window, text='Высота ячейки')
lbSetCellHeight.place(x=818, y=349)
sbHeightVar = IntVar()
sbHeightVar.set(5)
sbHeightVar.trace('w', refreshCellSize)
sbSetCellHeight = Spinbox(window, from_=2, to=50, width=8, textvariable=sbHeightVar, justify='center')
sbSetCellHeight.place(x=918, y=350)

# add buttons
btOpenWindow = Button(window, text='Авто-конструктор', command=lambda: openChildWindow(), width=20)
btOpenWindow.place(x=830, y=394)

btTest = Button(window, text='Найти пути', command=lambda: searchPaths(), width=20)
btTest.place(x=830, y=433)

btClear = Button(window, text='Очистить пути', command=lambda: clearPaths(), width=20)
btClear.place(x=830, y=472)

btLoad = Button(window, text='Загрузить изображение', command=lambda: loadImage(), width=20)
btLoad.place(x=830, y=511)

btOpen = Button(window, text='Открыть', command=lambda: openFile(), width=20)
btOpen.place(x=830, y=550)

btSave = Button(window, text='Сохранить', command=lambda: save(), width=20)
btSave.place(x=830, y=589)

# graphic moving cursor cell
cursorCell = canvas.create_rectangle((0, 0), (sbWidthVar.get(), sbHeightVar.get()), outline='blue')

# 6. binding UI event handlers
# - keyboard events
window.bind('<space>', markingSelectionCells)
window.bind('<Control-s>', save)
window.bind('<Control-o>', openFile)

# - mouse events
canvas.bind('<MouseWheel>', resizeImage)
canvas.bind('<Button-1>', mousePress)
canvas.bind('<Motion>', mouseMove)
canvas.bind('<B1-Motion>', mousePressMove)
canvas.bind('<ButtonRelease-1>', mouseUp)

# 7. starting system/program
window.mainloop()