import json
import os
import shutil

#This script deploys the project to screeps. Its not as quick as using link, but is a nice alternative if the project requires any extra build functionality

def deployDirectory(directory, project):
    if (not os.path.isdir(directory)):
        print("ERROR: " + directory + " not found")
        return

    rootDir = os.path.join(os.path.abspath(os.curdir), "code")
    deploymentDir = os.path.join(directory, project)

    #prep file
    if (os.path.isdir(deploymentDir)):
        print("Wiping " + deploymentDir + "...")
        shutil.rmtree(deploymentDir)

    #Deploy
    shutil.copytree(rootDir, deploymentDir)

def deployProject():
    with open('config.json') as file:
        data = json.load(file)

    name = data["projectName"]
    print("Building project '" + name + "'...")

    for directory in data["directories"]:
        deployDirectory(directory, name)

    print("project deployed")

#=========================#
#if __name__ == "__main__":
deployProject()
exit


from django.contrib import admin
from django.urls import path
from app import views
# STATIC AND MEDIA
from django.conf import settings
from django.conf.urls.static import static

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', views.HomePage.as_view(), name='home'),
    path('room/new/', views.AddRoom.as_view(), name="add_room"),
    path('room/modify/<int:id>', views.ModifyRoom.as_view(), name="modify_room"),
    path('add-reservation/', views.AddReservation.as_view(), name='add_reservation'),
    path('add-reservation/<int:id>', views.AddReservationById.as_view(),
         name='add_reservation_byid'),
    path('room-info/<int:id>', views.RoomInfo.as_view(), name="room_info"),
    path('test/', views.test),
]

urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)


from tinkoff.invest import Quotation
from datetime import timedelta
from dataclasses import asdict
from typing import Union
import math
import numpy as np

def qtof(q: Union[Quotation, dict]) -> float:
    if type(q) is dict:
        return float(q['units'] + q['nano'] * 10**-9)
    elif type(q) is Quotation:
        return float(q.units + q.nano * 10**-9)
    else:
        raise NotImplementedError

def ftoq(f: float) -> Quotation:
    return Quotation(*math.modf(f))

def ema(data, window):
    # numpy_ewma_vectorized_v2
    # thx to Divakar on stackoverflow
    alpha = 2 / (window + 1.)
    alpha_rev = 1 - alpha
    n = data.shape[0]

    pows = alpha_rev**(np.arange(n+1))

    scale_arr = 1 / pows[:-1]
    offset = data[0] * pows[1:]
    pw0 = alpha * alpha_rev**(n-1)

    mult = data * pw0 * scale_arr
    cumsums = mult.cumsum()
    out = offset + cumsums * scale_arr[::-1]
    return out

def ema_new_val(new_val, prev_ema, window):
    alpha = 2 / (window + 1.)
    alpha_rev = 1 - alpha
    return new_val * alpha + prev_ema * alpha_rev

def process_candle(candle):
    try:
        candle = asdict(candle)
        for attr in ['open', 'high', 'low', 'close']:
            candle[attr] = qtof(candle[attr])
        candle['time'] += timedelta(hours=3)  # converting to Moscow time
        return candle
    except Exception:
        return None


"""
Create all table that the project needs
"""
import os
from flask import Flask, render_template, request
from sqlalchemy import create_engine, text
from sqlalchemy.orm import scoped_session, sessionmaker
from env_init import database_flask_env_init

database_flask_env_init()

# Set up database
engine = create_engine(os.getenv("DATABASE_URL"))
db = scoped_session(sessionmaker(bind=engine))

def user_init():
    db.execute(text('drop table if exists users'))
    sql = text('''create table users(
            id serial primary key,
            username varchar not null unique,
            password varchar not null
        );''')
    db.execute(sql)
    db.commit()

def book_init():
    db.execute(text('drop table if exists books'))
    sql = text('''create table books(
            id serial primary key,
            isbn varchar not null unique,
            title varchar not null,
            author varchar not null,
            year varchar not null
        );''')
    db.execute(sql)
    db.commit()

def review_init():
    db.execute(text('drop table if exists reviews'))
    sql = text('''create table reviews(
            id serial primary key,
            username varchar references users(username) not null,
            isbn varchar references books(isbn) not null,
            comment varchar not null,
            star varchar not null
        );''')
    db.execute(sql)
    db.commit()

def main():
    review_init()

if __name__ == "__main__":
    main()


from django.db import models
from student.models import Student

class Applyleave(models.Model):
    id=models.AutoField(primary_key=True)
    studentId = models.ForeignKey(
        Student,
        on_delete=models.CASCADE,
    )
    startDate= models.DateField()
    endDate= models.DateField()
    status= models.BooleanField()


# -*- coding: utf-8 -*-
"""
Created on Mon Oct 24 22:37:16 2016

@author: Abdullah A. Alam
"""

# - ProblemSet4.py *- coding: utf-8 -*-
"""
Problem 4_1:
Write a program that will sort an alphabetic list (or list of words) into
alphabetical order. Make it sort independently of whether the letters are
capital or lowercase. First print out the wordlist, then sort and print out
the sorted list.
Here is my run on the list firstline below (note that the wrapping was added
when I pasted it into the file -- this is really two lines in the output).

problem4_1(firstline)
['Happy', 'families', 'are', 'all', 'alike;', 'every', 'unhappy', 'family',
 'is', 'unhappy', 'in', 'its', 'own', 'way.', 'Leo Tolstoy', 'Anna Karenina']
['alike;', 'all', 'Anna Karenina', 'are', 'every', 'families', 'family',
'Happy', 'in', 'is', 'its', 'Leo Tolstoy', 'own', 'unhappy', 'unhappy', 'way.']

"""
#%%
firstline = ["Happy", "families", "are", "all", "alike;", "every", \
              "unhappy", "family", "is", "unhappy", "in", "its", "own", \
              "way.", "Leo Tolstoy", "Anna Karenina"]
#%%
def problem4_1(wordlist):
    """ Takes a word list prints it, sorts it, and prints the sorted list """
    print(wordlist)
    wordlist.sort(key=str.lower)
    print(wordlist)

#%%
"""
Problem 4_2:
Write a function that will compute and print the mean and standard deviation
of a list of real numbers (like the following).  Of course, the length of the
list could be different. Don't forget to import any libraries that you might
need.
Here is my run on the list of 25 floats create below:

problem4_2(numList)
51.528
30.81215290541488

"""
#%%
import random
numList = []
random.seed(150)
for i in range(0,25):
    numList.append(round(100*random.random(),1))
#%%
def problem4_2(ran_list):
    """ Compute the mean and standard deviation of a list of floats """
    import statistics
    print(statistics.mean(ran_list))
    print(statistics.stdev(ran_list))

#%%
"""
Problem 4_3:
Write a function problem4_3(product, cost) so that you can enter the product
and its cost and it will print out nicely. Specifically, allow 25 characters
for the product name and left-justify it in that space; allow 6 characters for
the cost and right justify it in that space with 2 decimal places. Precede the
cost with a dollar-sign.  There should be no other spaces in the output.

Here is how one of my runs looks:
problem4_3("toothbrush",2.6)
toothbrush               $  2.60

"""
#%%
def problem4_3(product, cost):
    """ Prints the product name in a space of 25 characters, left-justified
        and the price in a space of 6 characters, right-justified"""
    print('{0:<25}'.format(product) + '$' +'{0:>6.2f}'.format(cost))

#%%
"""
Problem 4_4:
This problem is to build on phones.py.  You add a new menu item
  r) Reorder
This will reorder the names/numbers in the phone list. This may sound difficult
at first thought, but it really is straight forward.  You need to add two
lines to the main_loop, one line to menu_choice to print out the new menu
option (and add 'r' to the list of acceptable choices).  In addition you
need to add a new function to do the reordering: I called my reorder_phones().
Here is a start for this very short function:

def reorder_phones():
    global phones       # this insures that we use the one at the top
    pass # replace this pass (a do-nothing) statement with your code

Note: The auto-grader will run your program, choose menu items s, r, s, and q
in that order.  It will provide an unsorted CSV file and see if your program
reorders it appropriately. The grader will provided a version of myphones.csv
that has a different set of names in it from the ones we used in the lesson.
But the result of this added function is shown using the names used in class.

Before:
Choice: s
     Name                     Phone Number
  1  Jerry Seinfeld          (212) 842-2527
  2  George Costanza         (212) 452-8145
  3  Elaine Benes            (212) 452-8723
After:
Choice: s
     Name                     Phone Number
  1  Elaine Benes            (212) 452-8723
  2  George Costanza         (212) 452-8145
  3  Jerry Seinfeld          (212) 842-2527

"""


import json
import os

def name_to_var(lang_name):
    return (
        lang_name.upper()
        .replace(" ", "_")
        .replace("(", "")
        .replace(")", "")
        .replace("-", "_")
        .replace("'", "")
    )

def load_json(name):
    filepath = os.path.join(os.path.dirname(__file__), "langs_coverage", f"{name}.json")
    return json.loads(open(filepath).read())

auto_gen_comment = f"# Auto-generated. Do not modify, use {__file__} instead.\n"

name2json = {}

for name in ["m2m100", "mbart50", "nllb200"]:
    name2json[name] = lang2code = load_json(name)

    with open(f"./dl_translate/lang/{name}.py", "w") as f:
        f.write(auto_gen_comment)
        for lang, code in lang2code.items():
            f.write(f'{name_to_var(lang)} = "{lang}"\n')

with open("./dl_translate/_pairs.py", "w") as f:
    f.write(auto_gen_comment)

    for name, lang2code in name2json.items():
        f.write(f"_PAIRS_{name.upper()} = {tuple(lang2code.items())}\n")


import os
import gensim
import numpy as np
import pandas as pd
import keras

from keras.models import Model
from keras.layers import Input, Conv1D, Dense, Dropout, GlobalMaxPooling1D
from keras.layers.embeddings import Embedding
from keras.preprocessing import sequence, text
from keras.utils.np_utils import to_categorical
from sklearn.model_selection import train_test_split

import matplotlib.pyplot as plt

# GLOBAL PARAMETERS
NB_CATEGORIES = 52
EPOCHS = 10
PADDING = 150
PRE_TRAINED_DIM = 300

class CNN_model():
    def __init__(self, nbCategories=None, verbose=False, trainable = True):
        self.verbose = verbose

        self.nbCategories = nbCategories
        self.paddingLength = PADDING
        self.maxNumberWords = (1e4)
        self.trainable = trainable

        self.tokenizer = text.Tokenizer(num_words=self.maxNumberWords)

    def preprocess(self, x):
        # Inits tokenizer
        self.tokenizer.fit_on_texts(x)
        # Turns word sentences to word sequences
        sequences = self.tokenizer.texts_to_sequences(x)
        sequences = sequence.pad_sequences(sequences, self.paddingLength)
        return sequences

    def preprocessLabels(self, labels):
        return to_categorical(labels, num_classes=self.nbCategories)

    def buildModel(self, embedding):
        self.embedding = embedding
        drop_rate = 0.25
        nb_filters = 100
        filter_size = 3

        my_input = keras.Input(shape=(self.paddingLength,), name= 'input')

        embedding = (Embedding(input_dim = self.embedding.shape[0], output_dim = self.embedding.shape[1],
            weights = [self.embedding], input_length = self.paddingLength, trainable = self.trainable, name = 'embedding')) (my_input)

        embedding_dropped = Dropout(drop_rate, name = 'drop1')(embedding)
        conv = Conv1D(nb_filters, filter_size, activation= 'relu', name = 'conv1')(embedding_dropped)
        pooled_conv = GlobalMaxPooling1D(name = 'pool1')(conv)
        pooled_conv_dropped = Dropout(drop_rate, name = 'drop2')(pooled_conv)

        prob = Dense(self.nbCategories, activation= 'softmax', name = 'dense1') (pooled_conv_dropped)

        self.model = Model(my_input, prob)

        self.model.compile(
            loss='categorical_crossentropy',
            optimizer='adam',
            metrics=['accuracy'])

    def train(self, x, y, epochs=5, batch_size = 64, validation_data = None):
        self.model.fit(x, y, shuffle='batch', epochs=epochs, batch_size = batch_size, validation_data = validation_data)

    def evaluate(self, x, y):
        return self.model.evaluate(x, y)

    def predict(self, x):
        return self.model.predict(x)

if __name__ == '__main__':

    # LOAD DATA
    dataFolder = 'challenge_data'
    path2embedding = '../fr/'
    xPath = os.path.join(dataFolder, 'input_train.csv')
    yPath = os.path.join(dataFolder, 'challenge_output_data_training_file_predict_the_expected_answer.csv')
    model = CNN_model(nbCategories=NB_CATEGORIES)
    # Loading, parsing and spliting training and testing data
    x = pd.read_csv(xPath, delimiter=';', usecols=[1]).values.ravel()
    y = pd.read_csv(yPath, delimiter=';', usecols=[1]).values.ravel()
    y = model.preprocessLabels(y)

    # BUILD VOCABULARY
    # keras tokenizer gives all informations about our vocabulary
    model.preprocess(x)
    x_vocab  = list(model.tokenizer.word_index.keys())
    print('Size of the vocab', len(x_vocab))

    # Load Google's pre-trained french Word2Vec model (trained on wiki and of size 300).
    pre_trained_wv = gensim.models.Word2Vec.load(path2embedding + "fr.bin")
    # we use an embedding size of len(x_vocab) + 1 because the 0 is used for the padding
    embeddings = np.zeros((len(x_vocab) + 1 , PRE_TRAINED_DIM))
    not_in_pretrained = []
    for word, idx in model.tokenizer.word_index.items():
            if word not in pre_trained_wv.vocab:
                vec = np.zeros(PRE_TRAINED_DIM)
                not_in_pretrained.append(word)
            else:
                vec = pre_trained_wv[word]
            # word_to_index is 1-based! the 0-th row, used for padding, stays at zero
            embeddings[idx,] = vec
    print('----------embedding created----------')
    print('number of words in corpus that do not appear in pretrained word2vec: ', len(not_in_pretrained))

    # build the neural network of our model
    model.buildModel(embeddings)
    model.model.summary()

    print('total number of model parameters:',model.model.count_params())

    # process the data
    xTrain, xTest, yTrain, yTest = train_test_split(
        x, y, test_size=0.2, random_state=42)

    xTrain = model.preprocess(xTrain)
    xTest = model.preprocess(xTest)

    # Training model
    model.train(xTrain, yTrain, epochs=EPOCHS, validation_data = (xTest, yTest))

    # Testing model

    loss = model.evaluate(xTest, yTest)

    prediction = model.predict(xTest)
    predictionCategories = np.argmax(prediction, axis=1)
    yTestCategories = np.argmax(yTest, axis=1)
    accuracy = 100 * sum([predictionCategories[i] == yTestCategories[i] for i in range(len(yTestCategories))]) / len(yTestCategories)

    print('Accuracy: {:.2f} %\nLoss: {}'.format(accuracy, str(loss)))


from fastapi import FastAPI, HTTPException, status
from schema import Orders
from database import Base,engine, SessionLocal
import model

Base.metadata.create_all(engine)
db = SessionLocal()

app = FastAPI()
# OrderAPI

@app.get("/orders",response_model=list[Orders])     #To view all data from database to user
def get_all_orders():
    orders = db.query(model.Orders).all()

    return orders

@app.get("/order/{order_id}")       #To view a single record from database to user
def get_by_id(order_id:int):
    # filter is used for conditions
    order = db.query(model.Orders).filter(model.Orders.orderID==order_id).first()
    if order is None:       #if given order_id is not exist it will raise error else return order.
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND,detail="Resource Not Found")
    return order

@app.post("/order",                             # it will take data from user and store in database
          status_code=status.HTTP_201_CREATED)  # HTTP_201_CREATED to show that new recorded is stored
def create_order(order:Orders):                 # here we are accepting the complete data
    new_order = model.Orders(
        productName=order.productName,
        productPrice=order.productPrice,
        purchaseByName=order.purchaseByName,
        purchaseDate=order.purchaseDate
    )
    db.add(new_order)                           # add the data into table.
    db.commit()                                 #commit() is used to commit the current transaction
    return new_order
#delete a single order using order_id
@app.delete('/order/{order_id}')
def delete_item(order_id:int):
    order_to_delete=db.query(model.Orders).filter(model.Orders.orderID==order_id).first()

    if order_to_delete is None:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND,detail="Resource Not Found")

    db.delete(order_to_delete)
    db.commit()

    return order_to_delete


#!/usr/bin/env python3

from flask import Flask

app = Flask(__name__)

# Route for the home page
@app.route('/')
def index():
    return '
Python Operations with Flask Routing and Views
'

# Route for printing a string
@app.route('/print/<string:parameter>')
def print_string(parameter):
    print(parameter)
    return parameter

# use Route for counting numbers
@app.route('/count/<int:parameter>')
def count(parameter):
    numbers = '\n'.join(str(num) for num in range(parameter))
    return numbers

# This Route is used for performing math operations
@app.route('/math/<int:num1><operation><int:num2>')
def math(num1, operation, num2):
    result = None
    if operation == '+':
        result = num1 + num2
    elif operation == '-':
        result = num1 - num2
    elif operation == '*':
        result = num1 * num2
    elif operation == 'div':
        result = num1 / num2
    elif operation == '%':
        result = num1 % num2
    return str(result)

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


from django.contrib.auth import views
from django.urls import path
from .views import AdminApproveSellerView, UsersListAPIView, LoginView, RegisterUserAPIView, CurrentProfileAPIView, \
    ProfileAPIView, UserToBecomeSellerView

urlpatterns = [
    path('admin/notice/', AdminApproveSellerView.as_view(), name='admin-notice'),
    path('admin/accounts/list/', UsersListAPIView.as_view(), name='users-list'),

    path('login_token/', LoginView.as_view(), name='get-token'),
    path('register/', RegisterUserAPIView.as_view(), name='register'),
    # path('register/confirm/', ConfirmEmailAPIView.as_view(), name='register'),

    path('accounts/profile/', CurrentProfileAPIView.as_view(), name='current-profile'),
    path('accounts/profile/<int:id>/', ProfileAPIView.as_view(), name='profile-id'),

    path('seller/become/', UserToBecomeSellerView.as_view(), name='seller-become'),

]


from collections import deque

dx = [0, 1, 0, -1]
dy = [1, 0, -1, 0]

# 장마에 잠기는 영역
def rain(n):
    for i in range(N):
        for j in range(N):
            if board[i][j] <= n:
                save[i][j] = False

#안전구역 계산
def save_area(a, b):
    q = deque()
    q.append((a, b))
    while q:
        x, y = q.pop()
        for i in range(4):
            nx = x + dx[i]
            ny = y + dy[i]
            if 0 <= nx <= N - 1 and 0 <= ny <= N - 1:
                if save[nx][ny]:
                    save[nx][ny] = False
                    q.append((nx, ny))

N = int(input())
total_max = 0
board = []
#최대 구역
max_cnt = 0
# 영역 설정하면서 min값 ,max값 찾기
for _ in range(N):
    arr = list(map(int, input().split()))
    temp_max = max(arr)
    if total_max < temp_max:
        total_max = temp_max
    board.append(arr)

for i in range(total_max):
    temp_cnt = 0
    save = [[True] * N for _ in range(N)]
    # 장마로 인해 최소높이부터 물에 잠기기
    rain(i)
    #안전 구역 계산(잠긴 곳은 패스)
    for j in range(N):
        for k in range(N):
            if save[j][k]:
                save[j][k] = False
                save_area(j, k)
                temp_cnt += 1
    if max_cnt < temp_cnt:
        max_cnt = temp_cnt
if max_cnt == 0:
    max_cnt += 1
print(max_cnt)


import json
import os
from types import SimpleNamespace
from typing import Callable, Dict, TypeVar

import requests
from cachetools import cached, TTLCache
from requests.auth import HTTPBasicAuth

T = TypeVar("T")

class AZGewinkelClient:
    def __init__(self):
        key = os.environ.get("AZGEWINKEL_KEY")
        secret = os.environ.get("AZGEWINKEL_SECRET")
        self.__auth = HTTPBasicAuth(key, secret)
        self.root = "https://azgewinkel.ddns.net/wp-json/wc/v3"

    @cached(cache=TTLCache(maxsize=100, ttl=60))
    def get(self, path: str):

        response = requests.get(self.root + path, auth=self.__auth)
        if response.status_code != 200:
            raise IOError(response)
        text = response.text
        # pprint(json.loads(text))
        data = json.loads(text, object_hook=lambda d: SimpleNamespace(**d))
        if 'next' in response.links:
            next_path = response.links['next']['url']
            next_path = next_path.replace(self.root, "")
            next_data = self.get(next_path)
            data = data + next_data
        return data

    @cached(cache=TTLCache(maxsize=100, ttl=60))
    def load(self, path: str, mapper: Callable[[any], T]) -> Dict[int, T]:
        result = {}
        for item in self.get(path):
            result[item.id] = mapper(item)
        return result


"""Navigation menu for the netbox_facts plugin."""
from django.utils.translation import gettext_lazy as _
from extras.plugins import PluginMenuButton, PluginMenuItem, get_plugin_config
from extras.plugins.navigation import PluginMenu
from utilities.choices import ButtonColorChoices

macaddress_buttons = [
    PluginMenuButton(
        link="plugins:netbox_facts:macaddress_add",
        title="Add",
        icon_class="mdi mdi-plus-thick",
        color=ButtonColorChoices.GREEN,
    )
]
macvendor_buttons = [
    PluginMenuButton(
        link="plugins:netbox_facts:macvendor_add",
        title="Add",
        icon_class="mdi mdi-plus-thick",
        color=ButtonColorChoices.GREEN,
    )
]

menu_buttons = (
    PluginMenuItem(
        link="plugins:netbox_facts:macaddress_list", link_text=_("MAC Addresses"), buttons=macaddress_buttons
    ),
    PluginMenuItem(link="plugins:netbox_facts:macvendor_list", link_text=_("MAC Vendors"), buttons=macvendor_buttons),
)

if get_plugin_config("netbox_facts", "top_level_menu"):
    # add a top level entry
    menu = PluginMenu(
        label=_("Facts"),
        groups=(("Networking", menu_buttons),),
        icon_class="mdi mdi-checkbox-multiple-marked-outline",
    )
else:
    # display under plugins
    menu_items = menu_buttons


# Author = Valerii Vorobiov
# Date = 08 December, 2021
from functools import partial

def part_one(_input):
    four_digits = [line.split(' | ')[1].split(' ') for line in _input.split('\n')]
    length = {
        1: 2,
        7: 3,
        4: 4,
        8: 7
    }
    return sum(1 for digits in four_digits for d in digits if len(d) in length.values())

def part_two(_input):
    four_digits = [line.split(' | ')[1].split(' ') for line in _input.split('\n')]
    ten_digits = [line.split(' | ')[0].split(' ') for line in _input.split('\n')]
    sums = []
    for i, digits_set in enumerate(ten_digits):
        mapping = get_mapping(digits_set)
        digits = apply_mapping(four_digits[i], mapping)
        sums.append(list_to_number(digits))
    return sum(sums)

def apply_mapping(digits, mapping):
    return [sorted([mapping[d] for d in digit]) for digit in digits]

def list_to_number(lists):
    numbers = [[1, 2, 3, 5, 6, 7],
               [3, 6],
               [1, 3, 4, 5, 7],
               [1, 3, 4, 6, 7],
               [2, 3, 4, 6],
               [1, 2, 4, 6, 7],
               [1, 2, 4, 5, 6, 7],
               [1, 3, 6],
               [1, 2, 3, 4, 5, 6, 7],
               [1, 2, 3, 4, 6, 7]]
    return int(''.join(str(numbers.index(l)) for l in lists))

def len_based(digits, lenth):
    return list(set(i) for i in digits if len(i) == lenth)

one = partial(len_based, lenth=2)
seven = partial(len_based, lenth=3)
four = partial(len_based, lenth=4)

def get_mapping(ten_digits):
    d = dict()
    d[1] = seven(ten_digits)[0] - one(ten_digits)[0]
    d[7] = (len_based(ten_digits, 5)[0].intersection(*len_based(ten_digits, 5)[1:]) - d[1]) - four(ten_digits)[0]
    d[4] = (len_based(ten_digits, 5)[0].intersection(*len_based(ten_digits, 5)[1:]) - d[1]) - d[7]
    d[2] = four(ten_digits)[0] - d[4] - one(ten_digits)[0]
    five = [i for i in len_based(ten_digits, 5) if len(i) > len(i - d[2])][0]
    d[6] = five - d[1] - d[7] - d[2] - d[4]
    d[3] = one(ten_digits)[0] - d[6]
    d[5] = set('abcdefg') - set(''.join(i) for i in d.values())
    return {''.join(v): k for k, v in d.items()}

def read_input():
    with open((__file__.rstrip("main.py") + "input.txt"), 'r') as input_file:
        return input_file.read()

_input = read_input()

print("Part One : " + str(part_one(_input)))

print("Part Two : " + str(part_two(_input)))


from collections import deque

def bfs(start, visit, route):
    count = 0
    q = deque([[start, count]])  # [1,0]
    while q:
        value = q.popleft()
        v = value[0]  # 시작노드
        count = value[1]  # 1번노드부터 depth

        if visit[v] == -1:  # 방문하지 않았을 경우
            visit[v] = count
            count += 1
            for e in route[v]:
                q.append([e, count])

# n: node 수, edge: 양방향 간선

def solution(n, edge):
    answer = 0  # 가장 멀리있는 노드들의 갯수
    visit = [-1] * (n+1)  # 0~N번 노드까지 방문여부
    route = [[] for _ in range(n+1)]  # 각 노드에서 다른 노드까지 간선

    for e in edge:  # 양방향 그래프 생성
        route[e[0]].append(e[1])
        route[e[1]].append(e[0])

    bfs(1, visit, route)  # 1번 노드에서 시작
    for value in visit:
        if value == max(visit):
            answer += 1

    return answer
    # for _ in range(n):
    # return answer

def main():
    print(
        solution(6, [[3, 6], [4, 3], [3, 2], [1, 3], [1, 2], [2, 4], [5, 2]])
    )

main()


from typing import Any, Dict, Type, TypeVar

import attr

from ..models.subscr_channel_no_sound_option_type import SubscrChannelNoSoundOptionType
from ..models.subscr_channel_no_sound_option_value import SubscrChannelNoSoundOptionValue

T = TypeVar("T", bound="SubscrChannelNoSoundOption")

@attr.s(auto_attribs=True)
class SubscrChannelNoSoundOption:
    """
    Attributes:
        type (SubscrChannelNoSoundOptionType):
        value (SubscrChannelNoSoundOptionValue):
    """

    type: SubscrChannelNoSoundOptionType
    value: SubscrChannelNoSoundOptionValue

    def to_dict(self) -> Dict[str, Any]:
        type = self.type.value

        value = self.value.value

        field_dict: Dict[str, Any] = {}
        field_dict.update(
            {
                "type": type,
                "value": value,
            }
        )

        return field_dict

    @classmethod
    def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T:
        d = src_dict.copy()
        type = SubscrChannelNoSoundOptionType(d.pop("type"))

        value = SubscrChannelNoSoundOptionValue(d.pop("value"))

        subscr_channel_no_sound_option = cls(
            type=type,
            value=value,
        )

        return subscr_channel_no_sound_option


import streamlit as st
import requests
from PIL import Image
from transformers import BlipProcessor, BlipForConditionalGeneration
from sentence_transformers import SentenceTransformer
from sklearn.metrics.pairwise import cosine_similarity
import pandas as pd
import numpy as np

# Function to generate a caption
def generate_caption(image):
    processor = BlipProcessor.from_pretrained("Salesforce/blip-image-captioning-large")
    model = BlipForConditionalGeneration.from_pretrained("Salesforce/blip-image-captioning-large")
    inputs = processor(image, return_tensors="pt")
    out = model.generate(**inputs)
    return processor.decode(out[0], skip_special_tokens=True)

# Function to find the most similar emoji
def find_similar_emoji(caption, sentence_model, emoji_df):
    caption_embedding = sentence_model.encode([caption])[0]
    caption_embedding = np.array(caption_embedding).reshape(1, -1)

    emoji_embeddings = {row['emoji']: np.array(sentence_model.encode([row['name']])[0]).reshape(1, -1) for _, row in emoji_df.iterrows()}

    similarities = {emoji: cosine_similarity(caption_embedding, emoji_embedding)[0][0] for emoji, emoji_embedding in emoji_embeddings.items()}
    return max(similarities, key=similarities.get)

# Streamlit app
def main():
    st.title("Image to Emoji Converter")

    # User uploads an image
    uploaded_file = st.file_uploader("Choose an image...", type=["jpg", "png", "jpeg"])
    if uploaded_file is not None:
        # Display the image
        image = Image.open(uploaded_file)
        st.image(image, caption='Uploaded Image.', use_column_width=True)

        # Load the sentence transformer model
        sentence_model = SentenceTransformer('sentence-transformers/all-MiniLM-L6-v2')

        # Load emoji data
        emoji_df = pd.read_csv("./emoji_df.csv")  # Ensure the file is in the same directory as the app

        # Generate caption
        caption = generate_caption(image)
        st.write("Caption:", caption)

        # Find and display the most similar emoji
        emoji = find_similar_emoji(caption, sentence_model, emoji_df)
        st.write("Most similar emoji: ", emoji)

if __name__ == "__main__":
    main()


#!/usr/bin/env python3

#import sys
#from os import listdir, mkdir
from os.path import isfile, join, isdir
from collections import defaultdict
#import copy
#import spacy
#import scispacy
import sys, getopt

PROG_NAME = "add-term-from-umls.py"

# all columns values are zero-indexed

INPUT_COL_CONCEPT_ID = 0
UMLS_COL_CUI = 0
UMLS_COL_LANG = 1
UMLS_LANG_FILTER_VAL = [ "ENG" ]
UMLS_COL_PREFERED = 6
UMLS_COL_SOURCE = 11
UMLS_MESH_SOURCE_FILTER_VAL = "MSH"
UMLS_COL_MESH_ID = 10
UMLS_COL_TERM = 14

UMLS_STY_COL_CUI = 0
UMLS_STY_COL_TYPE_ID = 1
UMLS_STY_COL_TYPE_TREE_ID = 2
UMLS_STY_COL_TYPE_NAME = 3

SEMGROUPS_COL_COARSE_GROUP_ID = 0
SEMGROUPS_COL_FINE_GROUP_ID = 2

UMLS_SEP = '|'
UMLS_MAIN_FILE = "MRCONSO.RRF"
UMLS_GROUP_FILE = "MRSTY.RRF"

FILTER_LANG = False
ADD_GROUP_COL = False
PTC_INPUT = False
USE_MESH_IDS = False
REMOVE_MESH_PREFIX = False
USE_PTC_AS_GROUP_COL = False

INPUT_CONCEPT_FREQ_SEP=":"
SEPARATOR_CONCEPT_ID_TYPE = "@"
OUTPUT_GROUP_SEP=" "

def usage(out):
    print("Usage: ls <input files> | "+PROG_NAME+" [options] <UMLS dir> <output suffix> ",file=out)
    print("",file=out)
    print("  Reads a list of input tsv files with a concept id column (either a UMLS CUI id or a Mesh id)",file=out)
    print("  and maps the id to a term using the UMLS data. For each input file <f> an output file ",file=out)
    print("  <f><output suffix> is created with an additional term column. ",file=out)
    print("  <UMLS dir> is the UMLS metathesaurus data, it must contain RRF files: <UMLS dir>/META/*.RRF",file=out)
    print("  Notes:",file=out)
    print("    - If no term is found for a concept, the term column contains 'NA'.",file=out)
    print("    - In case -g/-G is used, the group column contains a list of groups separated by '"+OUTPUT_GROUP_SEP+"'",file=out)
    print("      The list can be empty, in which case the group column is empty.",file=out)
    print("",file=out)
    print("  Options:")
    print("    -h: print this help message.",file=out)
    print("    -i <id col>: concept id col; default: "+str(INPUT_COL_CONCEPT_ID+1)+".",file=out)
    print("    -m Mesh ids instead of default UMLS CUI ids (CUI is the default).",  file=out)
    print("    -M Mesh ids instead of default UMLS CUI ids + prefix 'MESH:' in the input files.",  file=out)
    print("    -p PTC input: the concept is represented as <id>@<category>, and a Mesh id has a ",file=out)
    print("       prefix 'MESH:'. Both the category and the prefix are removed. Implies '-M'.",file=out)
    print("    -g <UMLS sem groups file> add 'semantic group' column using UMLS group hierarchy which",file=out)
    print("       can be downloaded at https://lhncbc.nlm.nih.gov/semanticnetwork/download/SemGroups.txt",file=out)
    print("    -G add 'semantic group' column using PTC annotated type (requires PTC input; implies -p and -M)",file=out)
    print("    -l filter only English language terms. This can produce 'NA' terms if a concept does ",file=out)
    print("       not have any English term (this is rare but it happens). By default English is prefered")
    print("       but non-English is used if no English term is found.",file=out)
    print("",file=out)

# main

umlsGroupFile = None
try:
    opts, args = getopt.getopt(sys.argv[1:],"hi:mMpg:Gl")
except getopt.GetoptError:
    usage(sys.stderr)
    sys.exit(2)
for opt, arg in opts:
    if opt == "-h":
        usage(sys.stdout)
        sys.exit()
    elif opt == "-i":
        INPUT_COL_CONCEPT_ID = int(arg) -1
    elif opt == "-m":
        USE_MESH_IDS = True
    elif opt == "-M":
        USE_MESH_IDS = True
        REMOVE_MESH_PREFIX = True
    elif opt == '-p':
        PTC_INPUT = True
        USE_MESH_IDS = True
        REMOVE_MESH_PREFIX = True
    elif opt == '-g':
        ADD_GROUP_COL = True
        umlsGroupFile = arg
    elif opt == '-G':
        ADD_GROUP_COL = True
        PTC_INPUT = True
        USE_MESH_IDS = True
        REMOVE_MESH_PREFIX = True
        USE_PTC_AS_GROUP_COL = True
    elif opt == '-l':
        FILTER_LANG = True

#print("debug args after options: ",args)

if len(args) != 2:
    usage(sys.stderr)
    sys.exit(2)

umlsDir = args[0]
outputSuffix = args[1]

input_files = [ f.rstrip() for f in sys.stdin ]
for filename in input_files:
    if not isfile(filename):
        raise Exception("File '"+filename+"' read from STDIN does not exist.")

print("INFO: Reading UMLS concepts and terms...")
umls_mesh_to_cui = defaultdict(list)

#
# due to the possibility that a concept doesn't have an English term,
# there are two maps: one for English (index 1) one for non-English (index 0)
umls_cui_prefered_term = [ {}, {} ]

f= join(umlsDir, "META", UMLS_MAIN_FILE)
with open(f) as infile:
    for line in infile:
        cols = line.rstrip().split(UMLS_SEP)
        index_lang = 0
        if cols[UMLS_COL_LANG] in UMLS_LANG_FILTER_VAL:
            index_lang = 1
        if not FILTER_LANG or (index_lang == 1):                                     # filter language
            cui = cols[UMLS_COL_CUI]
            if cols[UMLS_COL_PREFERED] == 'Y' and umls_cui_prefered_term[index_lang].get(cui) is None:  # store only if prefered term, and only first found
                umls_cui_prefered_term[index_lang][cui] = cols[UMLS_COL_TERM]
            if USE_MESH_IDS and cols[UMLS_COL_SOURCE] == UMLS_MESH_SOURCE_FILTER_VAL:       # store all the CUIs corresponding to this Mesh
                umls_mesh_to_cui[cols[UMLS_COL_MESH_ID]].append(cui)
#                if cols[UMLS_COL_MESH_ID] == 'D000690':
#                    print("DEBUG: ",cols[UMLS_COL_MESH_ID],":",cui, " - term = ",cols[UMLS_COL_TERM])

umls_group_fine_to_coarse = {}
groups_by_cui = defaultdict(set)
if umlsGroupFile is not None:
    print("INFO: Reading UMLS groups...")
    with open(umlsGroupFile) as infile:
        for line in infile:
            cols = line.rstrip().split(UMLS_SEP)
            umls_group_fine_to_coarse[cols[SEMGROUPS_COL_FINE_GROUP_ID]] = cols[SEMGROUPS_COL_COARSE_GROUP_ID]
    f= join(umlsDir, "META", UMLS_GROUP_FILE)
    with open(f) as infile:
        for line in infile:
            cols = line.rstrip().split(UMLS_SEP)
            cui = cols[UMLS_STY_COL_CUI]
            fine_group = cols[UMLS_STY_COL_TYPE_ID]
            coarse_group = umls_group_fine_to_coarse[fine_group]
            if coarse_group is None:                # sanity check
                raise Exception("Error: cannot find coarse group corresponding to fine group '"+fine_group+"'")
            groups_by_cui[cui].add(coarse_group)

print("INFO: Processing input files...")
for input_file in input_files:
    with open(input_file+outputSuffix,"w") as outfile:
        with open(input_file) as infile:
            for line in infile:
                cols = line.rstrip().split('\t')
                concept_id = cols[INPUT_COL_CONCEPT_ID]
                cui_list = None
                if USE_MESH_IDS:
                    is_mesh = True
                    if REMOVE_MESH_PREFIX:
                        if concept_id[:5] == 'MESH:':
                            concept_id = concept_id[5:]
                        else:
                            is_mesh = False
                if PTC_INPUT:
                    sep_pos = concept_id.rfind(SEPARATOR_CONCEPT_ID_TYPE)
                    if sep_pos != -1:
                        ptc_category = concept_id[sep_pos+1:]
                        concept_id = concept_id[0:sep_pos]
                    else:
                        raise Exception("Bug! the concept id is supposed to contain '"+SEPARATOR_CONCEPT_ID_TYPE+"', this is not supposed to happen.",concept_id)
                cols[INPUT_COL_CONCEPT_ID] = concept_id
                if USE_MESH_IDS:
                    cui = None
                    if is_mesh:
                        cui_list = umls_mesh_to_cui[concept_id]
                        if len(cui_list)>0:
                            # just picking the first matched cui
                            cui = cui_list[0]
#                        else:
#                            print("Warning: no CUI found for MeSH descriptor "+concept_id)
                else:
                    cui = concept_id
                term = umls_cui_prefered_term[1].get(cui)
                if term is None:
                    # second attempt if no match found in English: non-English version
                    term = umls_cui_prefered_term[0].get(cui)
                    if term is None:
                        if not PTC_INPUT or is_mesh:
                            print("Warning: no term found for concept '"+concept_id+"'",file=sys.stderr)
                        term = "NA"
                cols.append(term)
                if ADD_GROUP_COL:
                    groups = []
                    if USE_MESH_IDS:
                        if USE_PTC_AS_GROUP_COL:
                            if ptc_category is not None:
                                groups = [ ptc_category ]
                        else:
                            if cui_list is not None and len(cui_list)>0:
                                groups_set = set()
                                for cui in cui_list:
                                    for g in groups_by_cui[cui]:
                                        groups_set.add(g)
                                groups = list(groups_set)
                    else:
                        groups = groups_by_cui[concept_id]
                    cols.append(OUTPUT_GROUP_SEP.join(groups))
                outfile.write("\t".join(cols)+"\n")


from gensim.models import FastText
import enchant
import nltk

model_fasttext = FastText.load('fasttext.model')

fasttext_min_similarity = 0.6
enchant_kr = enchant.Dict('ko_KR')

def include_spell_mistake(word, similar_word, score):
    edit_distance_threshold = 1 if len(word) <= 4 else 2
    score_1 = score > fasttext_min_similarity
    score_2 = len(similar_word) > 3
    score_3 = not enchant_kr.check(similar_word)
    score_4 = word[0] == similar_word[0]
    score_5 = nltk.edit_distance(word, similar_word) <= edit_distance_threshold
    score = score_1 + score_2 + score_3 + score_4 + score_5
    if score > 3:
        return True
    else:
        return False

def spell_check(word):
    w2m = []
    most_similar = model_fasttext.wv.most_similar(word, topn=50)
    for similar_word, score in most_similar:
        if include_spell_mistake(word, similar_word, score):
            w2m.append(similar_word)
    output = {'prediction' : w2m[:3]}
    return output

print(spell_check('스울'))


import requests
import time
from bs4 import BeautifulSoup
import json
import csv
import sqlite3

# GRAB LIST OF GROUP'S PUUIDs
# EVERY 30 MINUTES CHECK FOR EVERYONE

def get_all_puuids():
    # Connect to the SQLite database
    conn = sqlite3.connect('user_data.db')
    cursor = conn.cursor()

    # Retrieve the puuid of all users
    cursor.execute('''SELECT puuid FROM users''')
    puuids = cursor.fetchall()

    cursor.execute('''SELECT username FROM users''')
    usernames = cursor.fetchall()

    puuidsDictionary = {}
    for i in range(len(puuids)):
      puuidsDictionary[usernames[i][0]] = puuids[i][0]
    # Close the connection
    conn.close()

    return puuidsDictionary

#format: killer_name, killer_gun, killer_gun_media, victim_name, victim_gun, victim_gun, time_in_match, time_match_start
most_recent_eco = ('plumyum#BZB','spectre', 'https://media.valorant-api.com/weapons/462080d1-4035-2937-7c09-27aa2a5c27a7/displayicon.png','some shitter','classic', 'https://media.valorant-api.com/weapons/29a0cfab-485b-f5d5-779a-b59f85e204a8/displayicon.png', 0, 0)

#format: eco_checker[killer_gun][victim_gun]
# Load the JSON data from the file
with open('eco_checker.json', 'r') as file:
    eco_checker = json.load(file)

# Function that inserts new player into database
def insertPlayer(username, puuid, ecoKills=0, headshots=0, bodyshots=0, legshots=0, lastGame='0'):
  conn = sqlite3.connect('user_data.db')
  cursor = conn.cursor()

  cursor.execute('''
    INSERT INTO users (username, puuid, ecoKills, headshots, bodyshots, legshots, lastGame)
    VALUES (?, ?, ?, ?, ?, ?, ?)
  ''', (username, puuid, ecoKills, headshots, bodyshots, legshots, lastGame))

  # Commit the changes and close the connection
  conn.commit()
  conn.close()

  print("Data has been inserted into the 'users' table.")

# Function that allows SQL SELECT command to be use
def get_by_puuid(keyVal, puuid):
    # Connect to the SQLite database
    conn = sqlite3.connect('user_data.db')
    cursor = conn.cursor()

    # Execute a SELECT query with a WHERE clause to retrieve the keyVal value
    cursor.execute(f'SELECT {keyVal} FROM users WHERE puuid = ?', (puuid,))

    # Fetch the result

    returnVal = cursor.fetchone()

    # Close the connection
    conn.close()

    if returnVal:
        return returnVal[0]  # Extract the keyVal value from the result
    else:
        return None  # Player with the provided puuid not found

# Function that allows SQL UPDATE command to be use
def update_by_puuid(keyVal, new_keyVal_value, puuid):
    # Connect to the SQLite database
    conn = sqlite3.connect('user_data.db')
    cursor = conn.cursor()

    # Execute an UPDATE query with a WHERE clause to update the keyVal value
    cursor.execute(f'UPDATE users SET {keyVal} = ? WHERE puuid = ?', (new_keyVal_value, puuid))

    # Commit the changes and close the connection
    conn.commit()
    conn.close()

# Function that inserts game data into database
def insert_game_log(player_id, game_date, stats):
    # Connect to the SQLite database
    conn = sqlite3.connect('user_data.db')
    cursor = conn.cursor()

    # Insert a new game log
    cursor.execute('''
        INSERT INTO game_logs (player_id, game_date, stats)
        VALUES (?, ?, ?)
    ''', (player_id, game_date, stats))

    # Delete oldest game logs if there are more than 10 for this player
    cursor.execute('''
        DELETE FROM game_logs
        WHERE id NOT IN (
            SELECT id FROM game_logs WHERE player_id = ? ORDER BY game_date DESC LIMIT 10
        ) AND player_id = ?
    ''', (player_id, player_id))
    print("Game log updated!")

    # Commit the changes and close the connection
    conn.commit()
    conn.close()

# Function that gets the most recent game data of a player
def get_recent_game_stats(player_id, num_games=1):
    # Connect to the SQLite database
    conn = sqlite3.connect('user_data.db')
    cursor = conn.cursor()

    # Retrieve the stats column for the specified player's most recent games
    cursor.execute('''
        SELECT stats
        FROM game_logs
        WHERE player_id = ?
        ORDER BY game_date DESC
        LIMIT ?
    ''', (player_id, num_games))

    game_stats = cursor.fetchall()

    # Close the connection
    conn.close()
    json_player_stats_list = []
    for i in range(num_games):
      json_player_stats = game_stats[i][0].replace("'", "\"")
      json_player_stats = json.loads(json_player_stats)
      json_player_stats_list.append(json_player_stats)
    return json_player_stats_list

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

#finds data from API
def fetch_data_from_api(puuid):
    global most_recent_eco
    # Example API endpoint
    url = f"https://api.henrikdev.xyz/valorant/v3/by-puuid/matches/na/{puuid}?mode=competitive&size=1"
    response = requests.get(url)
    if response.status_code == 200:
      gameEcoCount = 0
      gameHeadshotsCount = 0
      gameBodyshotsCount = 0
      gameLegshotsCount = 0
      soup = BeautifulSoup(response.text, 'html.parser')
      site_json = json.loads(soup.text)

      if site_json["data"][0]["metadata"]["matchid"] != get_by_puuid("lastGame", puuid):
        player_stats = site_json["data"][0]["rounds"][0]["player_stats"]
        update_by_puuid("lastGame", site_json["data"][0]["metadata"]["matchid"], puuid)

        #grabs index of all the players making later processes faster
        playersIndices = {}
        for pos in range(0, 10):
          playersIndices[player_stats[pos]["player_puuid"]] = pos
          if player_stats[pos]["player_puuid"] == puuid:
            playerPos = pos
            playerName = player_stats[pos]['player_display_name']

        # iterates through rounds
        for roundNum in range(0, len(site_json["data"][0]["rounds"])):
          #adds headshots/bodyshots/legshots to user_data.db via users puuid
          headshots = int(site_json["data"][0]["rounds"][roundNum]["player_stats"][playerPos]["headshots"])

          gameHeadshotsCount += headshots
          bodyshots = int(site_json["data"][0]["rounds"][roundNum]["player_stats"][playerPos]["bodyshots"])

          gameBodyshotsCount += bodyshots
          legshots = int(site_json["data"][0]["rounds"][roundNum]["player_stats"][playerPos]["legshots"])

          gameLegshotsCount += legshots
          try:
            update_by_puuid("headshots", get_by_puuid("headshots", puuid)+headshots, puuid)
            update_by_puuid("bodyshots", get_by_puuid("bodyshots", puuid)+bodyshots, puuid)
            update_by_puuid("legshots", get_by_puuid("legshots", puuid)+legshots, puuid)
          except:
            True
          #checks if player gets a kill that round
          kill_events = site_json["data"][0]["rounds"][roundNum]["player_stats"][playerPos]["kill_events"]
          if (kill_events != False):
            killer_gun = site_json["data"][0]["rounds"][roundNum]["player_stats"][playersIndices[puuid]]["economy"]["weapon"]
            #iterates through all the kills the player gets that round
            for kill in kill_events:
              #gets victim's puuid then grabs their loadout_value
              victim_puuid = kill['victim_puuid']
              victim_gun = site_json["data"][0]["rounds"][roundNum]["player_stats"][playersIndices[victim_puuid]]["economy"]["weapon"]

              #adds an ecoKill to user_data.db via users puuid
              try:
                eco_checker[killer_gun["name"]][victim_gun["name"]]
                gameEcoCount += 1
                update_by_puuid("ecoKills", get_by_puuid("ecoKills", puuid)+1, puuid)
                if kill["kill_time_in_match"] > most_recent_eco[6] and site_json["data"][0]["metadata"]["game_start"] >= most_recent_eco[7]:
                  most_recent_eco = (kill["killer_display_name"], kill["damage_weapon_name"], kill["damage_weapon_assets"]["display_icon"], kill["victim_display_name"], victim_gun["name"], victim_gun["assets"]["display_icon"], kill["kill_time_in_match"], site_json["data"][0]["metadata"]["game_start"])

              except:
                True

        total_game_stats_dict ={"ecoKills":gameEcoCount, "headshots":gameHeadshotsCount, "bodyshots":gameBodyshotsCount, "legshots":gameLegshotsCount}
        total_game_stats = str({"ecoKills":gameEcoCount, "headshots":gameHeadshotsCount, "bodyshots":gameBodyshotsCount, "legshots":gameLegshotsCount})
        return total_game_stats_dict

        # CHECK IF USER IS IN DATA BASE ---------------------------------
        # IF NOT ADD THEM
        if get_by_puuid('id', puuid) is None:
          return [{"name": playerName[:playerName.index('#')], "puuid":puuid, "ecoKills":gameEcoCount, "headshots": gameHeadshotsCount, "bodyshots":gameBodyshotsCount, "legshots":gameLegshotsCount}]
        else:
          insert_game_log(get_by_puuid('id',puuid), site_json["data"][0]["metadata"]["game_start"], total_game_stats)

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

    else:
      #if api is down then gives us the code; a slightly better try except statement
      print(f"Error Status code: {response.status_code}")

def get_puuid(name, tag):
  url = f"https://api.henrikdev.xyz/valorant/v1/account/{name}/{tag}"
  response = requests.get(url)
  if response.status_code == 200:
    soup = BeautifulSoup(response.text, 'html.parser')
    site_json = json.loads(soup.text)
    return site_json["data"]["puuid"]
  else:
    print(f"Error Status code: {response.status_code}")

#prints the entire database
"""
# Connect to the SQLite database
conn = sqlite3.connect('user_data.db')
cursor = conn.cursor()

# Execute a SELECT query to retrieve all data from the 'users' table
cursor.execute('SELECT * FROM users')

# Fetch all rows from the result set
rows = cursor.fetchall()

# Print the retrieved data
for row in rows:
    print("ID:", row[0])
    print("Username:", row[1])
    print("PUUID:", row[2])
    print("Eco Kills:", row[3])
    print("Headshots:", row[4])
    print("Bodyshots:", row[5])
    print("Legshots:", row[6])
    print("Latest Match Id:", row[7])
    print("--------------------")

# Close the connection
conn.close()
"""

puuids = get_all_puuids()
#for username in puuids:
  #fetch_data_from_api(puuids[username])
  #print(f'User {username} has been update')
#INFINITY LOOP ONCE WE DONZO YAYAYAYAYA
#while True:
    #for username in puuids:
      #fetch_data_from_api(puuids[username])
      #print(f'User {username} has been update')
    #time.sleep(1800)  # 30 minutes in seconds

#grabs stats from last game in players logs
for i in range(1,14):
  player_stats = get_recent_game_stats(i,2)
  #json_player_stats = player_stats[0][0].replace("'", "\"")
  #json_player_stats = json.loads(json_player_stats)
  print(f"{i}:{player_stats[0]['ecoKills']}")


from django.shortcuts import render, redirect
from django.views.generic import TemplateView, ListView, CreateView
from django.core.files.storage import FileSystemStorage
from django.urls import reverse_lazy

from .forms import StForm
from .models import Storage

class Home(TemplateView):
    template_name = 'storage/home.html'

def upload(request):
    context = {}
    if request.method == 'POST':
        uploaded_file = request.FILES['document']
        fs = FileSystemStorage()
        name = fs.save(uploaded_file.name, uploaded_file)
        context['url'] = fs.url(name)
    return render(request, 'storage/upload.html', context)

def st_list(request):
    files = Storage.objects.all()
    return render(request, 'storage/st_list.html', {
        'files': files
    })

def upload_file(request):
    if request.method == 'POST':
        form = StForm(request.POST, request.FILES)
        if form.is_valid():
            form.save()
            return redirect('st_list')
    else:
        form = StForm()
    return render(request, 'storage/upload_file.html', {
        'form': form
    })

def delete_file(request, pk):
    if request.method == 'POST':
        file = Storage.objects.get(pk=pk)
        file.delete()
    return redirect('st_list')

# class BookListView(ListView):
#     model = Book
#     template_name = 'storage/class_book_list.html'
#     context_object_name = 'books'
#
#
# class UploadBookView(CreateView):
#     model = Book
#     form_class = BookForm
#     success_url = reverse_lazy('class_book_list')
#     template_name = 'storage/upload_file.html'


### Goal: Read in an Image an autoamtically detect the Scale used:
## Caveats: Maybe we will need manual input of scale,
##Do we perform this per Image or once provided the person doesn't change the zoom

####
#### Read in all Images and save their respective paths and filenames
def Images_list(path_to_images):
  import os as os
  PureNames = []
  Image_names = []
  for root, dirs, files in os.walk(path_to_images, topdown=False):
    #print(dirs, files)
    for name in files:
      #print(os.path.join(root, name))
      Image_names.append(os.path.join(root, name))
  for x in range(0,len(Image_names)):
    PureNames.append(Image_names[x].split("/")[-1])
  return Image_names, PureNames

def getLineLength(Image_names):
  ## Gaussiaun blur and image read ##
  # Detects lines used for scale, always
  # counts the saves the shortest scale
  # in image
  # Input: image names in folder
  # Output: line coordinates and length
  ###################################

  import cv2 as cv2
  import numpy as np
  from PIL import Image
  import matplotlib.pyplot as plt

  list_of_lengths = []
  list_of_images = []
  line_Coors = []
  list_of_lines = []
  for x in range(len(Image_names)):
      img = cv2.imread(Image_names[x])

      gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
      #thresh, gray_thresh = cv2.threshold(gray, 100, 255, cv2.THRESH_BINARY_INV)
      #thresh = cv2.threshold()

      ## why should we blur? Image lines should be sharp -> thresholding should be the most effective
      ## In thresholding we need to consider colors but should be managable if we make an OTSU and
      ## hard cut off for white backgrounds with white scales
      kernel_size = (5,1) # We do not wnt to blur the x axis as we need the length information
      blur_gray = cv2.GaussianBlur(gray,(kernel_size),0)

      low_threshold = 200
      high_threshold = 300
      edges = cv2.Canny(blur_gray, low_threshold, high_threshold)

      #### Set HoughLinesP Parameters

      rho = 1 # distance resolution in pixels of the Hough grid
      theta = np.pi / 180  # angular resolution in radians of the Hough grid
      threshold = 10  # minimum number of votes (intersections in Hough grid cell)
      min_line_length = 100 # minimum number of pixels making up a line
      max_line_gap = 0  # maximum gap in pixels between connectable line segments
      line_image = np.copy(img) * 0  # creating a blank to draw lines on
      # Run Hough on edge detected image
      # Output "lines" is an array containing endpoints of detected line segments

      lines = cv2.HoughLinesP(edges, rho, theta, threshold, np.array([]),min_line_length, max_line_gap)

      if lines is None: ## If no lines are found
        list_of_lengths.append(0)
        line_Coors.append(0)
      else: # if there are lines
        print(lines)
        for line in lines:
          x1, y1, x2, y2 = line[0]
          cv2.line(line_image, (x1, y1), (x2, y2), (255, 0, 0), 1)

        combined, Coordinates = group_lines(lines) ## combine close lines

        plt.clf()
        plt.imshow(line_image, cmap = "gray")
        plt.show()

        # Find the index of the min value so we can sort the line coordinates
        Idx = combined.index(min(combined))
        Correct_Coor = Coordinates[0][Idx] ## Get the coordinates of the shortest line
        PixelPerUnit = min(combined) ## take the min value of length as scale

        # Append values to lists
        line_Coors.append(Correct_Coor)
        list_of_lengths.append(PixelPerUnit)
        list_of_images.append(line_image)
        list_of_lines.append(lines)
  return list_of_lengths, line_Coors, list_of_images, list_of_lines ## Works right now with 5% Error reimplement giving coordinates

def group_lines(lines):
    # Combines lines and outputs the new coordiantes
    # Lines are grouped by y and then added to each other
    # with a new mean y
    # Input: Line coordinates [[[...],[...],...]]
    # Output: Line coordinates of combined lines [[[...],[...],...]]
    # Length of the combined lines
    import numpy as np

    groups = []

    # Convert lines to a list if it is a NumPy array
    if isinstance(lines, np.ndarray):
        lines = lines.tolist()
        lines_flat = [line[0] for line in lines]

    # Sort lines based on y-coordinate
    lines_flat.sort(key=lambda line: line[1])

    current_group = [lines_flat[0]]

    ### group them according if their difference is smaller than 5 pixels
    for line in lines_flat[1:]:

        if line[1] - current_group[-1][3] <= 3:
            current_group.append(line)

        else:
            groups.append(current_group)
            current_group = [line]

    groups.append(current_group)
    ### We also want to build the lines and output them too

    fused_lines = [] ## This is gonna be the list containing the lists of lines
    temp_lines = [] # These are the lines per image
    extracted_length = [] # This gonna be the list containing the lists of lenghts

    for group in groups:

        xmin = min(line[0] for line in group)
        xmax = max(line[2] for line in group)
        ymean = int(sum(line[1] for line in group)/len(group))
        extracted_length.append(abs(xmax - xmin)) # Calculate length
        temp_lines.append([xmin, ymean, xmax, ymean]) ## Coordinates of our line

    fused_lines.append(temp_lines)

    return extracted_length, fused_lines

def CutAndColour(Line_coordinates, Image_names):
  # Input: Coordinates of the shortest line (calcualted in getLineLength)
  # Output: Two lists, one containing all colour data in format white (0/1)
  # and a list of the scale cut out based on coordinates
  import cv2 as cv2
  import numpy as np
  import matplotlib.pyplot as plt

  list_of_crops = []
  for x in range(len(Image_names)):
      img = cv2.imread(Image_names[x])

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

      TempCoor = Line_coordinates[x] # Assign the Coordinates to a value

      if TempCoor == 0:
        list_of_crops.append(img_gray)

      else:
        ## Cut the image we give 5% in x coordinate as buffer to detect the number

        height, width = img_gray.shape
        buffer = int(width*0.05)

        ## Check if the y value still lies within the range of the image
        if int(TempCoor[1] - buffer) > 0 and int(TempCoor[1] + buffer) < height:

          cropped_img = img_gray[TempCoor[1]-buffer:TempCoor[1]+buffer,TempCoor[0]:TempCoor[2]]

        else: ## If the image is not big enough/the scale too low we pad the size of the buffer
              ## In the unlikely case we also add it on the upper part
          padded_img = np.pad(img_gray, ((buffer, buffer), (0, 0)), mode='constant', constant_values= int(np.average(img_gray)))
          cropped_img = padded_img[TempCoor[1]:TempCoor[1] + 2*buffer,TempCoor[0]:TempCoor[2]]

        # Recalculate the position of the scale which is at position buffer as buffer*2 is the new height
        ## Now we want the colour of the line
        ## So we make the image gray and extract the pixel values of of it

        # How about resizing the image. Thos would allow cv2.Canny
        # on small pixel numbers?
        # Now that we do not need exact values for the scale anymore we can process the image
        #Empty = np.zeros(cropped_img)
        img_normalized = cv2.normalize(cropped_img, None, 0, 255, cv2.NORM_MINMAX)
        blurred = cv2.GaussianBlur(img_normalized, (3,3), sigmaX=0, sigmaY=0) ## Blur important
        # Scale and number should normally be the same colour so Scale_colour = Value_colour

        Can = cv2.Canny(blurred,350,400, L2gradient = True)
        #test = np.invert(Can)

        # Find contours and hierarchy
        contours, hierarchy = cv2.findContours(Can, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)

        # Create an empty canvas with the same shape as Can
        WhiteCanvas = np.ones_like(Can) * 255

        # Find the outer contours by checking the hierarchy
        outer_contours = []
        for i in range(len(contours)):
            if hierarchy[0][i][3] != -1:  # Contour has a parent (no enclosed regions)
                outer_contours.append(contours[i])

        # Fill the outer contours on the canvas
        Filled = cv2.drawContours(WhiteCanvas, outer_contours, contourIdx=-1, color=(0), thickness=cv2.FILLED)
        ### As spaces in letters are filled in we now want the recreate these spaces
        #contours_fill, hierarchy = cv2.findContours(Can, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)

        plt.clf()
        plt.imshow(Can, cmap = "gray")
        plt.show()

        list_of_crops.append(Filled)

  return(list_of_crops)

def NormalizeDPI(images, image_names):
  # Resize Cutouts of the scale and enforce an uniform DPI scale ##
  # This helps tesseract ocr-to detect scales more confidently  ###
  # according to documentation
  # Input: Folder_path
  # Output: Saved Scale Images 512x512, 600 DPI at the folder path called
  # Converted Scales as Image_name_ConvScale.jpg

  import os
  from PIL import Image
  import re
  import matplotlib.pyplot as plt

  list_of_standardized_images = []
  directory = "Converted_Scales"
  save_path =  os.path.dirname(image_names[0])
  convert_path = os.path.join(save_path,directory)

  if os.path.exists(convert_path) == False:
    os.mkdir(convert_path)
  i = 1

  for image in range(len(images)):

    result = str(image_names[image]).split('/')[-1]

    try:
        new_file = convert_path + "/" + result[:-4] + "_ConvScale.jpg"

        i = i+1
        im = Image.fromarray(images[image])
        im.thumbnail((512,512))
        im.save(new_file,"JPEG",dpi=(600,600))
        list_of_standardized_images.append(new_file)
    except:
        continue
  return(list_of_standardized_images)

#### No we need to get the Number above the line
# def getUnit(cropped_Image) ### For py Tesseract we need sudo install
### white only needs mask
### We need to check if the scale is white
### Therefore we check if we have more 0 pixels in the mask than 255

def get_Scale(path_to_preprocessed_images, psm_mode=7):
  import pytesseract as pytesseract
  import matplotlib.pyplot as plt
  import cv2 as cv2

  ScaleUnit = []
  pytesseract.pytesseract.tesseract_cmd = r'/usr/bin/tesseract'
  for x in range(len(path_to_preprocessed_images)):

    img = cv2.imread(path_to_preprocessed_images[x])
    #try:
      #gaussian_3 = cv2.GaussianBlur(crop_img, (0, 0), 2.0)
      #unsharp_image = cv2.addWeighted(crop_img, 2.0, gaussian_3, -1.0, 0)
    #except:
      #gaussian_3 = crop_img

    ## tesseract detect

    tesseract_config = r'--oem 3 --psm ' + str(psm_mode) +" -c tessedit_char_whitelist=0123456789."

    ## as we dont no which kind of scale was put in we use all 3 (inverse, contrast for white and MasCorrNormBare) and then compare.
    ## We could find out the colour of the scale when we use the lines, but is it necessary?

    number = pytesseract.image_to_string(img, config= tesseract_config).strip()
    ScaleUnit.append(number)
  return(ScaleUnit)

########### We also should detect mm or µm this can be achieved with pytesseract. but we also can guess as
########### high values should always be µm and low ones mm ## psm 7 is good by far not perfect... Run multiple modes?

def makeDfwithfactors(list_of_names, One_scale,ScaleUnitClean=[], list_of_lengths=[], ConvFactor=0.002139):
  ### This function has two modes. 1) If the user declares taht we only have one
  ### scale we take the most common values of length and unit and 2) if more
  ### than one exist we keep the list as they are.
  ### Then we enter the singular or mutliple values into the df
  import pandas as pd
  LengthOpt = [int(item) for item in list_of_lengths] ## Make linelengths int
  if One_scale == 0:
    Scale_df = pd.DataFrame(list_of_names, columns =['Name'])
    Scale_df["distance_per_pixel"] = ConvFactor
    print(f"Using manual factor of {ConvFactor} px/mm")
    return Scale_df

  elif One_scale > 0:

    if One_scale == 1:
      LengthOpt = max(set(list_of_lengths), key = list_of_lengths.count)
      UnitOpt = max(set(ScaleUnitClean),key = ScaleUnitClean.count)

    else:
	    LengthOpt = list_of_lengths
	    UnitOpt = ScaleUnitClean

    Scale_df = pd.DataFrame(list_of_names, columns =['Name'])
    #print(list_of_lengths)
    Scale_df["metric_length"] = UnitOpt
    Scale_df["scale[px]"] = LengthOpt
    Scale_df["distance_per_pixel"] = Scale_df["metric_length"]/Scale_df["scale[px]"]

    return Scale_df

##### Testing space for image prep
##225 or 468
#### Make Lines to Int ### Do we make a config for all Codes?
### 0 = no scale native resolution of 2.8 px/µm with standard zoom (If you know the configuration of
### your own microscope enter it into the config.cfg)
### 1 = one scale for all images (automatically detects scale and Unit for every
### image but takes the most common value for all images -> robust)
### 2 = Multiple scales: tries to find a scale for every image. May be prone to
### error
### The new approach is split differently to increase the accuracy
# 1. Make image gray
# 2. Detect the line, find color and length of it
# 3. Cut out sourrinding area
# 3a. Optionally delete only the line
# 4. Normalize DPI
# 5. Binarise, Invert and Threshold the image based
# 6. Detect with Tesseract
# 7. Save in Df/Aig Cellulose 5000 84.jpg

a,b = Images_list("/home/philipp/JPG/")

c,d,q,z = getLineLength(a)
l= CutAndColour(d,a) ### Here we need another approach if we want to use new scales IDK iterate over 5
k = NormalizeDPI(l,a)
h = get_Scale(k,7)

### Two unlikely values: 1 due to missing scale in image and one due to false length
from collections import Counter
Counter(c)
import cv2
import numpy as np
original_image = cv2.imread(a[-6])
plt.imshow(original_image)
plt.show()
# Load the original RGB image
original_image = original_image.astype(np.float32)
kernel_size = (5,1) # We do not wnt to blur the x axis as we need the length information
blur_gray = cv2.GaussianBlur(original_image,(kernel_size),0)
# Extract the R, G, B channels ## Weird the image does show True values an the mask too
b, g, r = cv2.split(original_image)

#b =np.around(b/5, decimals=0)*5
#g =np.around(g/5, decimals=0)*5
#r =np.around(r/5, decimals=0)*5
# Create a mask for pixels where the absolute differences are within the tolerance

# Create a mask for pixels where the absolute differences are within the tolerance
red_mask = np.logical_or(original_image[:, :, 0] > 150, original_image[:, :, 0] < 100)
green_mask = np.logical_or(original_image[:, :, 1] > 150, original_image[:, :, 1] < 100)
blue_mask = np.logical_or(original_image[:, :, 2] > 150, original_image[:, :, 2] < 100)
mask = np.logical_and.reduce((red_mask, green_mask, blue_mask))

len(np.where(mask == True)[1])
# Create a new grayscale image with the same size as the original image
gray_image = np.zeros_like(r, dtype=np.uint8) + 255

# Set the pixels in the grayscale image where the mask is True to black (0)
gray_image[mask] = 0

# Set the pixels in the grayscale image where the mask is False to white (255)
gray_image[np.logical_not(mask)] = 255

plt.clf()
plt.imshow(gray_image, cmap = "gray")
plt.show()

plt.imsave("Waddup.jpg",arr = gray_image, dpi = 600, cmap = "gray")
a[1]

f
import cv2 as cv2
import matplotlib.pyplot as plt
img_normalized = cv2.normalize(l[2], None, 0, 255, cv2.NORM_MINMAX)
blurred = cv2.GaussianBlur(img_normalized, (3,3), sigmaX=0, sigmaY=0) ## Blur important
# Scale and number should normally be the same colour so Scale_colour = Value_colour
for x in range(50,500,50):
  Can = cv2.Canny(blurred,0,x, L2gradient = True)
  plt.clf()
  plt.imshow(Can, cmap = "gray")
  plt.show()

h[1]

l


from builtins import zip
import numpy as np
import healpy as hp
import matplotlib.pyplot as plt

import lsst.sims.maf.metrics as metrics

from .plotHandler import BasePlotter

__all__ = ['FOPlot', 'SummaryHistogram']

class FOPlot(BasePlotter):
    """
    Special plotter to generate and label fO plots.
    """
    def __init__(self):
        self.plotType = 'FO'
        self.objectPlotter = False
        self.defaultPlotDict = {'title': None, 'xlabel': 'Number of visits',
                                'ylabel': 'Area (1000s of square degrees)',
                                'scale': None, 'Asky': 18000., 'Nvisits': 825,
                                'xMin': 0, 'xMax': None, 'yMin': 0, 'yMax': None,
                                'linewidth': 2, 'reflinewidth': 2}

    def __call__(self, metricValue, slicer, userPlotDict, fignum=None):
        """
        Parameters
        ----------
        metricValue : numpy.ma.MaskedArray
            The metric values calculated with the 'Count' metric and a healpix slicer.
        slicer : lsst.sims.maf.slicers.HealpixSlicer
        userPlotDict: dict
            Dictionary of plot parameters set by user (overrides default values).
            Note that Asky and Nvisits values set here and in the slicer should be consistent,
            for plot labels and summary statistic values to be consistent.
        fignum : int
            Matplotlib figure number to use (default = None, starts new figure).

        Returns
        -------
        int
           Matplotlib figure number used to create the plot.
        """
        if not hasattr(slicer, 'nside'):
            raise ValueError('FOPlot to be used with healpix or healpix derived slicers.')
        fig = plt.figure(fignum)
        plotDict = {}
        plotDict.update(self.defaultPlotDict)
        plotDict.update(userPlotDict)

        if plotDict['scale'] is None:
            plotDict['scale'] = (hp.nside2pixarea(slicer.nside, degrees=True) / 1000.0)

        # Expect metricValue to be something like number of visits
        cumulativeArea = np.arange(1, metricValue.compressed().size + 1)[::-1] * plotDict['scale']
        plt.plot(np.sort(metricValue.compressed()), cumulativeArea, 'k-',
                 linewidth=plotDict['linewidth'], zorder=0)
        # This is breaking the rules and calculating the summary stats in two places.
        # Could just calculate summary stats and pass in labels.
        rarr = np.array(list(zip(metricValue.compressed())),
                        dtype=[('fO', metricValue.dtype)])
        fOArea = metrics.fOArea(col='fO', Asky=plotDict['Asky'], norm=False,
                                nside=slicer.nside).run(rarr)
        fONv = metrics.fONv(col='fO', Nvisit=plotDict['Nvisits'], norm=False,
                            nside=slicer.nside).run(rarr)

        plt.axvline(x=plotDict['Nvisits'], linewidth=plotDict['reflinewidth'], color='b')
        plt.axhline(y=plotDict['Asky'] / 1000., linewidth=plotDict['reflinewidth'], color='r')
        # Add lines for Nvis_median and fOArea: note if these are -666 (badval),
        # the default xMin/yMin values will just leave them off the edges of the plot.
        Nvis_median = fONv['value'][np.where(fONv['name'] == 'MedianNvis')]
        # Note that Nvis is the number of visits (it's not an area) - so goes on number axis
        plt.axvline(x=Nvis_median, linewidth=plotDict['reflinewidth'], color='b',
                    alpha=.5, linestyle=':', label=r'f$_0$ Median Nvisits=%.0f' % Nvis_median)
        plt.axhline(y=fOArea / 1000., linewidth=plotDict['reflinewidth'], color='r',
                    alpha=.5, linestyle=':', label='f$_0$ Area=%.0f' % fOArea)
        plt.legend(loc='lower left', fontsize='small', numpoints=1)

        plt.xlabel(plotDict['xlabel'])
        plt.ylabel(plotDict['ylabel'])
        plt.title(plotDict['title'])

        xMin = plotDict['xMin']
        xMax = plotDict['xMax']
        yMin = plotDict['yMin']
        yMax = plotDict['yMax']
        if (xMin is not None) or (xMax is not None):
            plt.xlim([xMin, xMax])
        if (yMin is not None) or (yMax is not None):
            plt.ylim([yMin, yMax])
        return fig.number

class SummaryHistogram(BasePlotter):
    """
    Special plotter to summarize metrics which return a set of values at each slicepoint,
    such as if a histogram was calculated at each slicepoint
    (e.g. with the lsst.sims.maf.metrics.TgapsMetric).
    Effectively marginalizes the calculated values over the sky, and plots the a summarized
    version (reduced to a single according to the plotDict['metricReduce'] metric).
    """

    def __init__(self):
        self.plotType = 'SummaryHistogram'
        self.objectPlotter = True
        self.defaultPlotDict = {'title': None, 'xlabel': None, 'ylabel': 'Count', 'label': None,
                                'cumulative': False, 'xMin': None, 'xMax': None, 'yMin': None, 'yMax': None,
                                'color': 'b', 'linestyle': '-', 'histStyle': True, 'grid': True,
                                'metricReduce': metrics.SumMetric(), 'bins': None}

    def __call__(self, metricValue, slicer, userPlotDict, fignum=None):
        """
        Parameters
        ----------
        metricValue : numpy.ma.MaskedArray
            Handles 'object' datatypes for the masked array.
        slicer : lsst.sims.maf.slicers
            Any MAF slicer.
        userPlotDict: dict
            Dictionary of plot parameters set by user (overrides default values).
            'metricReduce' (an lsst.sims.maf.metric) indicates how to marginalize the metric values
            calculated at each point to a single series of values over the sky.
            'histStyle' (True/False) indicates whether to plot the results as a step histogram (True)
            or as a series of values (False)
            'bins' (np.ndarray) sets the x values for the resulting plot and should generally match
            the bins used with the metric.
        fignum : int
            Matplotlib figure number to use (default = None, starts new figure).

        Returns
        -------
        int
           Matplotlib figure number used to create the plot.
        """
        fig = plt.figure(fignum)
        plotDict = {}
        plotDict.update(self.defaultPlotDict)
        plotDict.update(userPlotDict)
        # Combine the metric values across all slicePoints.
        if not isinstance(plotDict['metricReduce'], metrics.BaseMetric):
            raise ValueError('Expected plotDict[metricReduce] to be a MAF metric object.')
        # Get the data type
        dt = metricValue.compressed()[0].dtype
        # Change an array of arrays (dtype=object) to a 2-d array of correct dtype
        mV = np.array(metricValue.compressed().tolist(), dtype=[('metricValue', dt)])
        # Make an array to hold the combined result
        finalHist = np.zeros(mV.shape[1], dtype=float)
        metric = plotDict['metricReduce']
        metric.colname = 'metricValue'
        # Loop over each bin and use the selected metric to combine the results
        for i in np.arange(finalHist.size):
            finalHist[i] = metric.run(mV[:, i])
        bins = plotDict['bins']
        if plotDict['histStyle']:
            leftedge = bins[:-1]
            rightedge = bins[1:]

            x = np.vstack([leftedge, rightedge]).T.flatten()
            y = np.vstack([finalHist, finalHist]).T.flatten()

        else:
            # Could use this to plot things like FFT
            x = bins[:-1]
            y = finalHist
        # Make the plot.
        plt.plot(x, y, linestyle=plotDict['linestyle'],
                 label=plotDict['label'], color=plotDict['color'])
        # Add labels.
        plt.xlabel(plotDict['xlabel'])
        plt.ylabel(plotDict['ylabel'])
        plt.title(plotDict['title'])
        plt.grid(plotDict['grid'], alpha=0.3)
        # Set y and x limits, if provided.
        if plotDict['xMin'] is not None:
            plt.xlim(left=plotDict['xMin'])
        elif bins[0] == 0:
            plt.xlim(left=0)
        if plotDict['xMax'] is not None:
            plt.xlim(right=plotDict['xMax'])
        if plotDict['yMin'] is not None:
            plt.ylim(bottom=plotDict['yMin'])
        elif finalHist.min() == 0:
            plotDict['yMin'] = 0
        if plotDict['yMax'] is not None:
            plt.ylim(top=plotDict['yMax'])

        return fig.number


import numpy as np
from random import randint
from keras.utils import to_categorical
np.set_printoptions(threshold=np.nan)

def Create_Features(sample_size, sequence_length, feature_length):
    features = []
    for i in range(sample_size):
        _ = []
        for j in range(sequence_length):
            _.append(randint(0,feature_length))
        features.append(_)

    features = np.array(features)

    features = to_categorical(features)
    features = features.reshape([sample_size,sequence_length,feature_length])
    print("features shape: ", features.shape)
    return features

def Create_Labels(sample_size):
    phenotype = []
    for _ in range(sample_size):
        phenotype.append(randint(0,1))
    phenotype = np.array(phenotype)
    print("phenotype shape: ", phenotype.shape)
    return phenotype

def Sample_Data(sample_size,sequence_length, target):
    features = []
    for i in range(sample_size):
        _ = []
        for j in range(sequence_length):
            if j == target and i + randint(0,1)%2 ==0:
                _.append(1)
            else:
                _.append(randint(0, 3))
        features.append(_)

    phenotype = []
    for x in range(sample_size):
        if features[x][target] == 1:
            phenotype.append(1)
        else:
            phenotype.append(0)

    features = np.array(features)

    features = to_categorical(features)
    features = features.reshape([sample_size,sequence_length,4])
    phenotype = np.array(phenotype)
    return features, phenotype


import itertools
import pecan

from oslo_log import log
from pecan import rest

from shadowfiend.api import acl
from shadowfiend.api.controllers.v1 import models
from shadowfiend.common import exception
from shadowfiend.common import policy
from shadowfiend.common import timeutils
from shadowfiend.db import models as db_models
from shadowfiend.services import keystone as ks_client

from wsme import types as wtypes
from wsmeext.pecan import wsexpose

LOG = log.getLogger(__name__)
HOOK = pecan.request

class BillingOwnerController(rest.RestController):

    def __init__(self, project_id):
        self.project_id = project_id

    @wsexpose(None, wtypes.text)
    def put(self, user_id):
        """Change billing_owner of this project."""
        HOOK.conductor_rpcapi.change_billing_owner(
            HOOK.context,
            project_id=self.project_id,
            user_id=user_id)

    @wsexpose(models.UserAccount)
    def get(self):
        LOG.info("get_billing_owner")
        user_account = HOOK.conductor_rpcapi.get_billing_owner(
            HOOK.context,
            self.project_id)
        return db_models.Account(**user_account)

class ExistProjectController(rest.RestController):
    """Manages operations on project."""

    _custom_actions = {
        'estimate': ['GET'],
    }

    def __init__(self, project_id):
        self._id = project_id

    @pecan.expose()
    def _lookup(self, subpath, *remainder):
        if subpath == 'billing_owner':
            return (BillingOwnerController(self._id),
                    remainder)

    def _project(self):
        try:
            project = HOOK.conductor_rpcapi.get_project(
                HOOK.context,
                project_id=self._id)
        except Exception:
            LOG.error('project %s no found' % self._id)
            raise exception.ProjectNotFound(project_id=self._id)
        return project

    @wsexpose(models.Project)
    def get(self):
        """Return this project."""
        return db_models.Project(**self._project())

class ProjectController(rest.RestController):
    """Manages operations on the projects collection."""

    def __init__(self):
        pass

    @pecan.expose()
    def _lookup(self, project_id, *remainder):
        if remainder and not remainder[-1]:
            remainder = remainder[:-1]
        return ExistProjectController(project_id), remainder

    @wsexpose([models.UserProject], wtypes.text, wtypes.text, wtypes.text)
    def get_all(self, user_id=None, type=None, duration=None):
        """Get all projects."""
        user_id = acl.get_limited_to_user(HOOK.headers,
                                          'project:all') or user_id
        result = []

        if not type or type.lower() == 'pay':
            # if admin call this api, limit to admin's user_id
            if not user_id:
                user_id = HOOK.context.user_id

            try:
                relations = HOOK.conductor_rpcapi.get_relation(
                    HOOK.context,
                    user_id=user_id)
            except Exception as e:
                LOG.exception('Fail to get all projects')
                raise exception.DBError(reason=e)

            if not relations:
                LOG.warn('User %s has no payed projects' % user_id)
                return []

            project_ids = [up['project_id'] for up in relations]

            projects = self._list_keystone_projects()

            for u, p in itertools.product(relations, projects):
                if u['project_id'] == p.id:
                    up = models.UserProject(
                        user_id=user_id,
                        project_id=u['project_id'],
                        project_name=p.name,
                        user_consumption=u['user_consumption'],
                        project_consumption=u['project_consumption'],
                        billing_owner=None,
                        project_owner=None,
                        project_creator=None,
                        is_historical=u['is_historical'],
                        created_at=u['created_at'])
                    result.append(up)
        elif type.lower() == 'all':
            # if admin call this api, limit to admin's user_id
            if not user_id:
                user_id = HOOK.context.user_id

            k_projects = ks_client.get_project_list(name=user_id)
            LOG.debug('Projects: %s' % k_projects)
            project_ids = [p.id for p in k_projects]

            if not project_ids:
                LOG.warning('User %s has no projects' % user_id)
                return []

            try:
                sf_projects = (HOOK.conductor_rpcapi.
                               get_projects(HOOK.context, project_ids))
            except Exception as e:
                LOG.exception('Fail to get all projects')
                raise exception.DBError(reason=e)
            for k, sf in itertools.product(k_projects, sf_projects):
                k = k.__dict__
                if k['id'] == sf['project_id']:
                    up = models.UserProject(
                        user_id=user_id,
                        project_id=sf['project_id'],
                        project_name=k['name'],
                        project_consumption=sf['consumption'],
                        billing_owner=None,
                        project_owner=None,
                        project_creator=None,
                        is_historical=False,
                        created_at=(
                            sf['created_at'] if sf['created_at'] else None))
                    result.append(up)

        elif type.lower() == 'simple':
            duration = timeutils.normalize_timedelta(duration)
            if duration:
                active_from = timeutils.utcnow() - duration
            else:
                active_from = None
            sf_projects = list(HOOK.conductor_rpcapi.get_projects(
                HOOK.context,
                user_id=user_id,
                active_from=active_from))
            project_ids = [p.project_id for p in sf_projects]

            if not project_ids:
                LOG.warn('User %s has no payed projects' % user_id)
                return []

            k_projects = self._list_keystone_projects()

            for k, sf in itertools.product(k_projects, sf_projects):
                if k.id == sf['project_id']:
                    up = models.UserProject(
                        project_id=sf['project_id'],
                        project_name=k.name,
                        domain_id=sf['domain_id'],
                        billing_owner=dict(user_id=sf['user_id']))
                    result.append(up)

        return result

    def _list_keystone_projects(self):
        projects = []
        domain_ids = \
            [domain.id for domain in ks_client.get_domain_list()]
        for domain_id in domain_ids:
            projects.extend(ks_client.get_project_list(domain_id))
        return projects

    @wsexpose(None, body=models.Project)
    def post(self, data):
        """Create a new project."""
        policy.check_policy(HOOK.context, "project:post")
        try:
            project = data.as_dict()
            return HOOK.conductor_rpcapi.create_project(HOOK.context, project)
        except Exception:
            LOG.exception('Fail to create project: %s' % project)
            raise exception.ProjectCreateFailed(project_id=data.project_id,
                                                user_id=data.user_id)


import json
import pathlib
from typing import Set, List

from progress_report import ProgressReport  # , ProgressReportSubstep
import bpy

from . import gltftypes
from . import glb
from .import_manager import ImportManager
from .texture_io import load_textures
from .material_io import load_materials
from .mesh_io import load_meshes
from .node_io import load_objects
from .node import Node
from . import gltf_buffer

from logging import getLogger  # pylint: disable=C0411
logger = getLogger(__name__)

def _setup_skinning(blender_object: bpy.types.Object,
                    attributes: gltf_buffer.VertexBuffer, bone_names: List[str],
                    armature_object: bpy.types.Object)->None:
    # create vertex groups
    for bone_name in bone_names:
        if bone_name:
            blender_object.vertex_groups.new(
                name=bone_name)

    idx_already_done: Set[int] = set()

    # each face
    for poly in blender_object.data.polygons:
        # face vertex index
        for loop_idx in range(poly.loop_start, poly.loop_start + poly.loop_total):
            loop = blender_object.data.loops[loop_idx]
            vert_idx = loop.vertex_index
            if vert_idx < 0:
                raise Exception()
            if vert_idx >= len(attributes.joints):
                raise Exception()

            if vert_idx in idx_already_done:
                continue
            idx_already_done.add(vert_idx)

            cpt = 0
            for joint_idx in attributes.joints[vert_idx]:
                if cpt > 3:
                    break
                weight_val = attributes.weights[vert_idx][cpt]
                if weight_val != 0.0:
                    # It can be a problem to assign weights of 0
                    # for bone index 0, if there is always 4 indices in joint_ tuple
                    bone_name = bone_names[joint_idx]
                    if bone_name:
                        group = blender_object.vertex_groups[bone_name]
                        group.add([vert_idx], weight_val, 'REPLACE')
                cpt += 1

    # select
    # for obj_sel in bpy.context.scene.objects:
    #    obj_sel.select = False
    #blender_object.select = True
    #bpy.context.scene.objects.active = blender_object

    modifier = blender_object.modifiers.new(name="Armature", type="ARMATURE")
    modifier.object = armature_object

def _remove_empty(node: Node):
    for i in range(len(node.children)-1, -1, -1):
        child = node.children[i]
        _remove_empty(child)

    if node.children:
        print(f'{node} children {len(node.children)}')
        return
    if node.blender_armature:
        print(f'{node} has {node.blender_armature}')
        return
    if node.blender_object.data:
        print(f'{node} has {node.blender_object}')
        return

    # remove empty
    print('remove', node)
    bpy.data.objects.remove(node.blender_object, do_unlink=True)
    if node.parent:
        node.parent.children.remove(node)

def load(context,
         filepath: str,
         yup_to_zup: bool
         )->Set[str]:

    path = pathlib.Path(filepath)
    if not path.exists():
        return {'CANCELLED'}

    with ProgressReport(context.window_manager) as progress:
        progress.enter_substeps(5, "Importing GLTF %r..." % path.name)

        body = b''
        try:
            with path.open('rb') as f:
                ext = path.suffix.lower()
                if ext == '.gltf':
                    gltf = gltftypes.from_json(json.load(f))
                elif ext == '.glb' or ext == '.vrm':
                    gltf, body = glb.parse_glb(f.read())
                else:
                    logger.error("%s is not supported", ext)
                    return {'CANCELLED'}
        except Exception as ex:  # pylint: disable=w0703
            logger.error("%s", ex)
            return {'CANCELLED'}

        manager = ImportManager(path, gltf, body, yup_to_zup)
        manager.textures.extend(load_textures(progress, manager))
        manager.materials.extend(load_materials(progress, manager))
        manager.meshes.extend(load_meshes(progress, manager))
        nodes, root = load_objects(context, progress, manager)

        # skinning
        armature_object = next(
            node for node in root.traverse() if node.blender_armature)

        for node in nodes:
            if node.gltf_node.mesh != -1 and node.gltf_node.skin != -1:
                _, attributes = manager.meshes[node.gltf_node.mesh]

                skin = gltf.skins[node.gltf_node.skin]
                bone_names = [
                    nodes[joint].bone_name for joint in skin.joints]

                #armature_object =nodes[skin.skeleton].blender_armature

                _setup_skinning(node.blender_object, attributes,
                                bone_names,
                                armature_object.blender_armature)

        # remove empties
        _remove_empty(root)

        # done
        context.scene.update()
        progress.leave_substeps("Finished")
        return {'FINISHED'}


# coding=utf-8

import logging
import datetime
from dofitariomanager import flaskmongo
import numpy
from flask_restful import Resource
from flask import jsonify
from flask import request
from flask import abort
logger_ = logging.getLogger(__name__)

def make_error(status_code, message):
    response = jsonify({
        'status': status_code,
        'message': message
    })
    response.status_code = status_code
    return response

class GeneralWeek(Resource):

    # def __init__(self, session=None):
    #     if session is None:
    #         session = db.get_session()
    #     self._session = session
    def get(self):
        aux = numpy.asarray([[0] * 16] * 7)
        counter = 0
        cursor = flaskmongo.db.tIndividualWeeklyTimetable.find()
        for line in cursor:
            counter = counter + 1
            aux = aux + numpy.array(line['week'])
        result = numpy.ndarray.tolist(aux)

        if counter == 0:
            return make_error(404, "No results o_O, check DB!!!")
        else:
            return {"week": result}


from datetime import datetime

import pytest

from tests.assets import POSTS_DICT

class TestSearchPostInReplies:
    @pytest.mark.parametrize(
        ('body', 'result'),
        (
            (
                {'post_id': 2},
                {'amount': 0, 'result': []},
            ),
            (
                {'post_id': 4},
                {'amount': 1, 'result': [POSTS_DICT[5]]},
            ),
        ),
    )
    def test_clear_search(self, client_with_data, body, result):
        resp = client_with_data.post(url='/replies', json=body)
        assert resp.status_code == 200

        data = resp.json()

        for i in data['result']:
            i['post_created_at'] = datetime.strptime(
                i['post_created_at'], '%Y-%m-%dT%H:%M:%S'
            )
        assert data == result


import os

from django.conf import settings
from django.middleware import cache
from sass import compile

def locate(filename):
    for path, dirs, files in os.walk(os.getcwd(), followlinks=True):
        for f in files:
            if f == filename:
                yield os.path.join(path, filename)

class FetchFromCacheMiddleware(cache.FetchFromCacheMiddleware):
    """Minor change to the original middleware that prevents caching of
    requests that have a `sessionid` cookie. This should be the
    Django default, IMHO.

    """

    def process_request(self, request):
        if "sessionid" not in request.COOKIES:
            return super().process_request(request)

class SassMiddleware:
    """Simple SASS middleware that intercepts requests for .css files and
    tries to compile the corresponding SCSS file.

    """

    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        if settings.DEBUG and request.path.endswith(".css"):
            css_file = request.path.rsplit("/", 1)[1]
            sass_file = css_file[:-4]
            sass_paths = locate(sass_file)
            for sass_path in list(sass_paths):
                if os.path.exists(sass_path):
                    css_path = sass_path + ".css"
                    map_path = css_path + ".map"
                    css = compile(filename=sass_path, output_style="nested")
                    css, mapping = compile(
                        filename=sass_path, source_map_filename=map_path
                    )
                    with open(css_path, "w") as f:
                        f.write(css)
                    with open(map_path, "w") as f:
                        f.write(mapping)

        response = self.get_response(request)
        return response


import base64
import hashlib
import hmac
import time
from typing import Any, Dict

from pyfs_base import BaseFeishu

class Bot(BaseFeishu):
    def __init__(self, hook_id: str = None, key_word: str = None, secret: str = None) -> None:
        super(Bot, self).__init__()
        self.hook_id = hook_id
        self.key_word = key_word
        self.secret = secret
        # https://open.feishu.cn/document/client-docs/bot-v3/add-custom-bot
        # curl -X POST -H "Content-Type: application/json" \
        #     -d '{"msg_type":"text","content":{"text":"request example"}}' \
        #     https://open.feishu.cn/open-apis/bot/v2/hook/****
        self.WEBHOOK_URL = self.OPEN_DOMAIN + '/open-apis/bot/v2/hook/{hook_id}'

    def __gen_sign(self, timestamp: int, secret: str) -> str:
        # 拼接timestamp和secret
        string_to_sign = '{}\n{}'.format(timestamp, secret)
        hmac_code = hmac.new(string_to_sign.encode('utf-8'), digestmod=hashlib.sha256).digest()
        # 对结果进行base64处理
        sign = base64.b64encode(hmac_code).decode('utf-8')
        return sign

    def send_hook_message(self, data: Dict[str, Any], hook_id: str = None, secret: str = None) -> Dict[str, Any]:
        hook_id = hook_id or self.hook_id
        secret = secret or self.secret
        if secret:
            timestamp = int(time.time())
            data['timestamp'] = timestamp
            data['sign'] = self.__gen_sign(timestamp, secret)
        return self.post(self.WEBHOOK_URL.format(hook_id=hook_id), data=data)

    # 发送文本消息
    def send_hook_text_message(self, message: str, hook_id: str = None, key_word: str = None, secret: str = None) -> Dict[str, Any]:
        key_word = key_word or self.key_word
        if key_word:
            message = '【{0}】{1}'.format(key_word, message)
        data = {
            'msg_type': 'text',
            'content': {
                'text': message,
            }
        }
        return self.send_hook_message(data, hook_id=hook_id, secret=secret)

    # 发送富文本消息
    def send_hook_post_message(self, post: Dict[str, Any], hook_id: str = None, key_word: str = None, secret: str = None) -> Dict[str, Any]:
        key_word = key_word or self.key_word
        if key_word:
            for lang in post:
                post[lang]['title'] = '【{0}】{1}'.format(key_word, post[lang]['title'])
        data = {
            'msg_type': 'post',
            'content': {
                'post': post,
            }
        }
        return self.send_hook_message(data, hook_id=hook_id, secret=secret)

    # 发送群名片
    def send_hook_share_chat_message(self, share_chat_id: str, hook_id: str = None, secret: str = None) -> Dict[str, Any]:
        # 群 ID 说明: https://open.feishu.cn/document/server-docs/group/chat/chat-id-description
        data = {
            'msg_type': 'share_chat',
            'content': {
                'share_chat_id': share_chat_id,
            }
        }
        return self.send_hook_message(data, hook_id=hook_id, secret=secret)

    # 发送图片
    def send_hook_image_message(self, image_key: str, hook_id: str = None, secret: str = None) -> Dict[str, Any]:
        # 群 ID 说明: https://open.feishu.cn/document/server-docs/group/chat/chat-id-description
        data = {
            'msg_type': 'image',
            'content': {
                'image_key': image_key,
            }
        }
        return self.send_hook_message(data, hook_id=hook_id, secret=secret)

    # 发送消息卡片
    def send_hook_interactive_message(self, interactive: Dict[str, Any], hook_id: str = None, secret: str = None) -> Dict[str, Any]:
        # 卡片结构介绍: https://open.feishu.cn/document/common-capabilities/message-card/message-cards-content/card-structure/card-content
        # 消息卡片搭建工具: https://open.feishu.cn/document/common-capabilities/message-card/message-card-builder
        data = {
            'msg_type': 'interactive',
            'card': interactive,
        }
        return self.send_hook_message(data, hook_id=hook_id, secret=secret)

bot = Bot()
send_hook_message = bot.send_hook_message
send_hook_text_message = bot.send_hook_text_message
send_hook_post_message = bot.send_hook_post_message
send_hook_share_chat_message = bot.send_hook_share_chat_message
send_hook_image_message = bot.send_hook_image_message
send_hook_interactive_message = bot.send_hook_interactive_message