"""
Původní návrh:
class Board
- grid
* reset
* draw
* score - z pohledu hráče
* score_wnd5
* wintie - globálně, 0 = jedeme dál, 1/-1 win hráč, jinak = tie
* wintie_wnd5
"""

import pygame
import random
import math
from pyshqorky.players import *

class Board:
    """ Třída pro práci s herní deskou. Jsou zde informace o rozmístění kamenů na desce, vyhodnocení stavu desky a její vykreslování."""

    #: Obsah prázdného pole na desce.
    CELL_EMPTY = 0

    #: Vítězství nebo remíza? Nic, nejde určit.
    WT_NONE = 0
    #: Vítězství nebo remíza? Jsem vítěz.
    WT_WINNER = 1
    #: Vítězství nebo remíza? Nejsem vítěz.
    WT_LOSER = 2
    #: Vítězství nebo remíza? Je to remíza.
    WT_TIE = 3

    def __init__(self, rows: int, cols: int, width: int, height: int, x_offset: int, y_offset: int) -> None:
        #: Počet řádků.
        self.rows = rows
        #: Počet sloupců.
        self.cols = cols
        #: Velikost na ose x v px.
        self.width = width
        #: Velikost na ose y v px.
        self.height = height
        #: Velikost strany jednoho hracího pole.
        self.sqsize = width // cols
        #: Posun na ose x, kam se bude deska vykreslovat.
        self.x_offset = x_offset
        #: Posun na ose y, kam se bude deska vykreslovat.
        self.y_offset = y_offset
        #: Seznam seznamů (2D pole), kde je umístění kamenů na desce.
        self.grid = [[0 for col in range(self.cols)] for row in range(self.rows)]
        #: Seznam seznamů (2D pole), kde je info o hracích polích, které použijeme pro vyhodnocení interakce s hráčem.
        self.tiles = [[pygame.Rect for col in range(self.cols)] for row in range(self.rows)]

    def draw(self, screen, players: Players | None = None, mark_coords: list[tuple[int, int]] | None = None) -> None:
        """
        Vykreslení herní plochy. Nejdřív nakreslíme pole `pygame.Rect`. Každý v poli o velikosti o jedna menší, než velikost `pyshqorky.board.Board.sqsize`. To pro zobrazení mřížky.
        Potom, pokud jsme dostali v parametru i seznam hráčů, nakreslíme jejich kameny na každé pole, kde se nacházejí.
        Nakonec nakreslíme zvýraznění, pokud je máme.
        """
        # vykreslení herní plochy
        for r in range (self.rows):
            for c in range(self.cols):
                # Vykreslení jednoho herního pole
                self.tiles[r][c] = pygame.draw.rect(screen, (0x40,0x40,0x40), #type: ignore
                    pygame.Rect(self.sqsize*r+self.x_offset, self.sqsize*c+self.y_offset, self.sqsize-1, self.sqsize-1))
                # Pokud jsme dostali i seznam hráčů
                if players is not None:
                    # projedem oba
                    for id, pl in players.items():
                        # a pokud je tenhle na tomto poli
                        if self.grid[r][c] == pl.id:
                            # tak ho nakreslíme
                            pl.draw(screen, r, c, self.x_offset, self.y_offset, self.sqsize)
        # nakonec vykreslení zvýraznění, pokud je přítomno
        if mark_coords is not None:
            # pro každé pole k zvýraznění
            for (r, c) in mark_coords:
                # pokud máme hráče
                if players is not None:
                    # projedem oba
                    for id, pl in players.items():
                        # a pokud je tenhle na tomto poli
                        if self.grid[r][c] == pl.id:
                            # tak ho obtáhneme
                            pl.draw(screen, r, c, self.x_offset, self.y_offset, self.sqsize, True)
                # jinak uděláme pro zvýraznění tečku uprostřed
                else:
                    pygame.draw.circle(screen, (255, 255, 0), (self.sqsize*r+self.x_offset+(self.sqsize/2),
                                                    self.sqsize*c+self.y_offset+(self.sqsize/2)),
                                                    self.sqsize*0.15)

    def score_wnd5(self, window: list, player: Player) -> int:
        """
        Ohodnocení výseku 1x5 z hrací desky z pohledu hráče (počítačového). Jestliže je tu prázdno nebo jsou tu oba protivníci, skóre je nula.
        Jestli je tu hráč sám, skóre se přičítá a pokud pouze protihráč, skóre se odečítá.
        Kolik se toho přičte nebo odečte, záleží na úrovni hry počítače, jestli jsou to kameny hráče nebo protivníka a počtu kamenů v této pětici.
        Hodnota se vezme ze slovníku `pyshqorky.player.Player.AI_VALUES`
        """
        score = 0

        # jestliže je tu prázdno
        if window.count(Board.CELL_EMPTY) == 5:
            return 0
        # jestliže v této pětici jsme
        if window.count(player.id) != 0:
            # a nejsme tu sami
            if window.count(player.oponent_id) != 0:
                return 0
            # pokud jsme tu sami
            else:
                # tak přičteme hodnotu odpovídající počtu našich značek
                score += Player.AI_VALUES[player.ai_level][Player.AI_SCORE_MY][window.count(player.id)]
        else:
            # je tu pouze protivník, takže odečteme hodnotu odpovídající počtu jeho značek
            score -= Player.AI_VALUES[player.ai_level][Player.AI_SCORE_OPONENT][window.count(player.oponent_id)]

        return score

    def score_board(self, player: Player) -> int:
        """
        Projedeme na hrací desce všechna pole 1x5. Pro každé takové pole voláme `pyshqorky.board.Board.score_wnd5`.
        Nasčítáme všechna skóre, která se nám vrátila a vracíme to jako ohodnocení celé desky.
        Inspirace zde: http://blog.trixi.cz/2013/02/popis-piskvorkoveho-algoritmu/
        """
        score = 0
        #"""
        # ohodnocení řádků
        for r in range(self.rows):
            row_array = [int(i) for i in list(self.grid[r][:])]
            for c in range(self.cols-4):
                window = row_array[c:c+5]
                score += self.score_wnd5(window, player)

        # ohodnocení sloupců
        for c in range(self.cols):
            col_array = [i[:][c] for i in self.grid]
            for r in range(self.rows-4):
                window = col_array[r:r+5]
                score += self.score_wnd5(window, player)

        # ohodnocení diagonál (\ i /)
        for r in range(self.rows-4):
            for c in range(self.cols-4):
                # to je \
                window = [self.grid[r+i][c+i] for i in range(5)]
                score += self.score_wnd5(window, player)
                # a tohle /
                window = [self.grid[r+4-i][c+i] for i in range(5)]
                score += self.score_wnd5(window, player)
        """
        # optimalizovaný algoritmus, jenom nefunguje stejně
        for r in range(2, self.rows-2):
            for c in range(2, self.cols-2):
                # ohodnotíme řádky
                window = [self.grid[r-2+i][c] for i in range(5)]
                # budeme hodnotit pouze pokud tu není prázdno
                if window.count(Board.CELL_EMPTY != 5):
                    score += self.score_wnd5(window, player)
                # sloupce
                window = [self.grid[r][c-2+i] for i in range(5)]
                # budeme hodnotit pouze pokud tu není prázdno
                if window.count(Board.CELL_EMPTY != 5):
                    score += self.score_wnd5(window, player)
                # diagonála \
                window = [self.grid[r-2+i][c-2+i] for i in range(5)]
                # budeme hodnotit pouze pokud tu není prázdno
                if window.count(Board.CELL_EMPTY != 5):
                    score += self.score_wnd5(window, player)
                # diagonála /
                window = [self.grid[r+2-i][c-2+i] for i in range(5)]
                # budeme hodnotit pouze pokud tu není prázdno
                if window.count(Board.CELL_EMPTY != 5):
                    score += self.score_wnd5(window, player)
        """
        return score

    # vracíme WT_NONE, když je možné hrát dál
    # WT_WINNER, pokud je vítězem player
    # WT_LOSER, pokud je vítězem oponent
    # WT_TIE, pokud v této pětici nejde dosáhnout vítězství
    def win_tie_wnd5(self, window: list[int], player: Player) -> int:
        """
        Zde hodnotíme z pohledu hráče výsek z boardu o velikosti 1 x 5 na možnou výhru, prohru nebo remízu.
        Pokud je tam pouze player, vyhrál. Pokud je tam pouze oponent, player prohrál.
        Pokud jsou tam oba, tak zde již nikdo pětku neudělá. Pokud neplatí nic z toho, je možné hrát dál.
        Vrací možné hodnoty WT_WINNER, pokud player zvítězil, WT_LOSER pokud prohrál, WT_TIE pokud zde již není možné vyhrát nebo WT_NONE, pokud je možné zde ještě vyhrát.
        """
        # jestliže máme pět
        if window.count(player.id) == 5:
            return self.WT_WINNER

        # jestli má pět oponent
        if window.count(player.oponent_id) == 5:
            return self.WT_LOSER

        # zde již není možné vyhrát
        if window.count(player.id) != 0 and window.count(player.oponent_id) != 0:
            return self.WT_TIE

        # jinak je možné pořád hrát dál
        return self.WT_NONE

    def win_tie(self, player: Player) -> tuple[int, list[tuple[int, int]]]:
        """
        Zde projedeme celý board a z pohledu hráče zhodnotíme, jestli jsme vyhráli nebo prohráli, jestli je remíza nebo hrajeme dál.
        Technicky je to provedeno tak, že projedeme všechna okna 1 x 5, co jsou na desce a zhodnotíme je ve vlastní funkci win_tie_wnd5.
        Podle toho odsud vracíme hodnoty dál. Pro vítězství i kde bylo zvítězeno pro označení dané pětky.
        Jako hlavní integer vracíme WT_WINNER, pokud player zvítězil, WT_LOSER pokud prohrál, WT_TIE pokud je remíza nebo WT_NONE, pokud je možné hrát dál.
        """
        wt5 = None
        tie = self.WT_TIE

        # ohodnocení řádků
        for r in range(self.rows):
            row_array = [int(i) for i in list(self.grid[r][:])]
            for c in range(self.cols-4):
                window = row_array[c:c+5]
                wt5 = self.win_tie_wnd5(window, player)
                if (wt5 in (self.WT_WINNER, self.WT_LOSER)):
                    return (wt5, [(r, c+i) for i in range(5)])
                elif wt5 == self.WT_NONE:
                    tie = wt5

        # ohodnocení sloupců
        for c in range(self.cols):
            col_array = [i[:][c] for i in self.grid]
            for r in range(self.rows-4):
                window = col_array[r:r+5]
                wt5 = self.win_tie_wnd5(window, player)
                if (wt5 in (self.WT_WINNER, self.WT_LOSER)):
                    return (wt5, [(r+i,c) for i in range(5)])
                elif wt5 == self.WT_NONE:
                    tie = wt5

        # ohodnocení diagonál (\ i /)
        for r in range(self.rows-4):
            for c in range(self.cols-4):
                # to je \
                window = [self.grid[r+i][c+i] for i in range(5)]
                wt5 = self.win_tie_wnd5(window, player)
                if (wt5 in (self.WT_WINNER, self.WT_LOSER)):
                    return (wt5, [(r+i, c+i) for i in range(5)])
                elif wt5 == self.WT_NONE:
                    tie = wt5
                # a tohle /
                window = [self.grid[r+4-i][c+i] for i in range(5)]
                wt5 = self.win_tie_wnd5(window, player)
                if (wt5 in (self.WT_WINNER, self.WT_LOSER)):
                    return (wt5, [(r+4-i, c+i) for i in range(5)])
                elif wt5 == self.WT_NONE:
                    tie = wt5

        # nikdo ještě nevyhrál, tak vracíme, jestli byla remíza nebo ne
        return (tie, list())

    def best_move(self, player: Player) -> tuple:
        """
        Najdeme, který tah hráče z možných bude ohodnocen nejvyšším skóre. Všechny s tímto skóre si dáme do seznamu a z něho jeden náhodně vybereme.
        """
        # možné tahy
        avail_moves = []
        # na začátek je nejlepší skóre dostatečně malé, třeba mínus nekonečno
        best_score = -math.inf
        # projedeme všechny pole na hrací desce
        for r in range(self.rows):
            for c in range(self.cols):
                # pokud je prázdné
                if self.grid[r][c] == Board.CELL_EMPTY:
                    # tak si ho pro teď obsadíme
                    self.grid[r][c] = player.id
                    # a spočítáme jeho skóre
                    score = self.score_board(player)
                    # pole vrátíme zase zpět na prázdné
                    self.grid[r][c] = Board.CELL_EMPTY
                    # pokud je skóre vyšši než předchozí nejvyšší
                    if (score > best_score):
                        # vynulujeme seznam s možnými předchozími tahy
                        avail_moves = []
                        # a přidáme tam tento
                        avail_moves.append((r,c))
                        # nejlepší skóre je tedy toto naše nové
                        best_score = score
                    # jinak, pokud je zjištěné skóre shodné s nejvyššim
                    elif (score == best_score):
                        # tak přidáme tento tah mezi nejlepší
                        avail_moves.append((r,c))
        # vrátíme náhodně vybraný tah z těch nejlepších
        return random.choice(avail_moves)

    def make_move(self, player: Player, coord: tuple) -> None:
        """
        Položíme značku hráče `pyshqorky.player.Player` na pole o souřadnicích coord.
        """
        self.grid[coord[0]][coord[1]] = player.id

    def reset(self) -> None:
        """
        Inicializujeme hrací desku - odebereme všechny značky hráčů.
        """
        self.grid = [[0 for col in range(self.cols)] for row in range(self.rows)]


import pymongo
import os
from datetime import datetime
import math
import re
import pymongo
import keys  # .gitgnored file
from bson.objectid import ObjectId
from bson.son import SON
import atexit
import math

CONNECTION = None

PAGESIZE = 10

def date_now():
    """
    Needed to keep the same date in python and mongo, as mongo rounds to millisecond
    """
    d = datetime.utcnow()
    return d.replace(microsecond=math.floor(d.microsecond/1000)*1000)

CONNECTION = None

def close_connection():
    global CONNECTION
    if CONNECTION is not None:
        CONNECTION.close()

atexit.register(close_connection)

def get_connection():
    global CONNECTION
    if CONNECTION is not None:
        return CONNECTION
    else:
        mongo_db_key = os.getenv("LOCAL_DB_KEY", None)
        if mongo_db_key is None:
            exit("LOCAL_DB_KEY env variable is not set.")
        "Return mongodb connection"
        CONNECTION = pymongo.MongoClient(mongo_db_key)
        return CONNECTION

def check_run_name(name):
    connection = get_connection()
    db = connection.get_database()
    # Fastest.
    run = db.runs.find({"name": name}).limit(1).count(True)
    return run is not 0

def get_run_list():
    connection = get_connection()
    db = connection['bifrost_upgrade_test']
    # Fastest.
    runs = list(db.runs.find( {},#{"type": "routine"}, #Leave in routine
                                {"name": 1,
                                "_id": 0,
                                "samples": 1}).sort([['metadata.created_at', pymongo.DESCENDING]]))
    return runs

def get_group_list(run_name=None):
    connection = get_connection()
    db = connection.get_database()
    if run_name is not None:
        run = db.runs.find_one(
            {"name": run_name},
            {
                "_id": 0,
                "samples._id": 1
            }
        )
        if run is None:
            run_samples = []
        else:
            run_samples = run["samples"]
        sample_ids = [s["_id"] for s in run_samples]
        groups = list(db.samples.aggregate([
            {
                "$match": {
                    "_id": {"$in": sample_ids},
                }
            },
            {
                "$group": {
                    "_id": "$properties.sample_info.summary.group",
                    "count": {"$sum": 1}
                }
            }
        ]))
    else:
        groups = list(db.samples.aggregate([
            {
                "$group": {
                    "_id": "$properties.sample_info.summary.group",
                    "count": { "$sum":1 }
                }
            }
        ]))

    return groups

def get_species_list(species_source, run_name=None):
    connection = get_connection()
    db = connection.get_database()
    if species_source == "provided":
        spe_field = "properties.sample_info.summary.provided_species"
    else:
        spe_field = "properties.species_detection.summary.detected_species"
    if run_name is not None:
        run = db.runs.find_one(
            {"name": run_name},
            {
                "_id": 0,
                "samples._id": 1
            }
        )
        if run is None:
            run_samples = []
        else:
            run_samples = run["samples"]
        sample_ids = [s["_id"] for s in run_samples]
        species = list(db.samples.aggregate([
            {
                "$match": {
                    "_id": {"$in": sample_ids}
                }
            },
            {
                "$group": {
                    "_id": "$" + spe_field,
                    "count": {"$sum": 1}
                }
            },
            {
                "$sort": {"_id": 1}
            }
        ]))
    else:
        species = list(db.samples.aggregate([
            {
                "$group": {
                    "_id": "$" + spe_field,
                    "count": {"$sum": 1}
                }
            },
            {
                "$sort": {"_id": 1}
            }
        ]))
    return species

def filter_qc(qc_list):
    if qc_list is None or len(qc_list) == 0:
        return None
    qc_query = []
    for elem in qc_list:
        if elem == "Not checked":
            qc_query.append({"$and": [
                {"properties.datafiles.summary.paired_reads": {"$exists": True}},
                {"properties.stamper.summary.stamp.value": {"$exists": False}}
            ]})
        elif elem == "core facility":
            qc_query.append({"$or": [
                        {"properties.datafiles.summary.paired_reads": {"$exists": False}},
                        {"properties.stamper.summary.stamp.value": "core facility"}
                    ]
                })
        else:
            qc_query.append({"properties.stamper.summary.stamp.value": elem})
    return {"$match": {"$and": qc_query}}

def filter(run_names=None,
           species=None, species_source="species", group=None,
           qc_list=None, samples=None, pagination=None,
           sample_names=None,
           projection=None):
    if species_source == "provided":
        spe_field = "properties.provided_species"
    elif species_source == "detected":
        spe_field = "properties.detected_species"
    else:
        spe_field = "properties.species"
    connection = get_connection()
    db = connection['bifrost_upgrade_test']
    query = []
    sample_set = set()
    if sample_names is not None and len(sample_names) != 0:
        sample_names_query = []
        for s_n in sample_names:
            if s_n.startswith("/") and s_n.endswith("/"):
                sample_names_query.append(re.compile(s_n[1:-1]))
            else:
                sample_names_query.append(s_n)
        query.append({"name": {"$in": sample_names_query}})
    if samples is not None and len(samples) != 0:
        sample_set = {ObjectId(id) for id in samples}
        query.append({"_id": {"$in": list(sample_set)}})
    if run_names is not None and len(run_names) != 0:
        runs = list(db.runs.find(
            {"name": {"$in": run_names}},
            {
                "_id": 0,
                "samples._id": 1
            }
        ))
        if runs is None:
            run_sample_set = set()
        else:
            run_sample_set = {s["_id"] for run in runs for s in run['samples']}

        if len(sample_set):
            inter = run_sample_set.intersect(sample_set)
            query.append({"_id": {"$in": list(inter)}})
        else:
            query.append({"_id": {"$in": list(run_sample_set)}})
    if species is not None and len(species) != 0:

        if "Not classified" in species:
            query.append({"$or":
                [
                    {spe_field: None},
                    {spe_field: {"$in": species}},
                    {spe_field: {"$exists": False}}
                ]
            })
        else:
            query.append({spe_field: {"$in": species}})
    if group is not None and len(group) != 0:
        if "Not defined" in group:
            query.append({"$or":
                [
                    {"properties.sample_info.summary.group": None},
                    {"properties.sample_info.summary.group": {"$in": group}},
                    {"properties.sample_info.summary.group": {"$exists": False}}
                ]
            })
        else:
            query.append(
                {"properties.sample_info.summary.group": {"$in": group}})

    if pagination is not None:
        p_limit = pagination['page_size']
        p_skip = pagination['page_size'] * pagination['current_page']
    else:
        p_limit = 1000
        p_skip = 0

    skip_limit_steps = [
        {"$skip": p_skip}, {"$limit": p_limit}
    ]

    qc_query = filter_qc(qc_list)

    if len(query) == 0:
        if qc_query is None:
            match_query = {}
        else:
            match_query = qc_query["$match"]
    else:
        if qc_query is None:
            match_query = {"$and": query}
        else:
            match_query = {"$and": query + qc_query["$match"]["$and"]}
    query_result = list(db.samples.find(
        match_query, projection).sort([('name', pymongo.ASCENDING)]).skip(p_skip).limit(p_limit))

    return query_result

def get_species_QC_values(ncbi_species):
    connection = get_connection()
    db = connection.get_database('bifrost_species')
    species = db.species.find_one({"ncbi_species": ncbi_species}, {
                        "min_length": 1, "max_length": 1})
    if species is not None:
        return species
    species = db.species.find_one({"organism": ncbi_species}, {
        "min_length": 1, "max_length": 1})
    if species is not None:
        return species
    species = db.species.find_one({"group": ncbi_species}, {
        "min_length": 1, "max_length": 1})
    if species is not None:
        return species
    species = db.species.find_one({"organism": "default"}, {
        "min_length": 1, "max_length": 1})
    return species


# Dictionary and counter in Python to find winner of election

print("======== Counter + Sorted + Slicing ========")
from collections import Counter

def winner(input):
    votes = Counter(input)

    dic = {}
    # output : {4: [], 2: [], 3: []}
    for value in votes.values():
        dic[value] = []

    # output : {4: ['john', 'johnny'], 2: ['jackie'], 3: ['jamie']}
    for key,value in votes.items():
        dic[value].append(key)

    # outout: [4, 3, 2]
    # output : 4
    maxvote = sorted(dic.keys(), reverse=True)[0]

    # check if more than 1 candidates have same
    # number of votes. If yes, then sort the list
    # first and print first element
    if len(dic[maxvote]) > 1:
        print(sorted(dic[maxvote])[0])
    else:
        print(dic[maxvote][0])

input = ['john','johnny','jackie','johnny',
            'john','jackie','jamie','jamie',
            'john','johnny','jamie','johnny',
            'john']
winner(input)

print('\n====== shorter method using counter + max + list comp =======')
from collections import Counter

votes = ['john','johnny','jackie','johnny',
            'john','jackie','jamie','jamie',
            'john','johnny','jamie','johnny',
            'john']

# output: Counter({'john': 4, 'johnny': 4, 'jamie': 3, 'jackie': 2})
votes_count =  Counter(votes)

# output : 4
max_vote = max(votes_count.values())
# output : ['john', 'johnny']
lst = [ k for k,v in votes_count.items() if v == max_vote ]

# output: John
print(sorted(lst)[0])


from django.urls import path
from . import views

app_name = 'pages'

urlpatterns = [
    path('', views.index, name='index'),
    path('fare/', views.fare, name='fare'),
    path('about-us/', views.about, name='aboutus'),
    path('contact-us/', views.contactus, name='contactus'),
    path('complaints/', views.complaints, name='complaints'),
]


import sqlalchemy
from sqlalchemy.ext.declarative import declarative_base

#Crear engine

engine = sqlalchemy.create_engine("sqlite:///slangs2.db")

Base = declarative_base()

#Crear diccionario

class Diccionario(Base):
   __tablename__ = "diccionario"
   id = sqlalchemy.Column(sqlalchemy.Integer, primary_key=True)
   palabra = sqlalchemy.Column(sqlalchemy.String(length=100))
   significado = sqlalchemy.Column(sqlalchemy.String(length=100))

Base.metadata.create_all(engine)

#Crear y empezar la sesión

Session = sqlalchemy.orm.sessionmaker()
Session.configure(bind=engine)
session = Session()

#Funciones

def addSlang(palabra, significado):
    slang = Diccionario(palabra=palabra, significado=significado)
    session.add(slang)
    session.commit()

def editSlang(palabra, nuevo_significado):
    session.query(Diccionario).filter(
        Diccionario.palabra==palabra
    ).update({
        Diccionario.palabra: palabra,
        Diccionario.significado: nuevo_significado
    })
    session.commit()

def delSlang(palabra):
    session.query(Diccionario).filter(Diccionario.palabra == palabra).delete()
    session.commit()

def get_slangs():
    return session.query(Diccionario).all()

def buscar_def(palabra):
    return session.query(Diccionario).filter_by(palabra=palabra)

#Función principal de menú

def menu():
    menu = """
1) Agregar nuevo slang
2) Editar slang
3) Eliminar palabra existente
4) Ver diccionario
5) Buscar definición
6) Salir
Selecciona una opción: """

    opt = ""
    while opt != "6":   #Mientras el usuario no escoja 6 para salir, se mostrará el menú
        opt = input(menu)
        if opt == "1":  #Buscar si existe el slang ingresado y agregarlo si no
            palabra = input("\nIngrese un slang: ")
            posible_significado = buscar_def(palabra).count()
            if posible_significado > 0:
                print(f"El slang '{palabra}' ya existe")
            else:
                significado = input("Ingrese el significado: ")
                addSlang(palabra, significado)
                print("¡Slang agregado con éxito!")
        if opt == "2":  #Buscar el slang que se quiere editar y cambiar su significado, si no existe, te da la opción de agregarlo
            palabra = input("\n¿Qué slang desea editar?: ")
            posible_significado = buscar_def(palabra).count()
            if posible_significado > 0:
                nuevo_significado = input("Ingrese el nuevo significado: ")
                editSlang(palabra, nuevo_significado)
                print("¡Slang actualizado exitosamente!")
            else:
                yn=input(f"El slang '{palabra}' no existe. ¿Deseas agregarlo? Y/N: ")
                if yn == 'Y' or yn == 'y':
                    significado = input("Ingrese el significado: ")
                    addSlang(palabra, significado)
                    print("¡Slang agregado con éxito!")
                else:
                    continue
        if opt == "3":  #Eliminar un slang
            palabra = input("\n¿Qué slang desea eliminar?: ")
            delSlang(palabra)
        if opt == "4":  #Mostrar todos los slangs y sus definiciones usando un ciclo for
            palabras = get_slangs()
            print("\n--------Diccionario de Slangs--------\n")
            for palabra in palabras:
                print(palabra.palabra + ": " + palabra.significado)
        if opt == "5":  #Mostrar el significado del slang escogido, si no existe, te da la opción de agregarlo
            palabra = input(
                "\n¿Qué significado deseas saber?: ")
            significado = buscar_def(palabra)
            if significado.count() > 0:
                print(f"El significado de '{palabra}' es:\n{significado[0].significado}")
            else:
                yn=input(f"El slang '{palabra}' no existe. ¿Deseas agregarlo? Y/N: ")
                if yn == 'Y' or yn == 'y':
                    significado = input("Ingrese el significado: ")
                    addSlang(palabra, significado)
                    print("¡Slang agregado con éxito!")
                else:
                    continue

#Inicialización del programa

if __name__ == '__main__':
    menu()


from django.core.exceptions import ValidationError
from django.db import transaction
from rest_framework import exceptions, status, viewsets
from rest_framework.decorators import action
from rest_framework.response import Response

from ESSArch_Core.ip.models import Agent, InformationPackage
from ESSArch_Core.ip.permissions import CanLockSA
from ESSArch_Core.profiles.models import SubmissionAgreement, Profile, ProfileSA
from ESSArch_Core.profiles.serializers import ProfileSerializer, ProfileSASerializer, SubmissionAgreementSerializer
from ESSArch_Core.profiles.views import (
    ProfileViewSet as ProfileViewSetCore,
    SubmissionAgreementViewSet as SAViewSetCore,
)

class SubmissionAgreementViewSet(SAViewSetCore):
    @action(detail=True, methods=['post'], url_path='include-type')
    def include_type(self, request, pk=None):
        sa = SubmissionAgreement.objects.get(pk=pk)
        ptype = request.data["type"]

        setattr(sa, "include_profile_%s" % ptype, True)
        sa.save()

        return Response({
            'status': 'Including profile type %s in SA %s' % (ptype, sa)
        })

    @action(detail=True, methods=['post'], url_path='exclude-type')
    def exclude_type(self, request, pk=None):
        sa = SubmissionAgreement.objects.get(pk=pk)
        ptype = request.data["type"]

        setattr(sa, "include_profile_%s" % ptype, False)
        sa.save()

        return Response({
            'status': 'Excluding profile type %s in SA %s' % (ptype, sa)
        })

    @action(detail=True, methods=['post'])
    def save(self, request, pk=None):
        if not request.user.has_perm('profiles.create_new_sa_generation'):
            raise exceptions.PermissionDenied

        sa = self.get_object()

        try:
            new_name = request.data["new_name"]
        except KeyError:
            new_name = ''

        if not new_name:
            return Response(
                {'status': 'No name specified'},
                status=status.HTTP_400_BAD_REQUEST
            )

        new_data = request.data.get("data", {})

        changed_data = False

        for field in sa.template:
            if field.get('templateOptions', {}).get('required', False):
                if not new_data.get(field['key'], None):
                    return Response(
                        {"status': 'missing required field '%s'" % field['key']},
                        status=status.HTTP_400_BAD_REQUEST
                    )

        for k, v in new_data.items():
            if v != getattr(sa, k):
                changed_data = True
                break

        if not changed_data:
            return Response({'status': 'no changes, not saving'}, status=status.HTTP_400_BAD_REQUEST)

        new_sa = sa.copy(new_data=new_data, new_name=new_name,)
        serializer = SubmissionAgreementSerializer(
            new_sa, context={'request': request}
        )
        return Response(serializer.data)

    def get_profile_types(self):
        return 'sip', 'transfer_project', 'submit_description', 'preservation_metadata'

    @transaction.atomic
    @action(detail=True, methods=["post"])
    def lock(self, request, pk=None):
        sa = self.get_object()
        ip_id = request.data.get("ip")
        permission = CanLockSA()

        try:
            ip = InformationPackage.objects.get(pk=ip_id)
        except InformationPackage.DoesNotExist:
            raise exceptions.ParseError('Information Package with id %s does not exist')

        if ip.submission_agreement_locked:
            raise exceptions.ParseError('IP already has a locked SA')

        if not permission.has_object_permission(request, self, ip):
            self.permission_denied(request, message=getattr(permission, 'message', None))

        if ip.submission_agreement != sa:
            raise exceptions.ParseError('This SA is not connected to the selected IP')

        ip.submission_agreement_locked = True
        if sa.archivist_organization:
            existing_agents_with_notes = Agent.objects.all().with_notes([])
            ao_agent, _ = Agent.objects.get_or_create(
                role='ARCHIVIST', type='ORGANIZATION',
                name=sa.archivist_organization, pk__in=existing_agents_with_notes
            )
            ip.agents.add(ao_agent)
        ip.save()

        ip.create_profile_rels(self.get_profile_types(), request.user)
        return Response({'status': 'Locked submission agreement'})

class ProfileSAViewSet(viewsets.ModelViewSet):
    queryset = ProfileSA.objects.all()
    serializer_class = ProfileSASerializer

class ProfileViewSet(ProfileViewSetCore):
    @action(detail=True, methods=['post'])
    def save(self, request, pk=None):
        profile = Profile.objects.get(pk=pk)
        new_data = request.data.get("specification_data", {})
        new_structure = request.data.get("structure", {})

        changed_data = (profile.specification_data.keys().sort() == new_data.keys().sort() and
                        profile.specification_data != new_data)

        changed_structure = profile.structure != new_structure

        if (changed_data or changed_structure):
            try:
                new_profile = profile.copy(
                    specification_data=new_data,
                    new_name=request.data["new_name"],
                    structure=new_structure,
                )
            except ValidationError as e:
                raise exceptions.ParseError(e)

            serializer = ProfileSerializer(
                new_profile, context={'request': request}
            )
            return Response(serializer.data)

        return Response({'status': 'no changes, not saving'}, status=status.HTTP_400_BAD_REQUEST)


import os
import numpy as np
import pandas as pd

from tqdm import *

def label2csv(input_file, output_file, labels_file, train_dir):

    with open(labels_file, 'r', encoding='utf-8') as f:
        labels = f.readlines()
    labels = [a.strip() for a in labels]
    n_labels = len(labels)

    with open(input_file, 'r', encoding='utf-8') as f:
        samples = f.readlines()

    data = []
    for sample in samples:
        sample_items = sample.strip().split('\t')
        sample_labels = sample_items[3:]
        label = [0] * n_labels

        for sample_label in sample_labels:
            if sample_label in labels:
                label[labels.index(sample_label)] = 1

        if sum(label) > 0:
            sample_prefix = sample_items[:3]
            sample_prefix.insert(1, train_dir)
            sample_items = sample_prefix + label
            data.append(sample_items)

    columns = ['file', 'ecg_dir', 'age', 'sex'] + labels
    df = pd.DataFrame(data=data, columns=columns)
    df.to_csv(output_file, index=False)
    return

def merge_round1_train_testA(train_csv, testA_csv, output_csv):
    train_df = pd.read_csv(train_csv)
    testA_df = pd.read_csv(testA_csv)

    columns = train_df.columns.tolist()
    train_list = train_df.values.tolist()
    testA_list = testA_df.values.tolist()
    train_files = [tl[0] for tl in train_list]

    for testA_item in testA_list:
        if testA_item[0] not in train_files:
            train_list.append(testA_item)

    train_testA_df = pd.DataFrame(data=train_list, columns=columns)
    train_testA_df.to_csv(output_csv, index=False)
    return

def remove_round1_duplicates(train_testA_csv, output_csv):

    def load_ecg(ecg_path):
        with open(ecg_path, 'r') as f:
            ecg = f.readlines()
        return ecg

    train_testA_df = pd.read_csv(train_testA_csv)
    columns = train_testA_df.columns.tolist()
    labels = train_testA_df.values.tolist()
    IDs = [label[0] for label in labels]

    print('Loading ECG ...')
    ecgs = []
    for label in tqdm(labels, ncols=75):
        ecgs.append(load_ecg(os.path.join(label[1], label[0])))

    print('Removing duplicates ...')
    duplicates, count = [], 0
    for i in tqdm(range(len(IDs)), ncols=75):
        if IDs[i] in duplicates:
            continue

        ecg1 = ecgs[i]
        for j in range(i + 1, len(IDs)):
            ecg2 = ecgs[j]
            if ecg1 == ecg2:
                if IDs[j] not in duplicates:
                    count += 1
                    duplicates.append(IDs[j])

    rm_dup_labels = []
    for label in labels:
        if label[0] not in duplicates:
            rm_dup_labels.append(label)

    rm_dup_df = pd.DataFrame(data=rm_dup_labels, columns=columns)
    rm_dup_df.to_csv(output_csv, index=False)
    return

def generate_sample_weights(round1_csv, round2_csv, round1_output_csv, round2_output_csv):

    round1 = pd.read_csv(round1_csv)
    round2 = pd.read_csv(round2_csv)
    round1_labels = round1.iloc[:, 4:]
    round2_labels = round2.iloc[:, 4:]

    round1_freq = round1_labels.sum() / len(round1_labels)
    round2_freq = round2_labels.sum() / len(round2_labels)
    round2_vs_round1 = round2_freq / round1_freq
    round1_labels_weights = round1_labels * round2_vs_round1

    round1_sample_weights = []
    for i, row in round1_labels_weights.iterrows():
        row_list = row.tolist()
        row_list = [item for item in row_list if item != 0.0]
        sample_weight = np.prod(row_list)
        round1_sample_weights.append(sample_weight)

    round1_sample_weights = np.array(round1_sample_weights)
    round1_sample_weights[round1_sample_weights > 1] = 1
    round1_sample_weights[round1_sample_weights < 0.3] = 0
    round1.insert(1, 'sample_weight', round1_sample_weights)
    drop_idxs = round1.loc[round1['sample_weight'] == 0.0].index.tolist()
    round1.drop(index=drop_idxs, inplace=True)

    round2_sample_weights = [1] * len(round2)
    round2.insert(1, 'sample_weight', round2_sample_weights)

    round1.to_csv(round1_output_csv, index=False)
    round2.to_csv(round2_output_csv, index=False)
    return

def main(args):

    print('=' * 100)
    print('Preprocessing on train set')
    print('-' * 100)

    round1_testA_dir = os.path.join(args.input_dir, 'hf_round1_testA')
    round1_train_dir = os.path.join(args.input_dir, 'hf_round1_train')
    round2_train_dir = os.path.join(args.input_dir, 'hf_round2_train')

    round1_testA_txt = os.path.join(args.input_dir, 'hefei_round1_ansA_20191008.txt')
    round1_train_txt = os.path.join(args.input_dir, 'hf_round1_label.txt')
    round2_train_txt = os.path.join(args.input_dir, 'hf_round2_train.txt')

    # round1_arrythmia_txt = os.path.join(args.input_dir, 'hf_round1_arrythmia.txt')
    round2_arrythmia_txt = os.path.join(args.input_dir, 'hf_round2_arrythmia.txt')

    # -1- Convert labels of dataset to csv
    print('-1- Convert labels of dataset to csv')
    round1_testA_csv = os.path.join(args.output_dir, 'round1_testA.csv')
    label2csv(round1_testA_txt, round1_testA_csv, round2_arrythmia_txt, round1_testA_dir)
    round1_train_csv = os.path.join(args.output_dir, 'round1_train.csv')
    label2csv(round1_train_txt, round1_train_csv, round2_arrythmia_txt, round1_train_dir)
    round2_train_csv = os.path.join(args.output_dir, 'round2_train.csv')
    label2csv(round2_train_txt, round2_train_csv, round2_arrythmia_txt, round2_train_dir)

    # -2- Merge train and testA of Round1
    print('-2- Merge train and testA of Round1')
    round1_merge_csv = os.path.join(args.output_dir, 'round1_merge.csv')
    merge_round1_train_testA(round1_train_csv, round1_testA_csv, round1_merge_csv)

    # -3- Remove duplicates in train and testA
    print('-3- Remove duplicates in train and testA of Round1')
    round1_merge_noDup_csv = os.path.join(args.output_dir, 'round1_merge_noDup.csv')
    remove_round1_duplicates(round1_merge_csv, round1_merge_noDup_csv)

    # -4- Generate sample weights for sampling
    print('-4- Generate sample weights for sampling')
    round1_sample_weights_csv = os.path.join(args.output_dir, 'round1_merge_noDup_weighted.csv')
    round2_sample_weights_csv = os.path.join(args.output_dir, 'round2_train_weighted.csv')
    generate_sample_weights(round1_merge_noDup_csv, round2_train_csv,
                            round1_sample_weights_csv, round2_sample_weights_csv)

    print('=' * 100, '\n')
    return

if __name__ == '__main__':
    import warnings
    import argparse

    warnings.filterwarnings('ignore')
    parser = argparse.ArgumentParser(
        description='HFECG Competition -Round 2- Preprocessing Pipeline'
    )

    parser.add_argument('--input-dir', '-i', type=str,
                        action='store', dest='input_dir',
                        help='Directory of input data')
    parser.add_argument('--output-dir', '-o', type=str,
                        action='store', dest='output_dir',
                        help='Directory to save preprocessed data')

    args = parser.parse_args()
    main(args)


from datetime import datetime
from django.contrib import messages
from django.contrib.auth import get_user_model
from django.db.models import F, Subquery, Count, Q
from django.http.response import JsonResponse
from django.shortcuts import render, get_object_or_404, redirect
from django.contrib.auth.decorators import login_required
from django.views.decorators.http import require_POST

from game.models import (
    Challenge,
    ChallengeFlag,
    Game,
    UserChallengeRecord,
    UserParticipateGame,
)

from core.models import ScoreHistory, User

def populate_game_challenges(game, user_id):
    challenges = tuple(
        Challenge.objects.filter(game=game)
        .prefetch_related("flags")
        .annotate(
            docker_image=F("docker__docker"),
            url=F("docker__url"),
        )
    )

    # find all cleared flags
    user_records = UserChallengeRecord.objects.filter(
        challenge__in=challenges, participated_user__user_id=user_id
    )
    flags = []
    count_answered = 0
    for c in challenges:
        for flag in c.flags.all():
            # find if user already answer the flag
            flag.status = "Not Solved " + "\u2715"
            flag.answered = False
            for record in user_records:
                if record.challenge_flag_id == flag.id:
                    flag.status = "Solved " + "\u2713"
                    flag.answered = True
                    flag.points_gained = record.points_gained
                    count_answered += 1
                    break
            flags.append(flag)

    return {
        "game": game,
        "challenges": challenges,
        "flags": flags,
        "count_answered": count_answered,
    }

def update_score_process(game, flag, user_id, username):
    already_answered = UserChallengeRecord.objects.filter(
        participated_user__user_id=user_id,
        participated_user__game=game,
        challenge_flag=flag,
    ).exists()

    if already_answered:
        return {"message": "ตอบ flag นี้ไปแล้ว", "correct": False}
    else:
        points_gained = flag.point

        try:
            if game.period:
                remaingin_time = game.period.get_remaining_time_percentage()
                points_gained = round(points_gained * remaingin_time)
        except Game.period.RelatedObjectDoesNotExist:
            pass

        participation = UserParticipateGame.objects.filter(user=user_id, game=game)
        user_challenges_record = UserChallengeRecord(
            participated_user_id=Subquery(participation.values("id")),
            challenge=flag.challenge,
            challenge_flag=flag,
            points_gained=points_gained,
        )
        user_challenges_record.save()

        # add score
        participation.update(game_score=F("game_score") + points_gained)
        ScoreHistory.objects.create(
            gained=points_gained,
            type="challenge",
            object_id=flag.id,
            group_id=game.id,
            user_id=user_id,
        )

        return {
            "message": "ถูกต้อง",
            "correct": True,
            "points_gained": points_gained,
            "answered_at": user_challenges_record.answered_at,
            "flagid": user_challenges_record.challenge_flag_id,
        }

def get_top10_score(game_id):
    top10 = UserParticipateGame.objects.filter(game_id=game_id).values_list("id")[:10]
    unique_user = (
        UserParticipateGame.objects.filter(game_id=game_id)
        .extra(select={"points_gained": 0})
        .annotate(answered_at=F("participate_at"), username=F("user__username"))
    )

    score = (
        UserChallengeRecord.objects.filter(participated_user_id__in=top10)
        .values(
            "points_gained",
            "answered_at",
            username=F("participated_user__user__username"),
        )
        .union(unique_user)
        .order_by("answered_at")
    )

    return tuple(score)

def index(request):
    now = datetime.now()
    games = Game.objects.select_related("period").filter(is_archive=False)
    context = {"games": games}
    return render(request, "game/index.html", context)

@login_required
def game_view(request, game_slug):
    game = get_object_or_404(Game.objects.select_related("period"), slug=game_slug)

    try:
        remaining_time = game.period.get_remaining_time_percentage()
        if remaining_time > 1:
            messages.warning(request, "ยังไม่ถึงเวลาเริ่มเกม")
            return redirect("game_index")
        game.participants.add(request.user)
    except Game.period.RelatedObjectDoesNotExist:
        # no periods game always ongoning
        game.period = None
        game.participants.add(request.user)

    context = populate_game_challenges(game, request.user.id)
    return render(request, "game/game.html", context)

@login_required
@require_POST
def enter_challenge_flag(request, game_id):
    game = get_object_or_404(Game.objects.select_related("period"), id=game_id)

    try:
        # check if game has period and started yet...
        if not game.period.is_game_start():
            return JsonResponse({"message": "เกมยังไม่เริ่ม", "correct": False})
    except Game.period.RelatedObjectDoesNotExist:
        # no periods game always ongoning
        game.period = None

    try:
        right_flag = ChallengeFlag.objects.select_related("challenge").get(
            flag__iexact=request.POST.get("flag", "").strip(),
            challenge__game_id=game_id,
        )
        result = update_score_process(
            game, right_flag, request.user.id, request.user.username
        )
        return JsonResponse(result)

    except ChallengeFlag.DoesNotExist:
        return JsonResponse({"message": "ผิด", "correct": False})

@login_required
def get_current_top10_score(request, game_id):
    scores = get_top10_score(game_id)
    return JsonResponse({"data": scores})


import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import seaborn as sns

sns.set(style="whitegrid")
sns.set_context("paper", font_scale=1.5)

# read entire results
data = pd.read_csv("../CSV/jmh-result.csv")

# filter Benchmarks
data = data.loc[data['Benchmark'].str.contains("OneShot")]

# names are long like absda.asddsa.casdas.yield -> filter to yield
data['Benchmark'] = data['Benchmark'].apply(lambda x: x.split(".")[-1])

# round relevant cols to ints
cols = ['Param: paramCount', 'Param: stackDepth', 'Score']
data[cols] = data[cols].applymap(np.int64)

g = sns.catplot(x="Param: paramCount", y="Score", hue="Benchmark", data=data,
                hue_order=["noYield", "yield", "yieldThenContinue", "yieldAfterEachCall", "yieldBeforeEachCall",
                           "yieldBeforeAndAfterEachCall"],
                col="Param: stackDepth", col_wrap=4, kind="bar", sharey=False, legend=False)

g.despine(left=True)
g.set_ylabels("Time in nanoseconds")
g.set_xlabels("paramCount")
g.set_titles("stackDepth: {col_name}")

plt.legend(loc='center left', bbox_to_anchor=(1.01, 0.5), frameon=False)

# plt.show()

plot_folder = "../Plots/"
plt.savefig(plot_folder + "OneShot-stackDepths-as-columns.png", bbox_inches='tight')


import requests

from text2speech.modules import RemoteTTS, TTSValidator

class MaryTTS(RemoteTTS):
    PARAMS = {
        'INPUT_TYPE': 'TEXT',
        'AUDIO': 'WAVE_FILE',
        'OUTPUT_TYPE': 'AUDIO'
    }

    def __init__(self, config=None):
        config = config or {"lang": "en-us",
                            "url": "http://mary.dfki.de:59125/",
                            "voice": 'cmu-bdl-hsmm'
                            }
        super(MaryTTS, self).__init__(config, api_path='/process',
                                      validator=MaryTTSValidator(self))

        if self.lang.lower() in ["en-uk", "en-gb"]:
            self.lang = "en_GB"
        elif self.lang.lower().startswith("en"):
            self.lang = "en_US"

    def build_request_params(self, sentence):
        params = self.PARAMS.copy()
        params['LOCALE'] = self.lang
        params['VOICE'] = self.voice
        params['INPUT_TEXT'] = sentence.encode('utf-8')
        return params

    def describe_voices(self):
        voices = {}
        locales = requests.get(self.url + "/locales").text.split()
        for l in locales:
            voices[l] = []
        voice_data = requests.get(self.url + "/voices").text.split("\n")
        for v in voice_data:
            if not v.strip():
                continue
            voice, lang_code, gender = v.split()[:3]
            voices[lang_code] += [voice]
        return voices

class MaryTTSValidator(TTSValidator):
    def __init__(self, tts):
        super(MaryTTSValidator, self).__init__(tts)

    def validate_connection(self):
        try:
            resp = requests.get(self.tts.url + "/version", verify=False)
            if not resp.text.startswith("Mary TTS server"):
                raise Exception('Invalid MaryTTS server.')
        except:
            raise Exception(
                'MaryTTS server could not be verified. Check your connection '
                'to the server: ' + self.tts.url)

    def get_tts_class(self):
        return MaryTTS


# This code is written to extract electronic band structure data from V.A.S.P. calculation results.

import codecs
import re
import linecache  # 这个模块非常适合根据给出的行号， 从文本文件中读取指定行的数据
import numpy as np

class vasp:
    def __init__(self):
        self.name = vasp

    ##############################################################################################################
    # 一些通用函数

    # 这个函数利用linecache模块，可以从数据文件中读出指定行的信息，并以字符串形式返回
    # 应注意，这个函数的行数从1开始，即line_index=5指要读文件中的第五行
    def GrepLineContent(self,file,line_index):
        return linecache.getline(file,line_index).strip()

    # 此函数可将费米面调整为零，适用于energy为列表，一维数据，二维数组以及矩阵形式的数据的情况
    # 若输入的energy是一维数组或列表，对应于能量值是一维序列的情况，应用于调整态密度DOS的自变量
    # 若输入的energy是嵌套列表，二维数组或矩阵，对应于能量是二维能量面的情况，应用于调整能带图bands的高度
    def ShiftFermiSurface(self, energy, fermi_energy):
        energy_array = np.array(energy)  # 将输入转换为数组，确保下一步计算中的输入是数组（一维或二维）形式的数据
        return energy_array-fermi_energy

    ##############################################################################################################
    # 态密度（DOS）提取模块

    # This function is designed to read out DOS data from DOSCAR
    def ReadDOSCAR(self, DOSCAR):
        file = codecs.open(DOSCAR, 'rb', 'utf-8', 'ignore')  # Open file, using codecs to uniform coding type
        line = file.readline()
        lindex = 0  # line index
        data = []  # DOS数据
        while line:
            if lindex <= 4:
                pass  # The first five lines not terribly useful
            else:
                value = line.split()  # 以空字符（空格，换行'\n'，制表符'\t'等）为分隔符对字符串做切片 （什么都不填默认为空字符）
                value = list(map(float, value))
                data.append(value)

            line = file.readline()
            lindex += 1
        file.close()

        npoints = int(data[0][2])  # number of gridpoints on which the DOS is evaluated

        separated_data = []  # 分隔后的数据总集
        nrows = npoints + 1  # number of line in one data subset (一个数据子集的行数)
        nsubset = int(len(data) / nrows)  # number of data subsets (数据子集的个数)
        for i in range(nsubset):
            data_subset = []  # 数据子集，每次循环开始重新定义成空列表
            for j in range(nrows):
                data_subset.append(data[i * nrows + j])  # i标定了数据子集的序号，j标定了在这个子集中数据行的序号
            separated_data.append(data_subset)  # 将子集补充到分隔后的数据总集当中

        return separated_data

    # 利用ReadDOSCAR函数整理出态密度(DOS)
    def GetData(self, DOSCAR, spin_polarized='False'):
        data = self.ReadDOSCAR(DOSCAR)[0]  # 非投影的态密度在第一个子集当中
        npoints = int(data[0][2])  # number of gridpoints on which the DOS is evaluated
        Efermi = float(data[0][3])  # The Fermi energy

        if spin_polarized == 'False':
            key = ['energy', 'DOS', 'integrated DOS']
        else:
            key = ['energy', 'DOS-spin up', 'DOS-spin down', 'integrated DOS-spin up', 'intergrated DOS-spin down']
        DOS = dict.fromkeys(key)  # 根据列表key中的键生成DOS字典，对应键值为None
        for n in key:
            DOS[n] = []  # 将所以列表key中对于的键值改为空列表，用于存放数据
        DOS.update({'number': npoints, 'Efermi': Efermi})  # 将计算的能量点的个数跟费米能更新到DOS字典当中

        for i in range(len(data)):
            if i == 0:  # The first line is parameters (第一行都是参数)
                pass
            else:
                for j in key:
                    DOS[j].append(data[i][key.index(j)])  # key.index(j) - 利用j在列表key中的位置来分配对应数据到字典DOS中

        return DOS

    # 利用ReadDOSCAR函数整理出投影态密度(projected DOS)
    def GetProjectedData(self, DOSCAR, **kwargs):
        data_total = self.ReadDOSCAR(DOSCAR)
        natom = len(data_total) - 1  # 各个原子的态密度会分得一个子集，总DOS会分得一个子集，所以子集总数减1即为原子总数

        spin = kwargs['spin_polarized'] if 'spin_polarized' in kwargs else 'False'
        lm_decomposed = kwargs['lm_decomposed'] if 'lm_decomposed' in kwargs else 'False'
        # decomposition of azimuthal quantum number (角量子数) l and magnetic quantum number (磁量子数) m

        if spin == 'False':
            if lm_decomposed == 'False':
                key = ['energy', 's', 'p', 'd']  # s, p, d indicate the atomic orbital
            else:
                key = ['energy', 's', 'p_{y}', 'p_{z}', 'p_{x}', 'd_{xy}', 'd_{yz}', 'd_{z^2}', 'd_{xz}',
                           'd_{x^2-y^2}']
        else:
            key = ['energy', 's-spin up', 's-spin down', 'p-spin up', 'p-spin down', 'd-spin up', 'd-spin down']

        atom_list = kwargs['atom_list'] if 'atom_list' in kwargs else ['atom'+str(n+1) for n in range(natom)]
        # 如无指定，则根据原子个数生成原子名称

        DOS_projected = dict.fromkeys(atom_list)  # 根据atom_list创建一个字典，每个atom对应得键值都是一个空字典
        for i in atom_list:
            DOS_projected[i] = dict.fromkeys(key)
            for j in key:
                DOS_projected[i][j] = []  # 将对应原子中的对应键的值改为空列表，用于存放数据

        nrow_subset = len(data_total[0])  # 一个数据子集的行数
        for i in atom_list:
            subset_index = atom_list.index(i) + 1  # 由于总数据的第一个子集是总态密度，所以atom_list.index(i)要加1，即从第二个子集读起
            data_subset = data_total[subset_index]
            for j in range(nrow_subset):  # j标示着读这个数据子集的具体行数
                if j == 0:  # The first line is parameters (第一行都是参数)
                    pass
                else:
                    for k in key:
                        key_index = key.index(k)  # key.index(k) - 利用k在列表key中的位置来分配对应数据到字典中的具体位置
                        DOS_projected[i][k].append(data_subset[j][key_index])

        return DOS_projected

    ##############################################################################################################
    # 能带提取模块
    # This function is designed to extract electronic bands data from file EIGENVAL.
    def GetEbands(self,EIGENVAL):
        pattern_int = re.compile(r'-?\d+')  # 匹配整数，用于提取参数
        # pattern_float = re.compile(r'-?\d+\.\d+?[Ee]?-?\d+')  # 匹配可能有科学计数法的浮点数的正则表达式, 用于提取数据

        # 提取能带计算时的一些全局参数
        parameter_string = self.GrepLineContent(EIGENVAL,6)
        parameter = pattern_int.findall(parameter_string)  # 利用正则表达式提取出这一行所有的整数
        num_valence_electrons, num_kpoints, num_bands = parameter
        # 这行第一个数为价电子总数，第二个为k点路径总点数，第三个为能带总数
        num_valence_electrons = int(num_valence_electrons)  # 从文件中读取完的数据形式为字符串，需要转换为整型才能进行后续处理
        num_kpoints = int(num_kpoints)
        num_bands = int(num_bands)

        # 通过循环读取EIGENVAL中的数据
        file = codecs.open(EIGENVAL,'rb','utf-8','ignore')  # Open file, using codecs to uniform coding type
        line = file.readline()
        line_index = 1  # 读取文件时，为了方便，我们设定从一开始，那么line_index=1指文件的第一行
        raw_data = []   # 存放原始数据的列表
        while line:
            if line_index >= 7:  # 为了方便后续的编程跟数据处理，我们从EIGENVAL的第7行开始读
                value = line.split()  # 以空字符（空格，换行'\n'，制表符'\t'等）为分隔符对字符串做切片 （什么都不填默认为空字符）
                value = list(map(float,value))
                raw_data.append(value)

            line = file.readline()
            line_index += 1
        file.close()

        bands = np.zeros((num_bands,num_kpoints))        # 定义一个num_bands行num_kpoints列的矩阵用于存放能带数据
        occupation = np.zeros((num_bands, num_kpoints))  # 同理，定义一个矩阵存放电子占据数据，此矩阵跟能带矩阵具有相同的维度

        # 在EIGENVAL中，数据会按照K点路径顺序排布，每个K点的能带数据可以看作一个循环，那么我们便可以通过不断loop循环来将数据进行分类整理
        nrows_cycle = num_bands+2   # 每个循环的数据行数为：能带数+K点坐标行+空白分割行 = 能带数+2行
        Kpath, Kweight = [[],[]]  # 批量定义空列表准备储存数据，k_path是K点路径，k_weight是K点对应的权重
        for i in range(num_kpoints):
            # 确定各个数据对应的列表引索
            Kindex, band_data_starting = [i*nrows_cycle+1, i*nrows_cycle+2]
            Kpath.append([raw_data[Kindex][0],raw_data[Kindex][1],raw_data[Kindex][2]])  # K点路径
            Kweight.append(raw_data[Kindex][3])
            # 通过循环将能带数据赋值到刚刚创建的矩阵中
            for j in range(num_bands):
                bands[j,i] = raw_data[band_data_starting+j][1]
                occupation[j,i] = raw_data[band_data_starting+j][2]

        data_dict = {'num_kpoints': num_kpoints,          # K点路径上的取点数
                     'num_bands': num_bands,              # 能带数目
                     'Kpath': Kpath,                    # K点路径
                     'Kweight': Kweight,                # 每个K点对应的权重
                     'bands': np.array(bands),            # 能带数据（最后的输出为二维数组的话，操作空间会更大）
                     'occupation': np.array(occupation)}  # 轨道（能带）占据情况}

        return data_dict

    ###############################################################################################################
    # 能带分析模块
    # 这个模块的功能包括但不限于从静态自洽计算（SCF）结果中获取费米能级，或者通过能带占据情况确定费米能级位置
    # 以及计算禁带宽度，判断其为直接还是间接带隙等等

    # 此函数可以直接从SCF计算中得到的OUTCAR文件中读取费米能级
    def GetFermiEnergy(self,OUTCAR):
        return

    # 若使用MajestyV的脚本计算电子能带，SCF计算结果中通常会生成一个总结文件Markdown_SCF，其中记载着准确的费米能级（没有分数占据的情况下）
    # MajestyV的github：https://github.com/MajestyV
    # 此函数可以从Markdown文件中提取费米能级的计算结果
    def GetFermiEnergy_Markdown(self, Markdown_SCF):
        pattern = re.compile(r'-?\d+\.?\d+')  # 匹配浮点数的正则表达式
        file = codecs.open(Markdown_SCF, 'rb', 'utf-8', 'ignore')
        line = file.readline()
        energy = pattern.findall(line)
        Efermi = float(energy[0])
        return Efermi

    # 此函数可通过能带占据情况区分导带跟价带，提取能带边缘（带边，band edges）
    # 由于DFT算法本身的原因，会出现分子轨道（能带）被分数电子占据的情况，所以我们使用OrderPrecision控制占据情况的精确度
    # 如OrderPrecision=2，则精确到小数点后两位
    def GetBandEdges(self, EIGENVAL, accuracy_order=0):
        data_dict = self.GetEbands(EIGENVAL)  # 利用GetEbands函数从EIGENVAL文件提取能带数据
        num_bands = data_dict['num_bands']  # 提取能带总数
        num_kpoints = data_dict['num_kpoints']  # 提取K点总数
        bands = data_dict['bands']  # 能带具体的能量值
        occupation = data_dict['occupation']  # 能带的占据情况

        unoccupied = []  # 这个列表用于存放所有未被占据的能带数据
        occupied = []  # 这个列表用于存放所有已被占据的能带数据
        for n in range(num_kpoints):
            energy_unoccupied = []
            energy_occupied = []
            for m in range(num_bands):
                    energy = bands[m,n]
                    filling_condition = occupation[m][n]  # 电子的填充情况
                    if round(filling_condition, accuracy_order) == 0:  # 通过判断能带的占据情况来确定能带在费米面之下还是费米面之上
                        energy_unoccupied.append(energy)  # 0则为未被占据的能带
                    else:
                        energy_occupied.append(energy)    # 1则为被占据的能带
            unoccupied.append(energy_unoccupied)
            occupied.append(energy_occupied)

        conduction_band = [min(unoccupied[i]) for i in range(len(unoccupied))]  # 最低未占据能带（导带），Lowest unoccupied band
        valence_band = [max(occupied[i]) for i in range(len(occupied))]  # 最高已占据能带（价带），Highest occupied band

        return valence_band, conduction_band

    # 此函数通过费米能级的位置区分导带跟价带（如果出现分数电子占据的情况，得到的结果可能不太准确）
    def GetBandEdges_Fermi(self, EIGENVAL, Efermi=0):
        data_dict = self.GetEbands(EIGENVAL)  # 利用GetEbands函数从EIGENVAL文件提取能带数据
        num_bands = data_dict['num_bands']  # 提取能带总数
        num_kpoints = data_dict['num_kpoints']  # 提取K点总数
        bands = data_dict['bands']  # 能带具体的能量值

        unoccupied = []  # 这个列表用于存放所有未被占据的能带数据
        occupied = []  # 这个列表用于存放所有已被占据的能带数据
        for n in range(num_kpoints):
            energy_unoccupied = []
            energy_occupied = []
            for m in range(num_bands):
                energy = bands[m,n]
                if energy >= Efermi:  # 通过能量E是否大于给定的费米能级判断能带在费米面之下还是费米面之上
                    energy_unoccupied.append(energy)
                else:
                    energy_occupied.append(energy)
            unoccupied.append(energy_unoccupied)
            occupied.append(energy_occupied)

        conduction_band = [min(unoccupied[i]) for i in range(len(unoccupied))]  # 最低未占据能带（导带），Lowest unoccupied band
        valence_band = [max(occupied[i]) for i in range(len(occupied))]  # 最高已占据能带（价带），Highest occupied band

        return valence_band, conduction_band

    # 此函数可以计算带隙（Bandgap），同时分析材料是直接带隙还是间接带隙
    def GetBandgap(self, EIGENVAL, **kwargs):
        mode = kwargs['mode'] if 'mode' in kwargs else 'Occupation'  # 默认通过电子占据情况分析带隙
        accuracy_order = kwargs['accuracy_order'] if 'accuracy_order' in kwargs else 0  # 分析电子占据情况时所用的精确度
        Efermi = kwargs['Efermi'] if 'Efermi' in kwargs else 0.0  # 通常不使用此模式，故设Efermi为0

        if mode == 'occupation':
            valence_band, conduction_band = self.GetBandEdges(EIGENVAL, accuracy_order=accuracy_order)
        elif mode == 'Efermi':
            valence_band, conduction_band = self.GetBandEdges_Fermi(EIGENVAL, Efermi=Efermi)
        else:
            print(r'ERROR: The mode of this function could only be "Occupation" or "Efermi".')
            return

        Ev_max = max(valence_band)  # 价带顶
        Ec_min = min(conduction_band)  # 导带底
        Eg = Ec_min - Ev_max  # 带隙

        # 分析价带顶跟导带底的位置
        extremum_location = (valence_band.index(Ev_max), conduction_band.index(Ec_min))

        return Eg, Ev_max, Ec_min, extremum_location

if __name__=='__main__':
    EIGENVAL = 'D:/MaterialsGallery/Testing/MoS2_pawlda/MoS2_2H/1/result/EIGENVAL'
    ebands = vasp()
    # Gamma-M-K-Gamma-A-L-H-A
    a = ebands.GetEbands(EIGENVAL)
    #print(len(a['energy'][0]))
    #print(len(a['occupation'][31]))
    print(a)

    #kpath.GetKpath(saving_directory,path,59)


from django.forms import ModelForm
from product.models import Product
from django import forms

class ProductForm(ModelForm):
    class Meta:
        model = Product
        exclude = ["modified", "created"]

    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        ignore_fields = ["image"]
        for field in self.fields:
            if field in ignore_fields:
                continue
            self.fields[field].widget.attrs.update({
                'class': 'form-control'
            })

class ImportForm(forms.Form):
    excel_field = forms.FileField(label="Excel-Datei")


import praw
import gspread
from oauth2client.service_account import ServiceAccountCredentials
import bmemcached
import re
import time
import os
import json
import threading

ARTIST_COL = 0
ALBUM_COL  = 1
SCORE_COL  = 2

SUBREDDITS = 'fantanoforever+hiphopheads'
COMMAND = re.compile('!fantanobot (.*)', re.IGNORECASE)

URL = 'https://docs.google.com/spreadsheets/d/1GbGyWVtePH8RZCZd7N3RPDh8m-K6hgO6AyKsAHZpbeQ/edit#gid=0'
ACCOUNT = 'fantanobot@fantanobot.iam.gserviceaccount.com'

print('INITIALISING ...')

# Connect to google spreadsheet
scope = ['https://spreadsheets.google.com/feeds', 'https://www.googleapis.com/auth/drive']
credentials = ServiceAccountCredentials.from_json_keyfile_dict(
    json.loads(os.environ['CREDENTIALS']),
    scope
)
gc = gspread.authorize(credentials)
sheet = gc.open_by_url(URL).worksheet('All Reviews')
data = sheet.get_all_values()

# Connect to Memcached DB (stores comment IDs)
db = bmemcached.Client(
    os.environ['MEMCACHEDCLOUD_SERVERS'].split(','),
    os.environ['MEMCACHEDCLOUD_USERNAME'],
    os.environ['MEMCACHEDCLOUD_PASSWORD']
)

FOOTER = (
    "\n\nAll scores sourced from [here]({data_link}).\n\n"
    "---\n"
    "^(I am a bot and this action was performed automatically)  \n"
    "[^Send ^my ^creater ^a ^PM]({pm_link}) ^(to provide feedback)"
).format(data_link = URL, pm_link = "https://www.reddit.com/message/compose/?to=NobleLordOfLaziness")

# Try album then artist
def retrieve(term):
    try:
        regex = re.compile(term, re.IGNORECASE)
    except:
        return None
    print('retrieving album', term, '...')
    response = retrieve_album(regex)
    if response is None:
        print('retrieving artist', term, '...')
        response = retrieve_artist(regex)
    return response

def retrieve_album(album_name):
    global data
    try:
        values = None
        for album in data:
            if album_name.match(album[1]):
                values = album
        assert(values is not None)
        print('success')
        return "Artist: *{artist}*  \nAlbum: {album}  \nScore: **{score}**".format(
            artist = values[ARTIST_COL],
            album  = values[ALBUM_COL],
            score  = values[SCORE_COL]
        )
    except Exception as e:
        print('fail')
        print(e)
        return None

def retrieve_artist(artist_name):
    global data
    try:
        albums = []
        artist = None
        for album in data:
            if artist_name.match(album[ARTIST_COL]):
                albums.append('{album} - **{score}**'.format(
                    album = album[ALBUM_COL],
                    score = album[SCORE_COL]
                ))

                temp_artist = album[ARTIST_COL]
                if artist is None or len(temp_artist) < len(artist):
                    artist = temp_artist

        assert(artist is not None and len(albums) > 0)
        print('success')
        return "Fantano's album scores for *{artist}*:\n\n{albums}".format(
            artist = artist,
            albums = '  \n'.join(albums)
        )
    except Exception as e:
        print('fail')
        print(e)
        return None

def ampersand_replacement(term):
    # Make replacements for ampersand usage
    if 'and' in term:
        term = term.replace('and', '(and|&)')
    elif '&' in term:
        term = term.replace('&', '(and|&)')
    return term

def check_comments(client):
    for comment in client.subreddit(SUBREDDITS).stream.comments():
        # Check if replied to
        if db.get(str(comment.id)) is not None or comment.author == client.user.me():
            continue

        # search for bot command in comment
        bot_call = COMMAND.search(comment.body)

        if bot_call is None:
            continue

        print('found comment: https://reddit.com' + comment.permalink)
        print('term:', bot_call.group(1))
        term = bot_call.group(1).strip()

        new_term = ampersand_replacement(term)
        response = retrieve(new_term)

        if response is None:
            response = "Could not find anything for *{term}*".format(term = term)
        print(response)
        comment.reply(response + FOOTER)
        db.set(str(comment.id), 'True')
        print('replied')

def check_messages(client):
    for item in client.inbox.stream():
        if db.get(str(item.id)) is not None:
            continue

        if type(item) == praw.models.Message and '!fantanobot' in item.subject:
            print("Message found: **{subject}** - {body}".format(
                subject = item.subject,
                body    = item.body
            ))
            term = ampersand_replacement(item.body)
            response = retrieve(term)
            if response is None:
                response = "Could not find anything for *{term}*".format(term = item.body)
            print(response)
            item.reply(response + FOOTER)
            db.set(str(item.id), 'True')
            print('replied')

def login():
    print('logging in ...')
    client = praw.Reddit(
        username      = os.environ['REDDIT_USER'],
        password      = os.environ['REDDIT_PASS'],
        client_id     = os.environ['CLIENT_ID'],
        client_secret = os.environ['CLIENT_SECRET'],
        user_agent    = 'FantanoBot responder'
    )
    return client

def run(client):
    print('running ...')
    comment_thread = threading.Thread(target=check_comments, args=(client,))
    message_thread = threading.Thread(target=check_messages, args=(client,))
    comment_thread.start()
    message_thread.start()

if __name__ == '__main__':
    client = login()
    run(client)


import numpy as np
import pandas as pd
from matplotlib import pyplot as plt

from sklearn.cluster import KMeans

df = pd.read_csv('dataset.csv')

X = np.array(df)

c_x = np.array([0.1,0.3])
c_y = np.array([0.6,0.2])

centroids = np.array(list(zip(c_x,c_y)))
print(centroids)

model = KMeans()
model.fit(X, centroids)

plt.figure()
plt.scatter(X[:,0],X[:,1],alpha=0.3)
plt.show()

plt.figure()
plt.scatter(X[:,0],X[:,1],alpha=0.3)
plt.scatter(c_x,c_y, marker='o', c='black', s=150)
plt.show()


from itertools import permutations
import math

# 소수 판별 함수
def is_prime_number(x):
    if x < 2:
        return False
    for i in range(2, int(math.sqrt(x)) + 1):
        if x % i == 0:
            return False
    return True

def solution(numbers):
    answer = set()
    for length in range(1, len(numbers) + 1):
        for p in permutations(numbers, length):
            num = int("".join(p))
            if is_prime_number(num):
                answer.add(num)
    return len(answer)

# Test
print(solution("011"))
# print(solution("17"))

프로그래머스_고득점kit/완전탐색/2단계_소수찾기2.py

2단계_소수찾기2.py


import os

import numpy as np
import torch
import torch.utils.data as data

from torch.utils.tensorboard import SummaryWriter
from torchvision import transforms
from tqdm.notebook import tqdm

from dataset import MolecularDataset
from pointnet import PointNetCls

writer = SummaryWriter()

# hyper parameters
LR = 0.001
EPOCH = 500
BATCH_SIZE = 128

# load dataset
dataset = MolecularDataset(transform=transforms.ToTensor(), data_augmentation=True)
train_size = int(0.8 * len(dataset))
test_size = int(len(dataset) - train_size)
train_data, test_data = data.random_split(dataset, [train_size, test_size])

train_loader = data.DataLoader(dataset=train_data, batch_size=BATCH_SIZE, shuffle=True,)

test_loader = data.DataLoader(dataset=test_data, batch_size=BATCH_SIZE,)

# define something about training...
mynet = PointNetCls()
optimizer = torch.optim.Adam(mynet.parameters(), lr=LR)

scheduler = torch.optim.lr_scheduler.StepLR(optimizer, step_size=30, gamma=0.8)
loss_func = torch.nn.MSELoss()

# train
myepoch = tqdm(range(1,500))
for epoch in myepoch:
    loss_list = []
    valid_loss_list = []
    for step, (features, targets) in enumerate(train_loader):
        mynet.cuda()
        mynet.train()
        features = features.transpose(2, 1)
        features, targets = features.cuda(), targets.cuda()
        predicted_targets, feature_transform_matrix = mynet(features)

        loss = loss_func(targets, predicted_targets)
        loss = (
            loss + mynet.feature_transform_regularizer(feature_transform_matrix) * 0.001
        )
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()
        loss_list.append(loss.cpu().data.numpy())

    ave_loss = np.array(loss_list).mean()
    writer.add_scalar("loss", ave_loss, epoch)

    if epoch % 10 == 0:
        for step, (features, targets) in enumerate(test_loader):
            mynet.cpu()
            mynet.eval()
            features = features.transpose(2, 1)
            predicted_targets, feature_transform_matrix = mynet(features)
            valid_loss_list.append(loss_func(targets, predicted_targets).cpu().data.numpy())

        ave_valid_loss = np.array(valid_loss_list).mean()
        writer.add_scalar("valid_loss", ave_valid_loss, epoch)

    myepoch.set_description("loss:{:.2f}#####".format(ave_loss))
    scheduler.step()
mynet.eval()
torch.save(mynet, "mynet.pkl")

writer.close()

train_loss_list = []
for step, (features, targets) in enumerate(test_loader):
    features = features.transpose(2, 1)
    predicted_targets, feature_transform_matrix = mynet(features)
    train_loss_list.append((torch.abs(predicted_targets.data-targets)/targets*100).mean())

train_loss = -np.array(train_loss_list).mean()

valid_loss_list = []
for step, (features, targets) in enumerate(test_loader):
    features = features.transpose(2, 1)
    predicted_targets, feature_transform_matrix = mynet(features)
    valid_loss_list.append((torch.abs(predicted_targets.data-targets)/targets*100).mean())

valid_loss = -np.array(valid_loss_list).mean()

print('训练集误差：{:.4f}%'.format(train_loss))
print('测试集误差：{:.4f}%'.format(valid_loss))


from flask import jsonify, request
from flask_restful import Resource
from Model import db, VistorLevel, LevelOptionsSchema, Level2OptionsSchema, Vistor, LocationOptionSchema

from webargs import fields, validate
from webargs.flaskparser import use_args, use_kwargs, parser, abort

level_schema = LevelOptionsSchema
level_schema = LevelOptionsSchema(many=True)

level2_schema = Level2OptionsSchema
level2_schema = Level2OptionsSchema(many=True)

location_schema = LocationOptionSchema
location_schema = location_schema(many=True)

class Level1Resource(Resource):

    queryArgs = {
        "level": fields.Str(),
        "sublevel": fields.Str()
    }
    @use_args(queryArgs)
    def get(self, args):
        if 'level' and 'sublevel' in args:
            if(not len(args['sublevel']) == 0):
                location = Vistor.query.filter_by(
                    Level_1=args['level'], Level_2=args['sublevel']).distinct(Vistor.LOCATION).all()
            else:
                location = Vistor.query.filter_by(
                    Level_1=args['level']).distinct(Vistor.LOCATION).all()

            location = location_schema.dump(location).data
            return {"message": "Success", 'data': location}, 200

        elif'level' in args:
            levels = VistorLevel.query.filter_by(
                Level_1=args['level']).distinct(VistorLevel.Level_2).all()
            levels = level2_schema.dump(levels).data
            return {"message": "Success", 'data': levels}, 200

        else:
            levels = VistorLevel.query.distinct(VistorLevel.Level_1).all()
            levels = level_schema.dump(levels).data
            return {"message": "Success", 'data': levels}, 200


import os
import sys
import time
import pytest

def test_modules():
    topdir = os.path.dirname(__file__)
    for dirpath, _, filenames in os.walk(topdir):
        for fname in filenames:
            if _is_test_module(fname):
                yield os.path.join(dirpath, fname)

def _is_test_module(fname):
    return fname.startswith('test') and fname.endswith('.py')

def collect_execution_times(test_modules):
    sys.argv.append('--match=^test')
    sys.argv.append('-q')
    for tmodule in test_modules:
        yield tmodule, _test_module_execution_time(tmodule)

def _test_module_execution_time(tmodule):
    starttime = time.time()
    pytest.main(args=[tmodule])
    return time.time() - starttime

def write_results(exectimes, write):
    total = 0.0
    writes = []
    for record in reversed(sorted(exectimes, key=lambda record: record[1])):
        total += record[1]
        write('%s%.02f s (%.02f s)\n' % (record[0].ljust(70), record[1], total))
    write('\nTotal test execution time: %.02f seconds\n' % total)

def main():
    exectimes = collect_execution_times(test_modules())
    with open('testtimes.robot', 'w') as output:
        def write(txt):
            output.write(txt)
            sys.stdout.write(txt)
        write_results(exectimes, write)

if __name__ == '__main__':
    main()


import json

from django.http import HttpResponse
from django.shortcuts import render
from django.template.loader import render_to_string
from django.views.decorators.csrf import csrf_exempt
from django.views.generic.base import View

from hipsterboard.board.models import Player
from hipsterboard.board.models import Item

class BoardView(View):
    def get(self, request):
        context = {
            'players': Player.objects.all(),
        }

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

    @csrf_exempt
    def dispatch(self, *args, **kwargs):
        return super(BoardView, self).dispatch(*args, **kwargs)

    @csrf_exempt
    def post(self, request):
        post = request.POST
        player = Player.get(post.get('player'))

        if 'create' in post:
            item, created = Item.objects.get_or_create(
                player=player,
                target=post.get('create')
            )

            ret = {
                'html': render_to_string('item.html', {'item': item}),
                'count': Item.objects.filter(player=player).count(),
                'created': created,
            }

        elif 'delete' in post:
            iid = int(post.get('delete').split('-')[1])
            item = Item.objects.get(id=iid)
            item.delete()

            ret = {
                'killed_in_fire': True,
                'count': Item.objects.filter(player=player).count()
            }

        else:
            ret = {'wat': True}

        return HttpResponse(json.dumps(ret))


import json, os, platform, subprocess, sys, time
from datetime import datetime, timedelta
from operator import itemgetter

isPy3 = True

try:
    from colorama import init

    init()
except ImportError as e:
    pass

scripts_lib_path = os.path.join(os.path.dirname(__file__), "lib")
this_platform_system = str(platform.system())
platform_lib_path = os.path.join(scripts_lib_path, this_platform_system)
if os.path.exists(platform_lib_path):
    if platform_lib_path not in sys.path:
        sys.path.append(platform_lib_path)

import util

python_exe = sys.executable
python_ver = platform.python_version()

class bcolors:
    HEADER = "\033[95m"
    OKBLUE = "\033[94m"
    OKGREEN = "\033[92m"
    WARNING = "\033[93m"
    FAIL = "\033[91m"
    ENDC = "\033[0m"
    BOLD = "\033[1m"
    UNDERLINE = "\033[4m"
    BACKGROUND = "\033[42m"
    ITALIC = "\033[3m"

bold_start = bcolors.BOLD
bold_end = bcolors.ENDC
italic_start = bcolors.ITALIC
italic_end = bcolors.ENDC
table_header_style = bcolors.BOLD + bcolors.BACKGROUND
error_start = bcolors.FAIL

def format_help(p_input):
    inp = str(p_input)
    inp_lst = inp.split()

    p_1st = None
    if inp_lst:
        p_1st = str(inp_lst[0])

    if p_1st in ("#", "##", "###"):
        skip_len = len(p_1st) + 1
        inp = inp[skip_len:]
        inp = inp.replace("`", "")
        inp = bold_start + str(inp.upper()) + bold_end

    elif inp == "```":
        return None

    else:
        inp = inp.replace(" # ", italic_start + " # ")
        inp = "  " + inp + " " + italic_end

    return inp

def get_pip_ver():
    try:
        import pip

        return pip.__version__
    except ImportError as e:
        pass
    return "None"

def cli_unicode(p_str, p_encoding, errors="ignore"):
    return str(p_str)

try:
    test_unicode = unicode("test")
except NameError as e:
    unicode = cli_unicode

def check_output_wmic(p_cmds):
    out1 = subprocess.check_output(p_cmds)
    try:
        out2 = str(out1, "utf-8")
    except:
        out2 = str(out1)
    out3 = out2.strip().split("\n")[1]
    return out3

def top(display=True, isJson=False):
    try:
        import psutil
    except ImportError as e:
        util.exit_message("Missing psutil module", 1)

    current_timestamp = int(time.mktime(datetime.utcnow().timetuple()))
    jsonDict = {}
    procs = []
    for p in psutil.process_iter():
        try:
            p = p.as_dict(
                attrs=[
                    "pid",
                    "username",
                    "cpu_percent",
                    "memory_percent",
                    "cpu_times",
                    "name",
                ]
            )
        except (psutil.NoSuchProcess, IOError, OSError) as e:
            pass
        else:
            procs.append(p)

    if not display:
        return

    processes = sorted(procs, key=lambda p: p["cpu_percent"], reverse=True)

    network_usage = psutil.net_io_counters()
    jsonDict["kb_sent"] = network_usage.bytes_sent / 1024
    jsonDict["kb_recv"] = network_usage.bytes_recv / 1024

    cpu = psutil.cpu_times_percent(percpu=False)
    iowait = ""
    if util.get_platform() == "Linux":
        jsonDict["iowait"] = str(cpu.iowait)
        iowait = "," + str(cpu.iowait).rjust(5) + "%wa"

    jsonDict["current_timestamp"] = current_timestamp
    jsonDict["cpu_user"] = str(cpu.user)
    jsonDict["cpu_system"] = str(cpu.system)
    jsonDict["cpu_idle"] = str(cpu.idle)
    if not isJson:
        print(
            "CPU(s):"
            + str(cpu.user).rjust(5)
            + "%us,"
            + str(cpu.system).rjust(5)
            + "%sy,"
            + str(cpu.idle).rjust(5)
            + "%id"
            + iowait
        )

    disk = psutil.disk_io_counters(perdisk=False)
    read_kb = disk.read_bytes / 1024
    write_kb = disk.write_bytes / 1024
    jsonDict["kb_read"] = str(read_kb)
    jsonDict["kb_write"] = str(write_kb)
    if not isJson:
        print("DISK: kB_read " + str(read_kb) + ", kB_written " + str(write_kb))

    uptime = datetime.now() - datetime.fromtimestamp(psutil.boot_time())
    str_uptime = str(uptime).split(".")[0]
    line = ""
    uname_len = 8
    av1, av2, av3 = os.getloadavg()
    str_loadavg = "%.2f %.2f %.2f  " % (av1, av2, av3)
    line = bold_start + "Load average: " + bold_end + str_loadavg
    jsonDict["load_avg"] = str(str_loadavg)
    line = line + bold_start + "Uptime:" + bold_end + " " + str_uptime
    jsonDict["uptime"] = str(str_uptime)
    if not isJson:
        print(line)

    i = 0
    my_pid = os.getpid()
    if not isJson:
        print("")
        print(
            bold_start
            + "    PID "
            + "USER".ljust(uname_len)
            + "   %CPU %MEM      TIME+ COMMAND"
            + bold_end
        )

    jsonList = []
    for pp in processes:
        if pp["pid"] == my_pid:
            continue
        i += 1
        if i > 10:
            break

        # TIME+ column shows process CPU cumulative time and it
        # is expressed as: "mm:ss.ms"

        ctime = timedelta(seconds=sum(pp["cpu_times"]))
        ctime_mm = str(ctime.seconds // 60 % 60)
        ctime_ss = str(int(ctime.seconds % 60)).zfill(2)
        ctime_ms = str(ctime.microseconds)[:2].ljust(2, str(0))
        ctime = "{0}:{1}.{2}".format(ctime_mm, ctime_ss, ctime_ms)

        username = pp["username"][:uname_len]
        if isJson:
            pp["username"] = username
            pp["ctime"] = ctime
            pp["cpu_percent"] = float(pp["cpu_percent"])
            pp["memory_percent"] = float(round(pp["memory_percent"], 1))
            jsonList.append(pp)
        else:
            print(
                str(pp["pid"]).rjust(7)
                + " "
                + username.ljust(uname_len)
                + " "
                + str(pp["cpu_percent"]).rjust(6)
                + " "
                + str(round(pp["memory_percent"], 1)).rjust(4)
                + " "
                + str(ctime).rjust(10)
                + " "
                + pp["name"]
            )
    if isJson:
        jsonDict["top"] = jsonList
        print(json.dumps([jsonDict]))
    else:
        print("")

def list(p_json, p_cat, p_comp, p_ver, p_port, p_status, p_kount):
    lst = " "
    if p_kount > 1:
        lst = ","
    if p_json:
        lst = (
            lst
            + '{"category": "'
            + p_cat.rstrip()
            + '",'
            + ' "component": "'
            + p_comp.rstrip()
            + '",'
            + ' "version": "'
            + p_ver.rstrip()
            + '",'
            + ' "port": "'
            + p_port.rstrip()
            + '",'
            + ' "status": "'
            + p_status.rstrip()
            + '"}'
        )
        print(lst)
        return

    print(p_comp + "  " + p_ver + "  " + p_port + "  " + p_status)

def status(p_json, p_comp, p_ver, p_state, p_port, p_kount):
    status = " "
    if p_kount > 1:
        status = ","
    if p_json:
        jsonStatus = {}
        jsonStatus["component"] = p_comp
        jsonStatus["version"] = p_ver
        jsonStatus["state"] = p_state
        if p_port != "" and int(p_port) > 1:
            jsonStatus["port"] = p_port
        category = util.get_comp_category(p_comp)
        if category:
            jsonStatus["category"] = category
        elif p_comp.startswith == "pgdg":
            jsonStatus["category"] = 1
        print(status + json.dumps(jsonStatus))
        return

    app_ver = p_comp + "-" + p_ver
    app_ver = app_ver + (" " * (35 - len(app_ver)))

    if p_state in ("Running", "Stopped") and int(p_port) > 1:
        on_port = " on port " + p_port
    else:
        on_port = ""

    # print(app_ver + "(" + p_state + on_port + ")")
    print(p_comp + " " + p_state.lower() + on_port)

def info(p_json, p_home, p_repo, print_flag=True):
    (
        cloud_name,
        cloud_platform,
        instance_id,
        flavor,
        region,
        az,
        private_ip,
    ) = util.get_cloud_info()

    p_user = util.get_user()
    p_is_admin = util.is_admin()
    pip_ver = get_pip_ver()
    os_arch = util.get_arch()

    this_os = ""
    this_uname = str(platform.system())[0:7]
    if private_ip > "":
        host_ip = private_ip
    else:
        host_ip = util.get_host_ip()
    wmic_path = (
        os.getenv("SYSTEMROOT", "")
        + os.sep
        + "System32"
        + os.sep
        + "wbem"
        + os.sep
        + "wmic"
    )
    host_display = util.get_host_short()

    ## Check the OS & Resources ########################################
    plat = util.get_os()
    glibcV = util.get_glibc_version()

    os_major_ver = ""
    java_major_ver = ""
    java_ver = ""

    if this_uname == "Darwin":
        mem_mb = util.get_mem_mb()
        system_memory_in_kbytes = mem_mb * 1024
        system_memory_in_gb = mem_mb / 1024.0
        system_cpu_cores = util.get_cpu_cores()
        cpu_model = util.getoutput("/usr/sbin/sysctl -n machdep.cpu.brand_string")
        prod_name = util.getoutput("sw_vers -productName")
        prod_version = util.getoutput("sw_vers -productVersion")
        this_os = prod_name + " " + prod_version
    elif this_uname == "Linux":
        mem_mb = util.get_mem_mb()
        system_memory_in_kbytes = mem_mb * 1024
        system_memory_in_gb = mem_mb / 1024.0
        system_cpu_cores = util.get_cpu_cores()
        cpu_model = util.getoutput(
            "grep 'model name' /proc/cpuinfo | head -1 | cut -d':' -f2"
        )
        os_major_ver = util.getoutput(
            "cat /etc/os-release | grep VERSION_ID | cut -d= -f2 | tr -d '\"'"
        )
        if cpu_model == "":
            cpu_model = "ARM"
        if os.path.exists("/etc/redhat-release"):
            this_os = util.getoutput("cat /etc/redhat-release")
        elif os.path.exists("/etc/system-release"):
            this_os = util.getoutput("cat /etc/system-release")
        elif os.path.exists("/etc/lsb-release"):
            this_os = util.getoutput(
                "cat /etc/lsb-release | grep DISTRIB_DESCRIPTION | cut -d= -f2 | tr -d '\"'"
            )
        elif os.path.exists("/etc/os-release"):
            this_os = util.getoutput(
                "cat /etc/os-release | grep PRETTY_NAME | cut -d= -f2 | tr -d '\"'"
            )
        [java_major_ver, java_ver] = util.get_java_ver()

    if system_memory_in_gb > 0.6:
        round_mem = round(system_memory_in_gb)
    else:
        round_mem = round(system_memory_in_gb, 1)

    mem = str(round_mem) + " GB"

    cores = str(system_cpu_cores)

    cpu = cpu_model.strip()
    cpu = cpu.replace("(R)", "")
    cpu = cpu.replace("(TM)", "")
    cpu = cpu.replace(" CPU ", " ")

    os2 = this_os.replace(" release ", " ")
    os2 = os2.replace(" (Final)", "")
    os2 = os2.replace(" (Core)", "")

    ver = util.get_version()
    [last_update_utc, last_update_local, unique_id] = util.read_hosts("localhost")
    if last_update_local:
        last_upd_dt = datetime.strptime(last_update_local, "%Y-%m-%d %H:%M:%S")
        time_diff = int(util.timedelta_total_seconds(datetime.now() - last_upd_dt))
        last_update_readable = util.get_readable_time_diff(str(time_diff), precision=2)

    versions_sql = util.get_versions_sql()
    perl_ver = util.get_perl_ver()

    os_pkg_mgr = util.get_pkg_mgr()

    if p_json:
        infoJsonArray = []
        infoJson = {}
        infoJson["version"] = ver
        infoJson["home"] = p_home
        infoJson["user"] = p_user
        infoJson["host"] = host_display
        infoJson["host_short"] = util.get_host_short()
        infoJson["host_long"] = util.get_host()
        infoJson["host_ip"] = host_ip
        infoJson["os"] = unicode(
            str(os2), sys.getdefaultencoding(), errors="ignore"
        ).strip()
        infoJson["os_pkg_mgr"] = os_pkg_mgr
        infoJson["os_major_ver"] = os_major_ver
        infoJson["platform"] = unicode(
            str(plat), sys.getdefaultencoding(), errors="ignore"
        ).strip()
        infoJson["arch"] = os_arch
        infoJson["mem"] = round_mem
        infoJson["cores"] = system_cpu_cores
        infoJson["cpu"] = cpu
        infoJson["last_update_utc"] = last_update_utc
        if last_update_local:
            infoJson["last_update_readable"] = last_update_readable
        infoJson["unique_id"] = unique_id
        infoJson["repo"] = p_repo
        infoJson["versions_sql"] = versions_sql
        infoJson["system_memory_in_kb"] = system_memory_in_kbytes
        infoJson["python_ver"] = python_ver
        infoJson["python_exe"] = python_exe
        if pip_ver != "None":
            infoJson["pip_ver"] = pip_ver
        infoJson["perl_ver"] = perl_ver
        infoJson["java_ver"] = java_ver
        infoJson["java_major_ver"] = java_major_ver
        infoJson["glibc_ver"] = glibcV
        infoJson["region"] = region
        infoJson["az"] = az
        infoJson["instance_id"] = instance_id
        infoJson["flavor"] = flavor
        infoJson["private_ip"] = private_ip
        infoJsonArray.append(infoJson)
        if print_flag:
            print(json.dumps(infoJsonArray, sort_keys=True, indent=2))
            return
        else:
            return infoJson

    if p_is_admin:
        admin_display = " (Admin)"
    else:
        admin_display = ""

    langs = "Python v" + python_ver
    if perl_ver > "":
        langs = langs + " | Perl v" + perl_ver
    if java_ver > "":
        langs = langs + " | Java v" + java_ver

    ## util.validate_distutils_click(False)

    if glibcV <= " ":
        glibc_v_display = ""
    else:
        glibc_v_display = " glibc-" + glibcV + "-"

    print(bold_start + ("#" * 70) + bold_end)
    print(bold_start + "#  pgEdge CTL: " + bold_end + "v" + ver + "  " + p_home)
    print(
        bold_start
        + "# User & Host: "
        + bold_end
        + p_user
        + admin_display
        + "  "
        + host_display
        + "  "
        + host_ip
    )
    print(
        bold_start
        + "#          OS: "
        + bold_end
        + os2.rstrip()
        + " "
        + glibc_v_display
        + os_arch
    )
    print(
        bold_start + "#     Machine: " + bold_end + mem + ", " + cores + " vCPU, " + cpu
    )
    if instance_id > "" and not cloud_name == "unknown":
        print(
            bold_start
            + "#  Cloud Info: "
            + bold_end
            + f"{cloud_name}  {cloud_platform}  {instance_id}  {flavor}  {az}"
        )

    print(bold_start + "#       Langs: " + bold_end + langs)

    print(bold_start + "#    Repo URL: " + bold_end + p_repo)

    if not last_update_local:
        last_update_local = "None"

    print(bold_start + "# Last Update: " + bold_end + str(last_update_local))
    print(bold_start + ("#" * 70) + bold_end)

def info_component(p_comp_dict, p_kount):
    if p_kount > 1:
        print(bold_start + ("-" * 90) + bold_end)

    print(
        bold_start
        + "     Project: "
        + bold_end
        + p_comp_dict["project"]
        + " ("
        + p_comp_dict["project_url"]
        + ")"
    )

    print(
        bold_start
        + "   Component: "
        + bold_end
        + p_comp_dict["component"]
        + " "
        + p_comp_dict["version"]
        + " ("
        + p_comp_dict["proj_description"]
        + ")"
    )

    if p_comp_dict["port"] > 1:
        print(bold_start + "        port: " + bold_end + str(p_comp_dict["port"]))

    if p_comp_dict["datadir"] > "":
        print(bold_start + "     datadir: " + bold_end + p_comp_dict["datadir"])

    if p_comp_dict["logdir"] > "":
        print(bold_start + "      logdir: " + bold_end + p_comp_dict["logdir"])

    if p_comp_dict["autostart"] == "on":
        print(bold_start + "   autostart: " + bold_end + p_comp_dict["autostart"])

    if p_comp_dict["svcuser"] > "" and util.get_platform() == "Linux":
        print(bold_start + "     svcuser: " + bold_end + p_comp_dict["svcuser"])

    if ("status" in p_comp_dict) and ("up_time" in p_comp_dict):
        print(
            bold_start
            + "      status: "
            + bold_end
            + p_comp_dict["status"]
            + bold_start
            + " for "
            + bold_end
            + p_comp_dict["up_time"]
        )
    else:
        if "status" in p_comp_dict:
            print(bold_start + "      status: " + bold_end + p_comp_dict["status"])
        if "up_time" in p_comp_dict:
            print(bold_start + "    up since: " + bold_end + p_comp_dict["up_time"])

    if "data_size" in p_comp_dict:
        print(bold_start + "   data size: " + bold_end + p_comp_dict["data_size"])

    if "connections" in p_comp_dict:
        print(bold_start + " connections: " + bold_end + p_comp_dict["connections"])

    print(
        bold_start
        + "Release Date: "
        + bold_end
        + p_comp_dict["release_date"]
        + bold_start
        + "  Stage: "
        + bold_end
        + p_comp_dict["stage"]
    )

    if p_comp_dict["platform"] > "":
        print(
            bold_start
            + "Supported On: "
            + bold_end
            + "["
            + p_comp_dict["platform"]
            + "]"
        )

    if p_comp_dict["pre_reqs"] > "":
        print(bold_start + "   Pre Req's: " + bold_end + p_comp_dict["pre_reqs"])

    print(bold_start + "     License: " + bold_end + p_comp_dict["license"])

    is_installed = str(p_comp_dict["is_installed"])
    if str(is_installed) == "0":
        is_installed = "NO"

    print(
        bold_start
        + "   IsCurrent: "
        + bold_end
        + str(p_comp_dict["is_current"])
        + bold_start
        + "  IsInstalled: "
        + bold_end
        + is_installed
    )

def format_data_to_table(
    data,
    keys,
    header=None,
    error_key=None,
    error_msg_column=None,
    sort_by_key=None,
    sort_order_reverse=False,
):
    """Takes a list of dictionaries, formats the data, and returns
    the formatted data as a text table.

    Required Parameters:
        data - Data to process (list of dictionaries). (Type: List)
        keys - List of keys in the dictionary. (Type: List)

    Optional Parameters:
        header - The table header. (Type: List)
        sort_by_key - The key to sort by. (Type: String)
        sort_order_reverse - Default sort order is ascending, if
            True sort order will change to descending. (Type: Boolean)
    """
    # Sort the data if a sort key is specified (default sort order
    # is ascending)
    if sort_by_key:
        data = sorted(data, key=itemgetter(sort_by_key), reverse=sort_order_reverse)

    # If header is not empty, add header to data
    if header:
        # Get the length of each header and create a divider based
        # on that length
        header_divider = []
        for name in header:
            header_divider.append("-" * len(name))

        # Create a list of dictionary from the keys and the header and
        # insert it at the beginning of the list. Do the same for the
        # divider and insert below the header.
        # header_divider = dict(zip(keys, header_divider))
        # data.insert(0, header_divider)
        header = dict(zip(keys, header))
        data.insert(0, header)

    column_widths = []
    for key in keys:
        column_widths.append(max(len(str(column[key])) for column in data) + 2)

    # Create a tuple pair of key and the associated column width for it
    key_width_pair = zip(keys, column_widths)
    key_length = len(keys)

    str_format = ("%-*s " * len(keys)).strip() + "\n"
    formatted_data = ""

    for element in data:
        data_to_format = []
        s = 0
        key_width_pair = zip(keys, column_widths)
        # Create a tuple that will be used for the formatting in
        # width, value format
        for pair in key_width_pair:
            dataStr = str(element[pair[0]])
            spaces = " " * ((int(float(pair[1])) - len(dataStr)) - 2)
            if s < key_length - 1:
                spaces = spaces + " |"

            if dataStr in header.values():
                if s == 0:
                    dataStr = table_header_style + dataStr
                dataStr = dataStr + spaces
                if s == key_length - 1:
                    dataStr = dataStr + bold_end
                s = s + 1
            elif error_key and error_msg_column:
                if (
                    pair[0] in error_msg_column
                    and element.get(error_key[0]) == error_key[1]
                ):
                    dataStr = error_start + dataStr + bold_end

            data_to_format.append(pair[1])
            data_to_format.append(dataStr)
        formatted_data += str_format % tuple(data_to_format)
    return formatted_data