## Import Statements
from helpers import filling_movie_name, movie_showboard, number_of_players, removing_spaces, spin_wheel, VOWELS, INTEGERS, SYMBOLS, ALPHABETS
from get_movie import get_movie_name
from create_players import HumanPlayer
import time

## GLobal variables
index = 0
guessed_letters = []
winner = False

print("\n############# HUMAN PLAYERS  #############")
num_of_human = number_of_players(0,4)

## Prompting for number of players and level of difficulty
if type(num_of_human) is int:
    human_players = [HumanPlayer(input("Enter Name of player {0}: ".format(i+1))) for i in range(num_of_human)]
    print("\n1 - EASY, 2 - MEDIUM, 3 - DIFFICULT")
    difficulty = input("Level of Difficulty: ")

    movie_name = get_movie_name(difficulty)
    # print(movie_name)

    print("\n")
    print("=="*40)
    print("\n")
    [print("WELCOME {0}..! Your Prize Money is Rs.{1}/-".format(each.name,each.prize_money)) for each in human_players]

    print(movie_showboard(movie=movie_name, guessed=guessed_letters))

    ##########  ACTUAL LOGIC OF GAME    ##########
    while True:
        player = human_players[index]
        print("\n{0}'s turn..!".format(player.name))
        time.sleep(2)
        option = spin_wheel()
        chance = list(option.keys())[0]

        ## Checking for the chance
        if chance == "PASS":
            print("{0} got PASS. {1}".format(player.name, option["PASS"]))
        elif chance == "PUNISHMENT":
            print("{0} got punishment. {1}".format(player.name, option["PUNISHMENT"]))
            player.punish_charge()
        elif chance == "CHANCE":
            print("{0} got CHANCE. {1}".format(player.name, option["CHANCE"]))
            player.add_prize_lst(prize= option["CHANCE"])
            guess = player.human_get_move()
            # print(guess)

            ## Logic of taking the guess and checking
            if guess == "EXIT":
                print("Thank You for your time {0}..! Please come back to GuessTheMovie.".format(player.name))
                break
            elif guess == "PASS":
                print("{0} passes..!".format(player.name))
            elif len(guess) == 1:
                if (guess in VOWELS):
                    print("{0} is a vowel".format(guess))
                elif (guess in INTEGERS):
                    print("{0} is an integer".format(guess))
                elif (guess in SYMBOLS):
                    print("{0} is a symbol".format(guess))
                elif (guess in guessed_letters):
                    print("{0} is already guessed! Guess another..!".format(guess))
                    continue
                elif (guess in ALPHABETS):
                    guess = guess
                    guessed_letters.append(guess)
                    count = movie_name.count(guess)

                    if count <= 0:
                        player.prize_money = player.prize_money - 50
                    else:
                        player.add_prize_money(count)

                    print("{0}'s guesses {1}".format(player.name, guess))
                    print("Movie has {0} {1}.".format(count, guess))

                    ## Checking for the whole guess as correct or not
                    movie_title = filling_movie_name(movie=movie_name,guessed=guessed_letters)
                    if removing_spaces(movie_title) == removing_spaces(movie_name):
                        winner = player
                        break

            else:
                ## If the whole movie is guessed in once. Then, check:-
                if removing_spaces(guess) == removing_spaces(movie_name):
                    winner = player
                    player.add_prize_money(count=len(removing_spaces(guess)))
                    break
                else:
                    print("{0} is not the correct movie.".format(guess))

        print("Now, {0}'s total prize money is Rs.{1}/-".format(player.name,player.prize_money))
        print(movie_showboard(movie=movie_name, guessed=guessed_letters))
        print("\nGuessed letters are: ",guessed_letters)

        index = (index + 1) % len(human_players)

    ##########  WINNER DECLARATION  ##########

    if winner:
        print("\n\n{0} WINS..! Correct movie name was {1}.\nCongratulations..! Your winning prize amount is Rs.{2}/-.".format(winner.name, movie_name,winner.prize_money))
        print("Additional prizes you won are :")
        [print(prize) for prize in set(winner.prizes_lst)]
    else:
        print("NoBody Wins..! Movie name was {0}".format(movie_name))

## If limit of players is either low or out of bound on higher side
else:
    print(num_of_human)


# Support Vector Machine (SVM)
# from https://www.superdatascience.com/machine-learning/

# Part 1 - Data Preprocessing

# Importing the libraries
import os
import glob
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt

train_dir = os.path.join(os.path.curdir, "data/train")
validation_dir = os.path.join(os.path.curdir, "data/validate")

train_dirs = []
train_dirs.append(os.path.join(train_dir, "cima"))
train_dirs.append(os.path.join(train_dir, "baixo"))
train_dirs.append(os.path.join(train_dir, "esq"))
train_dirs.append(os.path.join(train_dir, "dir"))

validation_dirs = []
validation_dirs.append(os.path.join(validation_dir, "cima"))
validation_dirs.append(os.path.join(validation_dir, "baixo"))
validation_dirs.append(os.path.join(validation_dir, "esq"))
validation_dirs.append(os.path.join(validation_dir, "dir"))

# Preparando os dados de treinamento
X = []
y = []
for dir in train_dirs:
    classe = dir.rsplit('/')[-1]
    if classe == 'cima':
        classe_num = 0
    if classe == 'baixo':
        classe_num = 1
    if classe == 'esq':
        classe_num = 2
    if classe == 'dir':
        classe_num = 3

    files = os.listdir(dir)
    for file in files:
        image = cv.imread(dir+"/"+file, 0)
        # flatten transforma o array 2D de imagem em 1D
        X.append(image.flatten())
        y.append(classe_num)

X_train = np.array(X)
y_train = np.array(y)
print(X_train.shape)
print(y_train.shape)

# Preparando os dados de validação
X = []
y = []
for dir in validation_dirs:
    classe = dir.rsplit('/')[-1]
    if classe == 'cima':
        classe_num = 0
    if classe == 'baixo':
        classe_num = 1
    if classe == 'esq':
        classe_num = 2
    if classe == 'dir':
        classe_num = 3

    files = os.listdir(dir)
    for file in files:
        image = cv.imread(dir+"/"+file, 0)
        # flatten transforma o array 2D de imagem em 1D
        X.append(image.flatten())
        y.append(classe_num)

X_val = np.array(X)
y_val = np.array(y)
print(X_val.shape)
print(y_val.shape)

# Feature Scaling
from sklearn.preprocessing import StandardScaler
sc = StandardScaler()
X_train = sc.fit_transform(X_train)
X_val = sc.transform(X_val)

# Fitting SVM to the Training set
from sklearn.svm import SVC
from sklearn.pipeline import Pipeline

#classifier = SVC(kernel = 'linear', random_state = 0)
classifier = Pipeline((
("scaler", StandardScaler()),
("svm_clf", SVC(kernel="rbf", gamma=0.01, C=1000000))
))

classifier.fit(X_train, y_train)

# Predicting the Test set results
y_pred = classifier.predict(X_val)

print(y_val[0:35])
print(y_pred[0:35])

# Making the Confusion Matrix
from sklearn.metrics import confusion_matrix
cm = confusion_matrix(y_val, y_pred)

# matriz de confusão
print(cm)

print("Score da validação: ", classifier.score(X_val, y_val))

# Salvando modelo
import joblib as jl

model_file = "svm_eyes.pkl"
jl.dump(classifier, model_file)


import sys
from collections import deque
dq = deque()
N, K = map(int, sys.stdin.readline().rstrip().split(' '))

for i in range(1, N + 1):
    dq.append(i)
eleminated = []
while len(dq) != 0:
    count = 1
    while count < K:
        dq.append(dq.popleft())
        count += 1

    eleminated.append(dq.popleft())

print('<', end='')
for e in range(len(eleminated)):
    print(eleminated[e], end='')
    if e < len(eleminated) - 1: print(',',end=' ')

print('>')


# This file is Copyright 2020 Volatility Foundation and licensed under the Volatility Software License 1.0
# which is available at https://www.volatilityfoundation.org/license/vsl-v1.0

import json
import logging
import ntpath
import os
import re
from typing import List, Dict, Union

from volatility3.framework import (
    renderers,
    interfaces,
    objects,
    exceptions,
    constants,
    layers,
)
from volatility3.framework.configuration import requirements
from volatility3.framework.renderers import format_hints
from volatility3.framework.symbols.windows.extensions import registry
from volatility3.plugins.windows import pslist
from volatility3.plugins.windows.registry import hivelist

vollog = logging.getLogger(__name__)

def find_sid_re(
    sid_string, sid_re_list
) -> Union[str, interfaces.renderers.BaseAbsentValue]:
    for reg, name in sid_re_list:
        if reg.search(sid_string):
            return name
    return renderers.NotAvailableValue()

class GetSIDs(interfaces.plugins.PluginInterface):
    """Print the SIDs owning each process"""

    _version = (1, 0, 0)
    _required_framework_version = (2, 0, 0)

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        for plugin_dir in constants.PLUGINS_PATH:
            sids_json_file_name = os.path.join(
                plugin_dir, os.path.join("windows", "sids_and_privileges.json")
            )
            if os.path.exists(sids_json_file_name):
                break
        else:
            vollog.log(
                constants.LOGLEVEL_VVV,
                "sids_and_privileges.json file is missing plugin error",
            )
            raise RuntimeError(
                "The sids_and_privileges.json file missed from you plugin directory"
            )

        # Get all the sids from the json file.
        with open(sids_json_file_name, "r") as file_handle:
            sids_json_data = json.load(file_handle)
            self.servicesids = sids_json_data["service sids"]
            self.well_known_sids = sids_json_data["well known"]

            # Compile all the sids regex.
            self.well_known_sid_re = [
                (re.compile(c_list[0]), c_list[1])
                for c_list in sids_json_data["sids re"]
            ]

    @classmethod
    def get_requirements(cls) -> List[interfaces.configuration.RequirementInterface]:
        return [
            requirements.ModuleRequirement(
                name="kernel",
                description="Windows kernel",
                architectures=["Intel32", "Intel64"],
            ),
            requirements.ListRequirement(
                name="pid",
                description="Filter on specific process IDs",
                element_type=int,
                optional=True,
            ),
            requirements.PluginRequirement(
                name="pslist", plugin=pslist.PsList, version=(2, 0, 0)
            ),
            requirements.PluginRequirement(
                name="hivelist", plugin=hivelist.HiveList, version=(1, 0, 0)
            ),
        ]

    def lookup_user_sids(self) -> Dict[str, str]:
        """
        Enumerate the registry for all the users.

        Returns:
            An dictionary of {sid: user name}
        """

        key = "Microsoft\\Windows NT\\CurrentVersion\\ProfileList"
        val = "ProfileImagePath"
        kernel = self.context.modules[self.config["kernel"]]

        sids = {}
        for hive in hivelist.HiveList.list_hives(
            context=self.context,
            base_config_path=self.config_path,
            layer_name=kernel.layer_name,
            symbol_table=kernel.symbol_table_name,
            filter_string="config\\software",
            hive_offsets=None,
        ):
            try:
                for subkey in hive.get_key(key).get_subkeys():
                    sid = str(subkey.get_name())
                    path = ""
                    for node in subkey.get_values():
                        try:
                            value_node_name = node.get_name() or "(Default)"
                        except (
                            exceptions.InvalidAddressException,
                            layers.registry.RegistryFormatException,
                        ) as excp:
                            continue
                        try:
                            value_data = node.decode_data()
                            if isinstance(value_data, int):
                                value_data = format_hints.MultiTypeData(
                                    value_data, encoding="utf-8"
                                )
                            elif (
                                registry.RegValueTypes(node.Type)
                                == registry.RegValueTypes.REG_BINARY
                            ):
                                value_data = format_hints.MultiTypeData(
                                    value_data, show_hex=True
                                )
                            elif (
                                registry.RegValueTypes(node.Type)
                                == registry.RegValueTypes.REG_MULTI_SZ
                            ):
                                value_data = format_hints.MultiTypeData(
                                    value_data, encoding="utf-16-le", split_nulls=True
                                )
                            else:
                                value_data = format_hints.MultiTypeData(
                                    value_data, encoding="utf-16-le"
                                )
                            if value_node_name == val:
                                path = str(value_data).replace("\\x00", "")[:-1]
                                user = ntpath.basename(path)
                                sids[sid] = user
                        except (
                            ValueError,
                            exceptions.InvalidAddressException,
                            layers.registry.RegistryFormatException,
                        ) as excp:
                            continue
            except (KeyError, exceptions.InvalidAddressException):
                continue

        return sids

    def _generator(self, procs):
        user_sids = self.lookup_user_sids()

        # Go all over the process list, get the token
        for task in procs:
            # Make sure we have a valid token
            try:
                token = task.Token.dereference().cast("_TOKEN")
            except exceptions.InvalidAddressException:
                token = False

            if not token or not isinstance(token, interfaces.objects.ObjectInterface):
                yield (
                    0,
                    [
                        int(task.UniqueProcessId),
                        str(task.ImageFileName),
                        "Token unreadable",
                        "",
                    ],
                )
                continue

            # Go all over the sids and try to translate them with one of the tables we have
            for sid_string in token.get_sids():
                if sid_string in self.well_known_sids:
                    sid_name = self.well_known_sids[sid_string]
                elif sid_string in self.servicesids:
                    sid_name = self.servicesids[sid_string]
                elif sid_string in user_sids:
                    sid_name = user_sids[sid_string]
                else:
                    sid_name_re = find_sid_re(sid_string, self.well_known_sid_re)
                    if sid_name_re:
                        sid_name = sid_name_re
                    else:
                        sid_name = ""

                yield (
                    0,
                    (
                        task.UniqueProcessId,
                        objects.utility.array_to_string(task.ImageFileName),
                        sid_string,
                        sid_name,
                    ),
                )

    def run(self):
        filter_func = pslist.PsList.create_pid_filter(self.config.get("pid", None))
        kernel = self.context.modules[self.config["kernel"]]

        return renderers.TreeGrid(
            [("PID", int), ("Process", str), ("SID", str), ("Name", str)],
            self._generator(
                pslist.PsList.list_processes(
                    context=self.context,
                    layer_name=kernel.layer_name,
                    symbol_table=kernel.symbol_table_name,
                    filter_func=filter_func,
                )
            ),
        )


# %% [markdown]
# # Extracting attributes from timedelta columns via a ColumnTransformationPlugin
#
# inspired by Sailu and the following stackoverflow question:
# - https://stackoverflow.com/questions/38355816/pandas-add-timedelta-column-to-datetime-column-vectorized
#
# __Goal:__ extract the number of weeks as float based on the timedelta column

# %%
import pandas as pd
import numpy as np
import bamboolib as bam

# %%
df = pd.DataFrame()

# %%
df["date"] = ["2016-01-10", "2016-05-11", "2016-02-23", "2015-12-08"]
df["date"] = pd.to_datetime(df["date"])

# %%
df["days"] = [28, 7, 15, 30]
df["days"] = pd.to_timedelta(df["days"], "d")

# %%
# # solution:
# df['weeks'] = df['days'] / np.timedelta64(1, 'W')

# %%
import ipywidgets as widgets

from bamboolib.plugins import ColumnTransformationPlugin, DF_OLD, SelectizeDropdown

class TimedeltaExtractAttribute(ColumnTransformationPlugin):

    name = "Timedelta: extract attribute"

    def __init__(self, *args, column=None, **kwargs):
        super().__init__(*args, **kwargs)

        self.column = column

        # based on https://docs.scipy.org/doc/numpy/reference/arrays.datetime.html#datetime-units
        self.attribute = SelectizeDropdown(
            options=[
                ("years", "Y"),
                ("months", "M"),
                ("weeks", "W"),
                ("days", "D"),
                ("hours", "h"),
                ("minutes", "m"),
                ("seconds", "s"),
            ],
            value="D",
            focus_after_init=True,
        )
        self.new_column_name = widgets.Text(value=self.column)

    def render(self):
        self.set_title("Extract attribute")
        self.set_content(
            widgets.HTML(f"Convert <b>{self.column}</b> to"),
            self.attribute,
            widgets.HTML("New column name:"),
            self.new_column_name,
        )

    def get_description(self):
        return (
            f"Extract timedelta attribute {self.attribute.label} from '{self.column}'"
        )

    def get_code(self):
        return f"{DF_OLD}['{self.new_column_name.value}'] = {DF_OLD}['{self.column}'] / np.timedelta64(1, '{self.attribute.value}')"

# %% [markdown]
# __Hint:__ The plugin is shown in bamboolib when clicking on the column header of 'days' and searching for the transformation

# %%
df

# %%


#!/usr/bin/env python
# encoding: utf-8
"""
@author: HuRuiFeng
@file: vm.py
@time: 2020/8/19 21:28
@project: wasm-python-book
@desc:
"""
from ch09.binary.module import Module, ImportTagFunc
from ch09.binary.opcodes import Call
from ch09.interpreter.instr_control import call
from ch09.interpreter.instructions import instr_table
from ch09.interpreter.native import *
from ch09.interpreter.vm_func import new_internal_func, new_external_func
from ch09.interpreter.vm_global import GlobalVar
from ch09.interpreter.vm_memory import Memory
from ch09.interpreter.vm_stack_control import ControlStack, ControlFrame
from ch09.interpreter.vm_stack_operand import OperandStack
from ch09.interpreter.vm_table import Table

class VM(OperandStack, ControlStack):
    def __init__(self, module=None, memory=None):
        super(VM, self).__init__()
        if module is None:
            module = Module()
        self.module = module
        self.memory = memory
        # 用于存放模块实例的全局变量
        self.globals = []
        # 用于记录内/外部函数
        self.funcs = []
        self.table = None
        # 用来记录当前函数的第一个局部变量
        self.local_0_idx = None
        self.frames = []
        self.slots = []

    def init_mem(self):
        """
        内存初始化
        Wasm模块可以导入或者定义一块内存，还有一个数据段专门用来存放内存初始化数据
        """
        # 如果模块定义了内存，就先创建内存实例并分配必要的内存页
        if len(self.module.mem_sec) > 0:
            self.memory = Memory(self.module.mem_sec[0])

        for data in self.module.data_sec:
            for instr in data.offset:
                self.exec_instr(instr)

            # 指令执行完毕后，留在操作数栈顶的就是内存起始地址
            self.memory.write(self.pop_u64(), data.init)

    def init_globals(self):
        for global_var in self.module.global_sec:
            for instr in global_var.init:
                self.exec_instr(instr)
            self.globals.append(GlobalVar(global_var.type, self.pop_u64()))

    def init_funcs(self):
        self.link_native_funcs()
        for i, ft_idx in enumerate(self.module.func_sec):
            ft = self.module.type_sec[ft_idx]
            code = self.module.code_sec[i]
            self.funcs.append(new_internal_func(ft, code))

    def link_native_funcs(self):
        """外部函数的初始化"""
        for imp in self.module.import_sec:
            if imp.desc.tag == ImportTagFunc and imp.module == "env":
                ft = self.module.type_sec[imp.desc.func_type]
                name = imp.name
                if name == "print_char":
                    self.funcs.append(new_external_func(ft, print_char))
                elif name == "assert_true":
                    self.funcs.append(new_external_func(ft, assert_true))
                elif name == "assert_false":
                    self.funcs.append(new_external_func(ft, assert_false))
                elif name == "assert_eq_i32":
                    self.funcs.append(new_external_func(ft, assert_eq_i32))
                elif name == "assert_eq_i64":
                    self.funcs.append(new_external_func(ft, assert_eq_i64))
                elif name == "assert_eq_f32":
                    self.funcs.append(new_external_func(ft, assert_eq_f32))
                elif name == "assert_eq_f64":
                    self.funcs.append(new_external_func(ft, assert_eq_f64))
                else:
                    raise Exception("TODO")

    def init_table(self):
        if len(self.module.table_sec) > 0:
            self.table = Table(self.module.table_sec[0])
        for elem in self.module.elem_sec:
            for instr in elem.offset:
                self.exec_instr(instr)
            offset = self.pop_u32()
            for i, func_idx in enumerate(elem.init):
                self.table.set_elem(offset + i, self.funcs[func_idx])

    def enter_block(self, opcode, bt, instrs):
        """
        进入函数（或控制块）时使用
        """
        bp = self.stack_size - len(bt.param_types)
        cf = ControlFrame(opcode, bt, instrs, bp)
        self.push_control_frame(cf)
        if opcode == Call:
            self.local_0_idx = int(bp)

    def exit_block(self):
        cf = self.pop_control_frame()
        self.clear_block(cf)

    def clear_block(self, cf):
        results = self.pop_u64s(len(cf.bt.result_types))
        self.pop_u64s(self.stack_size - cf.bp)
        self.push_u64s(results)
        if cf.opcode == Call and self.control_depth > 0:
            last_call_frame, _ = self.top_call_frame()
            self.local_0_idx = int(last_call_frame.bp)

    def reset_block(self, cf):
        results = self.pop_u64s(len(cf.bt.param_types))
        self.pop_u64s(self.stack_size - cf.bp)
        self.push_u64s(results)

    def exec_code(self, idx):
        """一条一条执行函数指令"""
        code = self.module.code_sec[idx]
        for _, instr in enumerate(code.expr):
            self.exec_instr(instr)

    def exec_instr(self, instr):
        """指令分派逻辑：采用查表法"""
        instr_table[instr.opcode](self, instr.args)

    def loop(self, verbose_flag):
        depth = self.control_depth
        while self.control_depth >= depth:
            cf = self.top_control_frame
            if cf.pc == len(cf.instrs):
                self.exit_block()
            else:
                instr = cf.instrs[cf.pc]
                if verbose_flag:
                    print("PC={}, opcode={}, instrs={}, slots={}".format(cf.pc, instr.opcode,
                                                                         instr_table[instr.opcode].__name__,
                                                                         self.slots))
                cf.pc += 1
                self.exec_instr(instr)

def get_main_func_idx(module):
    for exp in module.export_sec:
        if exp.desc.tag == ImportTagFunc and exp.name == "main":
            return exp.desc.idx
    raise Exception("main func not found")

def exec_main_func(module, verbose_flag=False):
    vm = VM(module)
    vm.init_mem()
    vm.init_globals()
    vm.init_funcs()
    vm.init_table()
    if module.start_sec is not None:
        call(vm, module.start_sec)
    else:
        call(vm, get_main_func_idx(module))
    vm.loop(verbose_flag)


import yaml

from modulemd.components import ModuleComponents
from modulemd.content import ModuleContent
from modulemd.rpms import ModuleRPMs
from modulemd.profile import ModuleProfile

supported_mdversions = ( 0, )

class ModuleMetadata(object):
    """Class representing the whole module."""

    REPODATA_FILENAME = "modulemd"

    def __init__(self):
        """Creates a new ModuleMetadata instance."""
        self.mdversion = max(supported_mdversions)
        self.name = ""
        self.version = ""
        self.release = ""
        self.summary = ""
        self.description = ""
        self.module_licenses = set()
        self.content_licenses = set()
        self.buildrequires = dict()
        self.requires = dict()
        self.community = ""
        self.documentation = ""
        self.tracker = ""
        self.xmd = dict()
        self.profiles = dict()
        self.components = None

    def load(self, f):
        """Loads a metadata file into the instance.

        :param str f: File name to load
        """
        with open(f, "r") as infile:
            data = infile.read()
        self.loads(data)

    def loads(self, s):
        """Loads metadata from a string.

        :param str s: Raw metadata in YAML
        :raises ValueError: If the metadata is invalid or unsupported.
        """
        yml = yaml.safe_load(s)
        if "document" not in yml or yml["document"] != "modulemd":
            raise ValueError("The supplied data isn't a valid modulemd document")
        if "version" not in yml:
            raise ValueError("version is required")
        if yml["version"] not in supported_mdversions:
            raise ValueError("The supplied metadata version isn't supported")
        self.mdversion = yml["version"]
        if "data" not in yml or not isinstance(yml["data"], dict):
            return
        if "name" in yml["data"]:
            self.name = yml["data"]["name"]
        if "version" in yml["data"]:
            self.version = yml["data"]["version"]
        if "release" in yml["data"]:
            self.release = yml["data"]["release"]
        if "summary" in yml["data"]:
            self.summary = yml["data"]["summary"]
        if "description" in yml["data"]:
            self.description = str(yml["data"]["description"]).strip()
        if ("license" in yml["data"]
                and isinstance(yml["data"]["license"], dict)
                and "module" in yml["data"]["license"]
                and yml["data"]["license"]["module"]):
            self.module_licenses = set(yml["data"]["license"]["module"])
        if ("license" in yml["data"]
                and isinstance(yml["data"]["license"], dict)
                and "content" in yml["data"]["license"]):
            self.content_licenses = set(yml["data"]["license"]["content"])
        if ("dependencies" in yml["data"]
                and isinstance(yml["data"]["dependencies"], dict)):
            if ("buildrequires" in yml["data"]["dependencies"]
                    and yml["data"]["dependencies"]["buildrequires"]):
                self.buildrequires = yml["data"]["dependencies"]["buildrequires"]
            if ("requires" in yml["data"]["dependencies"]
                    and yml["data"]["dependencies"]["requires"]):
                self.requires = yml["data"]["dependencies"]["requires"]
        if "references" in yml["data"] and yml["data"]["references"]:
            if "community" in yml["data"]["references"]:
                self.community = yml["data"]["references"]["community"]
            if "documentation" in yml["data"]["references"]:
                self.documentation = yml["data"]["references"]["documentation"]
            if "tracker" in yml["data"]["references"]:
                self.tracker = yml["data"]["references"]["tracker"]
        if "xmd" in yml["data"]:
            self.xmd = yml["data"]["xmd"]
        if ("profiles" in yml["data"]
                and isinstance(yml["data"]["profiles"], dict)):
            for profile in yml["data"]["profiles"].keys():
                self.profiles[profile] = ModuleProfile()
                if "description" in yml["data"]["profiles"][profile]:
                    self.profiles[profile].description = \
                        str(yml["data"]["profiles"][profile]["description"])
                if "rpms" in yml["data"]["profiles"][profile]:
                    self.profiles[profile].rpms = \
                        set(yml["data"]["profiles"][profile]["rpms"])
        if ("components" in yml["data"]
                and isinstance(yml["data"]["components"], dict)):
            self.components = ModuleComponents()
            if "rpms" in yml["data"]["components"]:
                self.components.rpms = ModuleRPMs()
                if "dependencies" in yml["data"]["components"]["rpms"]:
                    self.components.rpms.dependencies = \
                        yml["data"]["components"]["rpms"]["dependencies"]
                if "api" in yml["data"]["components"]["rpms"]:
                    self.components.rpms.api = \
                        set(yml["data"]["components"]["rpms"]["api"])
                if "packages" in yml["data"]["components"]["rpms"]:
                    for p, e in yml["data"]["components"]["rpms"]["packages"].items():
                        extras = dict()
                        extras["rationale"] = e["rationale"]
                        if "repository" in e:
                            extras["repository"] = e["repository"]
                        if "cache" in e:
                            extras["cache"] = e["cache"]
                        if "commit" in e:
                            extras["commit"] = e["commit"]
                        if "arches" in e:
                            extras["arches"] = e["arches"]
                        if "multilib" in e:
                            extras["multilib"] = e["multilib"]
                        self.components.rpms.add_package(p, **extras)
                if "filter" in yml["data"]["components"]["rpms"]:
                    self.components.rpms.filter = \
                        set(yml["data"]["components"]["rpms"]["filter"])

    def dump(self, f):
        """Dumps the metadata into the supplied file.

        :param str f: File name of the destination
        """
        data = self.dumps()
        with open(f, "w") as outfile:
            outfile.write(data)

    def dumps(self):
        """Dumps te metadata into a string.

        :rtype: str
        :raises Exception: If metadata validation fails
        """
        if not self.validate:
            raise Exception("Metadata validation failed")
        data = dict()
        # header
        data["document"] = "modulemd"
        data["version"] = self.mdversion
        # data
        data["data"] = dict()
        data["data"]["name"] = self.name
        data["data"]["version"] = self.version
        data["data"]["release"] = self.release
        data["data"]["summary"] = self.summary
        data["data"]["description"] = self.description
        data["data"]["license"] = dict()
        data["data"]["license"]["module"] = list(self.module_licenses)
        if self.content_licenses:
            data["data"]["license"]["content"] = list(self.content_licenses)
        if self.buildrequires or self.requires:
            data["data"]["dependencies"] = dict()
            if self.buildrequires:
                data["data"]["dependencies"]["buildrequires"] = self.buildrequires
            if self.requires:
                data["data"]["dependencies"]["requires"] = self.requires
        if self.community or self.documentation or self.tracker:
            data["data"]["references"] = dict()
            if self.community:
                data["data"]["references"]["community"] = self.community
            if self.documentation:
                data["data"]["references"]["documentation"] = self.documentation
            if self.tracker:
                data["data"]["references"]["tracker"] = self.tracker
        if self.xmd:
            data["data"]["xmd"] = self.xmd
        if self.profiles:
            data["data"]["profiles"] = dict()
            for profile in self.profiles.keys():
                if self.profiles[profile].description:
                    if profile not in data["data"]["profiles"]:
                        data["data"]["profiles"][profile] = dict()
                    data["data"]["profiles"][profile]["description"] = \
                        str(self.profiles[profile].description)
                if self.profiles[profile].rpms:
                    if profile not in data["data"]["profiles"]:
                        data["data"]["profiles"][profile] = dict()
                    data["data"]["profiles"][profile]["rpms"] = \
                        list(self.profiles[profile].rpms)
        if self.components:
            data["data"]["components"] = dict()
            if self.components.rpms:
                data["data"]["components"]["rpms"] = dict()
                data["data"]["components"]["rpms"]["dependencies"] = \
                    self.components.rpms.dependencies
                data["data"]["components"]["rpms"]["api"] = \
                    list(self.components.rpms.api)
                if self.components.rpms.packages:
                    data["data"]["components"]["rpms"]["packages"] = dict()
                    for p, e in self.components.rpms.packages.items():
                        extra = dict()
                        extra["rationale"] = e["rationale"]
                        if "commit" in e:
                            extra["commit"] = e["commit"]
                        if "repository" in e:
                            extra["repository"] = e["repository"]
                        if "cache" in e:
                            extra["cache"] = e["cache"]
                        if "arches" in e:
                            extra["arches"] = e["arches"]
                        if "multilib" in e:
                            extra["multilib"] = e["multilib"]
                        data["data"]["components"]["rpms"]["packages"][p] = \
                            extra
                if self.components.rpms.filter:
                    data["data"]["components"]["rpms"]["filter"] = \
                        list(self.components.rpms.filter)
        return yaml.safe_dump(data)

    def validate(self):
        """Performs an in-depth validation of the metadata instance.

        :rtype: bool
        :raises TypeError: If properties are holding data of incorrect type
        :raises ValueError: If properties are holding invalid data
        """
        if not isinstance(self.mdversion, int):
            raise TypeError("mdversion must be an integer")
        if not isinstance(self.name, str):
            raise TypeError("name must be a string")
        if not isinstance(self.version, str):
            raise TypeError("version must be a string")
        if not isinstance(self.release, str):
            raise TypeError("release must be a string")
        if not isinstance(self.summary, str):
            raise TypeError("summary must be a string")
        if not isinstance(self.description, str):
            raise TypeError("description must be a string")
        if not isinstance(self.module_licenses, set):
            raise TypeError("module_licenses must be a set")
        for l in self.module_licenses:
            if not isinstance(l, str):
                raise TypeError("module_licenses must be a set of strings")
        if not isinstance(self.content_licenses, set):
            raise TypeError("content_licenses must be a set")
        for l in self.content_licenses:
            if not isinstance(l, str):
                raise TypeError("content_licenses must be a set of strings")
        if not isinstance(self.buildrequires, dict):
            raise TypeError("buildrequires must be a dictionary")
        for n, v in self.buildrequires.items():
            if not isinstance(n, str) or not isinstance(v, str):
                raise TypeError("buildrequires keys and values must be strings")
        if not isinstance(self.requires, dict):
            raise TypeError("requires must be a dictionary")
        for n, v in self.requires.items():
            if not isinstance(n, str) or not isinstance(v, str):
                raise TypeError("requires keys and values must be strings")
        if not isinstance(self.community, str):
            raise TypeError("community must be a string")
        if not isinstance(self.documentation, str):
            raise TypeError("documentation must be a string")
        if not isinstance(self.tracker, str):
            raise TypeError("tracker must be a string")
        if self.xmd is not None and not isinstance(self.xmd, dict):
            raise TypeError(
                "xmd must be a dictionary or null, current value: {!r}".format(self.xmd)
            )
        if not isinstance(self.profiles, dict):
            raise TypeError("profiles must be a dictionary")
        for p in self.profiles.keys():
            if not isinstance(p, str):
                raise TypeError("profiles keys must be strings")
            if not isinstance(self.profiles[p], ModuleProfile):
                raise TypeError("profiles values must be instances of ModuleProfile")
            if not isinstance(self.profiles[p].description, str):
                raise TypeError("profile description must be string")
            if not isinstance(self.profiles[p].rpms, set):
                raise TypeError("profile rpms must be sets")
            for ps in self.profiles[p].rpms:
                if not isinstance(ps, str):
                    raise TypeError("profile rpms must be sets of strings")
        if not isinstance(self.components, ModuleComponents) \
           and self.components is not None:
            raise TypeError("components must be an instance of ModuleComponents")
        if self.components:
            if self.components.rpms:
                if not isinstance(self.components.rpms, ModuleRPMs):
                    raise TypeError("rpms must be an instance of ModuleRPMs")
                if not isinstance(self.components.rpms.dependencies, bool):
                    raise TypeError("rpms.dependencies must be a boolean")
                if not isinstance(self.components.rpms.api, set):
                    raise TypeError("rpms.api must be a set")
                for a in self.components.rpms.api:
                    if not isinstance(a, str):
                        raise TypeError("rpms.api must be a set of strings")
                if not isinstance(self.components.rpms.filter, set):
                    raise TypeError("rpms.filter must be a set")
                for a in self.components.rpms.filter:
                    if not isinstance(a, str):
                        raise TypeError("rpms.filter must be a set of strings")
                if self.components.rpms.packages:
                    if not isinstance(self.components.rpms.packages, dict):
                        raise TypeError("rpms.packages must be a dictionary")
                    for p, e in self.components.rpms.packages.items():
                        if not isinstance(p, str):
                            raise TypeError("rpms.packages keys must be strings")
                        if not isinstance(e, dict):
                            raise TypeError("rpms.packages values must dictionaries")
                        for k, v in e.items():
                            if not isinstance(k, str):
                                raise TypeError("rpms extras keys must be strings")
                            if k == "rationale" and v:
                                if not isinstance(v, str):
                                    raise TypeError("rpms rationale must be a string")
                            if k == "commit" and v:
                                if not isinstance(v, str):
                                    raise TypeError("rpms commit must be a string")
                            if k == "repository" and v:
                                if not isinstance(v, str):
                                    raise TypeError("rpms repository must be a string")
                            if k == "cache" and v:
                                if not isinstance(v, str):
                                    raise TypeError("rpms cache must be a string")
                            if k == "arches" and v:
                                if not isinstance(v, list):
                                    raise TypeError("rpms arches must be a list")
                                for s in v:
                                    if not isinstance(s, str):
                                        raise TypeError("arches must be a list of strings")
                            if k == "multilib" and v:
                                if not isinstance(v, list):
                                    raise TypeError("rpms multilib must be a list")
                                for s in v:
                                    if not isinstance(s, str):
                                        raise TypeError("multilib must be a list of strings")
        if not self.name:
            raise ValueError("name is required")
        if not self.version:
            raise ValueError("version is required")
        if not self.release:
            raise ValueError("release is required")
        if not self.summary:
            raise ValueError("summary is required")
        if not self.description:
            raise ValueError("description is required")
        if not self.module_licenses:
            raise ValueError("at least one module license is required")
        if self.components:
            if self.components.rpms:
                for p, e in self.components.rpms.packages.items():
                    if "rationale" not in e:
                        raise ValueError(p, "has no rationale")
        # TODO: Validate dependency version formats
        return True

    @property
    def mdversion(self):
        """An int property representing the metadata format version used.

        This is automatically set to the highest supported version for
        new objects or set by the loaded document.  This value can be
        changed to one of the supported_mdversions to alter the output
        format.
        """
        return self._mdversion

    @mdversion.setter
    def mdversion(self, i):
        if i not in supported_mdversions:
            raise ValueError("Unsupported metadata version")
        self._mdversion = int(i)

    @property
    def name(self):
        """A string property representing the name of the module."""
        return self._name

    @name.setter
    def name(self, s):
        self._name = str(s)

    @property
    def version(self):
        """A string property representing the version of the module."""
        return self._version

    @version.setter
    def version(self, s):
        self._version = str(s)

    @property
    def release(self):
        """A string property representing the release of the module."""
        return self._release

    @release.setter
    def release(self, s):
        self._release = str(s)

    @property
    def summary(self):
        """A string property representing a short summary of the module."""
        return self._summary

    @summary.setter
    def summary(self, s):
        self._summary = str(s)

    @property
    def description(self):
        """A string property representing a detailed description of the
        module."""
        return self._description

    @description.setter
    def description(self, s):
        self._description = str(s)

    @property
    def module_licenses(self):
        """A set of strings, a property, representing the license terms
        of the module itself."""
        return self._module_licenses

    @module_licenses.setter
    def module_licenses(self, ss):
        if not isinstance(ss, set):
            raise TypeError("module_licenses requires a set")
        self._module_licenses = set([str(x) for x in ss])

    def add_module_license(self, s):
        """Adds a module license to the set.

        :param str s: License name
        """
        self._module_licenses.add(str(s))

    def del_module_license(self, s):
        """Removes the supplied license from the module licenses set.

        :param str s: License name
        """
        self._module_licenses.discard(str(s))

    def clear_module_licenses(self):
        """Clears the module licenses set."""
        self._module_licenses.clear()

    @property
    def content_licenses(self):
        """A set of strings, a property, representing the license terms
        of the module contents."""
        return self._content_licenses

    @content_licenses.setter
    def content_licenses(self, ss):
        if not isinstance(ss, set):
            raise TypeError("content_licenses requires a set")
        self._content_licenses = set([str(x) for x in ss])

    def add_content_license(self, s):
        """Adds a content license to the set.

        :param str s: License name
        """
        self._content_licenses.add(str(s))

    def del_content_license(self, s):
        """Removes the supplied license from the content licenses set.

        :param str s: License name
        """
        self._content_licenses.discard(str(s))

    def clear_content_licenses(self):
        """Clears the content licenses set."""
        self._content_licenses.clear()

    @property
    def requires(self):
        """A dictionary property representing the required dependencies of
        the module.

        Keys are the required module names (strings), values are their
        mininum required versions (also strings).
        """
        return self._requires

    @requires.setter
    def requires(self, d):
        if d and not isinstance(d, dict):
            raise TypeError("Incorrect data type passed for requires")
        if d:
            self._requires = { str(k) : str(v) for k, v in d.items() }
        else:
            self._requires = dict()

    def add_requires(self, n, v):
        """Adds a required module dependency.

        :param str n: Required module name
        :param str v: Required module version
        """
        self._requires[str(n)] = str(v)

    update_requires = add_requires

    def del_requires(self, n):
        """Deletes the dependency on the supplied module.

        :param str n: Required module name
        """
        if str(n) in self._requires:
            del self._requires[str(n)]

    def clear_requires(self):
        """Removes all required runtime dependencies."""
        self._requires = dict()

    @property
    def buildrequires(self):
        """A dictionary property representing the required build dependencies
        of the module.

        Keys are the required module names (strings), values are their
        minimum required versions (also strings).
        """
        return self._buildrequires

    @buildrequires.setter
    def buildrequires(self, d):
        if d and not isinstance(d, dict):
            raise TypeError("Incorrect data type passed for buildrequires")
        self._buildrequires = { str(k) : str(v) for k, v in d.items() }

    def add_buildrequires(self, n, v):
        """Adds a module build dependency.

        :param str n: Required module name
        :param str v: Required module version
        """
        self._buildrequires[str(n)] = str(v)

    update_buildrequires = add_buildrequires

    def del_buildrequires(self, n):
        """Deletes the build dependency on the supplied module.

        :param str n: Required module name
        """
        if str(n) in self._buildrequires:
            del self._buildrequires[str(n)]

    def clear_buildrequires(self):
        """Removes all build dependencies."""
        self._buildrequires = dict()

    @property
    def community(self):
        """A string property representing a link to the upstream community
        for this module."""
        return self._community

    @community.setter
    def community(self, s):
        self._community = str(s)

    @property
    def documentation(self):
        """A string property representing a link to the upstream
        documentation for this module."""
        return self._documentation

    @documentation.setter
    def documentation(self, s):
        self._documentation = str(s)

    @property
    def tracker(self):
        """A string property representing a link to the upstream bug tracker
        for this module."""
        return self._tracker

    @tracker.setter
    def tracker(self, s):
        self._tracker = str(s)

    @property
    def xmd(self):
        """A dictionary property containing user-defined data."""
        return self._xmd

    @xmd.setter
    def xmd(self, d):
        if d and not isinstance(d, dict):
            raise TypeError("Incorrect data supplied for xmd")
        self._xmd = d

    @property
    def profiles(self):
        """A dictionary property representing the module profiles."""
        return self._profiles

    @profiles.setter
    def profiles(self, o):
        if not isinstance(o, dict):
            raise TypeError("Incorrect data types passed for profiles")
        self._profiles = o

    @property
    def components(self):
        """A ModuleComponents instance property representing the components
        defining the module."""
        return self._components

    @components.setter
    def components(self, o):
        if o and not isinstance(o, ModuleComponents):
            raise TypeError("Incorrect data type passed for components")
        self._components = o


from menu import Menu, MenuItem
from coffee_maker import CoffeeMaker
from money_machine import MoneyMachine

to_make=True
menu=Menu()
coffee_maker=CoffeeMaker()
money_machine=MoneyMachine()
# cost={
#     "latte":2.5,
#     "espresso":1.5,
#     "cappuccino":3
# }

while to_make:
    order=input("what do you want?:")

    if order=="report":
        coffee_maker.report()
        money_machine.report()
    if order=="off":
        to_make=False

    drink = menu.find_drink(order)

    if coffee_maker.is_resource_sufficient(drink):
        if money_machine.make_payment(drink.cost):
            coffee_maker.make_coffee(drink)


from pprint import pprint
import statistics

DEBUG = False
PATH = f"C:\\work\\SVN\\adventofcode\\2021\\day8_{'sample' if DEBUG else 'input'}.txt"

with open(PATH, 'r') as f:
    #inp2 = [tuple(parse.parse("{:d},{:d} -> {:d},{:d}",
                  #l.strip()).fixed) for l in f.readlines()]
    # print(inp2)
    inp = [[v.strip().split(" ") for v in i.strip().split("|")] for i in f.readlines()]
    print(inp)

def part1():
    ones = 0
    fours = 0
    sevens = 0
    eights = 0
    for codes in [k[1] for k in inp]:
        for code in codes:
            if len(code) == 2:
                ones += 1
            elif len(code) == 4:
                fours += 1
            elif len(code) == 3:
                sevens += 1
            elif len(code) == 7:
                eights += 1
    print(f"Part 1: {ones + fours + sevens + eights}")

def part2():
    sum_all = 0
    for all_codes, answer_codes in inp:
        d_one = [c for c in all_codes if len(c) == 2][0]
        d_four = [c for c in all_codes if len(c) == 4][0]
        d_seven = [c for c in all_codes if len(c) == 3][0]
        d_eight = [c for c in all_codes if len(c) == 7][0]

        d_zero_six_nine = [c for c in all_codes if len(c) == 6]
        d_six = [c for c in d_zero_six_nine if len([value for value in d_one if value in c]) == 1][0]
        d_nine = [c for c in d_zero_six_nine if len([value for value in d_four if value in c]) == 4][0]
        d_zero = [c for c in d_zero_six_nine if c != d_six and c != d_nine][0]
        d_two_three_five = [c for c in all_codes if len(c) == 5]
        d_five = [c for c in d_two_three_five if len([value for value in d_four if value in c]) == 3 and len([value for value in d_one if value in c]) == 1][0]
        d_two = [c for c in d_two_three_five if len([value for value in d_four if value in c]) == 2 and len([value for value in d_one if value in c]) == 1][0]
        d_three = [c for c in d_two_three_five if len([value for value in d_one if value in c]) == 2][0]
        digets = ["".join(sorted(a)) for a in [d_zero, d_one, d_two, d_three, d_four, d_five, d_six, d_seven, d_eight, d_nine]]
        answer = ''
        for a in ["".join(sorted(a)) for a in answer_codes]:
            answer += str(digets.index(a))
        sum_all += int(answer)

    print(f"Part 2: {sum_all}")

part1()
part2()


# -*- coding: utf-8 -*-
# @Time    : 2017/7/16 23:55
# @Author  : chen
# @Site    :
# @File    : vector_util.py
# @Software: PyCharm
import pandas as pd

from load.import_util import file_to_dict, file_to_list

def deal_ida_format(types):
    # f = open("D:/python/workspace/TextProcess/segment/data/lda/one-annals.lda-c", "r")
    f = open("D:/python/workspace/TextProcess/segment/data/lda/"+ types +".lda-c", "r")

    total_words_nums = []
    total_words_freq = []
    for line in f.readlines():
        datas = line.split()
        total_words_nums.append(datas[0])
        word_freq = {}
        for data in datas:
            dict = data.split(":")
            if len(dict) == 2:
                word_freq[dict[0]] = dict[1]
        total_words_freq.append(word_freq)

    # print total_words_nums
    # for key in total_words_freq:
    #     print key

    return total_words_nums, total_words_freq

# deal_ida_format()

# all_extend_dict left join tokens2

def account_dict2id(worddict_path, word_dict, types):
    all_extend_ids = {}

    lda_path = "D:/python/workspace/TextProcess/segment/data/lda/"
    v1_tokens2id = file_to_dict(lda_path, types + ".tokens2id")

    all_extend_list = file_to_list(worddict_path, word_dict)

    for word in all_extend_list:
        if word in v1_tokens2id:
            all_extend_ids[word] = v1_tokens2id[word]

    # for word in all_extend_ids:
    #     print word, all_extend_ids[word]
    # print len(all_extend_ids)

    return all_extend_ids

# account_dict2id()

def compute_account_freq(worddict_extend_path, word_dict, types):
    all_extend_ids = account_dict2id(worddict_extend_path, word_dict, types)
    # ids_set = all_extend_ids.keys()
    ids_set = set(all_extend_ids.values())

    pure_words_nums, total_words_freq = deal_ida_format(types)

    nums = []
    total_words_nums = []
    join_words = []
    for words_freq in total_words_freq:
        words_num = 0
        for freq in words_freq.values():
            words_num += int(freq)
        total_words_nums.append(words_num)

        num = 0
        key_set = set(words_freq.keys())
        join_set = ids_set.intersection(key_set)
        join_words.append(len(join_set))
        for id in join_set:
            num += int(words_freq[id])

        nums.append(num)
    st = pd.DataFrame(data={"MDA总词数": total_words_nums, "(MDA中)宏观词汇个数": nums, "纯的MDA总词数": pure_words_nums,
                            "纯的(MDA中)宏观词汇个数": join_words})

    file2id = pd.read_csv(
        "D:/python/workspace/TextProcess/dataset/output/csv/" + types.split("_")[1] + "_file2id.csv",
        dtype={'code': str})
    statistic = file2id.join(st, on="id")
    statistic.to_csv(
        "D:/python/workspace/TextProcess/segment/statistic/" + types + "/" + word_dict.split(".")[0] + ".csv")

    # print total_words_nums
    # print nums

#
# def connect_id():
#     median_file2id = pd.read_csv("../../dataset/output/txt/v1_file2id.csv", dtype={'code':str})
#     st = pd.read_csv("st.csv")
#
#     statistic = median_file2id.merge(st, on="id")
#     statistic.to_csv("statistic.csv")

if __name__ == '__main__':
    # connect_id()
    compute_account_freq()


import random
import sqlite3

def sql_create():
    global db, cursor
    db = sqlite3.connect("bot.sqlite3")
    cursor = db.cursor()

    if db:
        print("База данных подключена!")

    db.execute("CREATE TABLE IF NOT EXISTS anketa "
               "(id INTEGER PRIMARY KEY, "
               "name VARCHAR (100), "
               "name VARCHAR (100), "
               "direction VARCHAR(100), "
               "age INTEGER (20), "
               "group VARCHAR(10), ")
    db.commit()

async def sql_command_insert(state):
    async with state.proxy() as data:
        cursor.execute("INSERT INTO anketa VALUES (?, ?, ?, ?, ?, ?, ?)",
                       tuple(data.values()))
        db.commit()

async def sql_command_random():
    result = cursor.execute("SELECT * FROM anketa").fetchall()
    random_user = random.choice(result)
    return random_user

async def sql_command_all():
    return cursor.execute("SELECT * FROM anketa").fetchall()

async def sql_command_delete(id):
    cursor.execute("DELETE FROM anketa WHERE id = ?", (id,))
    db.commit()


import numpy as np
import matplotlib.pyplot as plt

black1 = np.zeros((50,50))
black2 = black1.copy()
white1 = np.ones((50,50))
white2 = white1.copy()
row1 = np.hstack((black1,white1))
row2 = np.hstack((white2, black2))
full = np.vstack((row1,row2))
plt.figure()
plt.imshow(full, cmap='gray')
plt.show()


#!/bin/python3
import os
import pandas
import argparse
import traceback
import numpy as np
from datetime import datetime, timedelta

# lisflood
import lisf1
from lisflood.global_modules.decorators import Cache

from liscal import hydro_model, templates, config, subcatchment, calibration, objective

class ScalingModel():
    def __init__(self, cfg, subcatch, lis_template, lock_mgr, objective):

        self.cfg = cfg
        self.subcatch = subcatch

        self.lis_template = lis_template

        self.lock_mgr = lock_mgr

        self.objective = objective

        self.start = cfg.forcing_start.strftime('%d/%m/%Y %H:%M')
        self.end = cfg.forcing_end.strftime('%d/%m/%Y %H:%M')

    def init_run(self):

        # dummy Individual, doesn't matter here
        param_ranges = self.cfg.param_ranges
        Individual = 0.5*np.ones(len(param_ranges))

        cfg = self.cfg

        gen = self.lock_mgr.get_gen()
        run_id = str(gen)

        out_dir = os.path.join(self.subcatch.path_out, run_id)
        os.makedirs(out_dir, exist_ok=True)

        parameters = self.objective.get_parameters(Individual)

        prerun_file, run_file = self.lis_template.write_init(run_id, self.start, self.end, self.start, self.end, cfg.param_ranges, parameters)

        # -i option to exit after initialisation, we just load the inputs map in memory
        lisf1.main(prerun_file, '-i')
        lisf1.main(run_file, '-i')

        # store lisflood cache size to make sure we don't load anything else after that
        self.lisflood_cache_size = Cache.size()

    def run(self, Individual):

        cfg = self.cfg

        gen = self.lock_mgr.get_gen()
        run = self.lock_mgr.increment_run()
        print('Generation {}, run {}'.format(gen, run))

        run_id = '{}_{}'.format(gen, run)

        out_dir = os.path.join(self.subcatch.path_out, run_id)
        os.makedirs(out_dir, exist_ok=True)

        parameters = self.objective.get_parameters(Individual)

        prerun_file, run_file = self.lis_template.write_template(run_id, self.start, self.end, self.start, self.end, cfg.param_ranges, parameters)

        lisf1.main(prerun_file, '-v')
        lisf1.main(run_file, '-v')

def scaling_subcatchment(cfg, obsid, subcatch, n_runs):

    lis_template = templates.LisfloodSettingsTemplate(cfg, subcatch)

    lock_mgr = calibration.LockManager(cfg.num_cpus)

    lock_mgr.set_gen(cfg.num_cpus)

    obj = objective.ObjectiveKGE(cfg, subcatch, read_observations=False)

    model = ScalingModel(cfg, subcatch, lis_template, lock_mgr, obj)

    # load forcings and input maps in cache
    # required in front of processing pool
    # otherwise each child will reload the maps
    model.init_run()

    dummy_params = [0.5*np.ones(len(cfg.param_ranges)) for i in range(n_runs)]

    scaling_map, pool = lock_mgr.create_mapping()

    mapped = list(scaling_map(model.run, dummy_params))

    if pool:
        pool.close()

class ConfigScaling(config.Config):

    def __init__(self, settings_file, num_cpus):
        super().__init__(settings_file)

        self.num_cpus = int(num_cpus)

        # paths
        self.subcatchment_path = self.parser.get('Path','subcatchment_path')

        # Date parameters
        self.forcing_start = datetime.strptime(self.parser.get('Main','forcing_start'),"%d/%m/%Y %H:%M")  # Start of forcing
        self.forcing_end = datetime.strptime(self.parser.get('Main','forcing_end'),"%d/%m/%Y %H:%M")  # Start of forcing
        self.timestep = int(self.parser.get('Main', 'timestep'))  # in minutes
        self.prerun_timestep = 360  # in minutes
        if self.prerun_timestep != 360 and self.prerun_timestep != 1440:
            raise Exception('Pre-run timestep {} not supported'.format(self.prerun_timestep))

        # Load param ranges file
        self.param_ranges = pandas.read_csv(self.parser.get('Path','param_ranges'), sep=",", index_col=0)

        # template
        self.lisflood_template = self.parser.get('Templates','LISFLOODSettings')

        # pcraster commands
        self.pcraster_cmd = {}
        for execname in ["pcrcalc", "map2asc", "asc2map", "col2map", "map2col", "mapattr", "resample", "readmap"]:
            self.pcraster_cmd[execname] = execname

if __name__ == '__main__':

    parser = argparse.ArgumentParser()
    parser.add_argument('settings', help='Settings file')
    parser.add_argument('stations_data', help='Stations metadata CSV file')
    parser.add_argument('obsid', help='Station obsid')
    parser.add_argument('n_cpus', help='Station obsid')
    parser.add_argument('n_runs', help='Station obsid')
    args = parser.parse_args()

    print('  - obsid: {}'.format(args.obsid))
    print('  - settings file: {}'.format(args.settings))
    obsid = int(args.obsid)
    cfg = ConfigScaling(args.settings, args.n_cpus)

    print(">> Reading stations.csv file...")
    stations = pandas.read_csv(args.stations_data, sep=",", index_col=0)
    try:
        station_data = stations.loc[obsid]
    except KeyError as e:
        print(stations)
        raise Exception('Station {} not found in stations file'.format(obsid))

    subcatch = subcatchment.SubCatchment(cfg, obsid, station_data, create_links=False)

    scaling_subcatchment(cfg, obsid, subcatch, int(args.n_runs))


# -*- coding: utf-8 -*-
"""
Created on Fri Aug 17 05:15:30 2018
@author: LeeMH
"""
from bs4 import BeautifulSoup
from datetime import datetime, timedelta
import requests
import re

from utils.processor_checker import timeit
from gobble.module.crawler import Crawler

class NaverRealtimeCrawler(Crawler):
    '''
    네이버 증권 실시간 속보 크롤러
    '''
    def __init__(self):
        super().__init__()

    # func (기능): all (오늘 날짜의 모든 뉴스를 크롤링), new (1page만 크롤링)
    @timeit
    def create_url_list(self, func):
        req = self.request_get(self.real_time_list.format(self.rt_today, 1), self.user_agent)
        print(self.real_time_list.format(self.rt_today, 1))
        soup = self.html_parser(req)
        url_list = []
        if func == 'new':
            url_data = self.find_navernews_url(soup, url_list)

        elif func == 'all':
            pgRR = self.soup_find(soup, 'td', {'class':'pgRR'})
            last_page = self.soup_find(pgRR, 'a')['href'][-3:]
            last_page = re.findall("\d+", last_page)[0]

            sub_list = []
            for i in range(1,int(last_page)+1):
                req = self.request_get(self.real_time_list.format(self.rt_today, i), self.user_agent)
                sub_soup = self.html_parser(req)
                url_list += self.find_navernews_url(sub_soup, sub_list)
            url_data = url_list
        else:
            print("Choose between 'all' and 'new'")
        url_data = list(set(url_data))
        print(len(url_data))
        real_time_url = [self.soup_find(sub, 'a')['href'].replace('§', '&sect') for sub in url_data]
        return real_time_url

    @timeit
    def get_data(self, url_list, checklist):
        url_list = url_list
        data_list = []
        for url in url_list:
            self.req = self.request_get(self.fin_nhn.format(url), self.user_agent)
            soup = self.html_parser(self.req)
            url = self.fin_nhn.format(url)
            title = self.soup_find(soup, 'h3').text.replace('\n','').replace('\t','').strip()
            checkurl = re.sub(r'&page=\d+$', '', url)
            if checkurl in checklist:
                print('Already up-to-date.')
                continue
            upload_time = self.soup_find(soup, 'span', {'class':'article_date'}).text
            media = self.soup_find(soup, 'span', {'class':'press'}).img['title']
            data_dict = {'title':title, 'media':media, 'url':checkurl, 'data_type':'R', 'upload_time': upload_time}
            data_list.append(data_dict)
        print(len(data_list))
        return data_list


import cv2
from pykuwahara import kuwahara

image = cv2.imread('selfie.jpg')
image = (image / 255).astype('float32')     # pykuwahara supports float32 as well

lab_image = cv2.cvtColor(image, cv2.COLOR_BGR2Lab)
l, a, b = cv2.split(lab_image)

hsv_image = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
h, s, v = cv2.split(hsv_image)

filt1 = kuwahara(image, method='gaussian', radius=5, sigma=2., image_2d=l)
filt2 = kuwahara(image, method='gaussian', radius=5, sigma=2., image_2d=v)
#filt = kuwahara(lab_image, method='gaussian', radius=5, sigma=2., image_2d=l)

cv2.imwrite('selfie-kfilt-gaus1.jpg', filt1 * 255)
cv2.imwrite('selfie-kfilt-gaus2.jpg', filt2 * 255)
#cv2.imwrite('selfie-kfilt-gaus.jpg', cv2.cvtColor(filt, cv2.COLOR_Lab2BGR) * 255)


# Testzone para o apêndice

import apendice as ap
import matplotlib.pyplot as plt

#%% Plotando os sharp_test

## Sinal 1

vector1 = ap.sharpe_test_1(combined = combined, tam_p = 0.1, qtde = 200, inverso = True)

plt.hist(vector1.iloc[:,0], bins = 40)
plt.ylabel('Quantas vezes')
plt.xlabel('Sharpe')
plt.title('Para o Sinal 1')
plt.show()

## Sinal 2

vector2 = ap.sharpe_test_2(combined = combined, tam_p = 0.1, qtde = 200, inverso = True)

plt.hist(vector2.iloc[:,0], bins = 40)
plt.ylabel('Quantas vezes')
plt.xlabel('Sharpe')
plt.title('Para o Sinal 2')
plt.show()

## Sinal 3

vector3 = ap.sharpe_test_3(combined = combined, tam_p = 0.1, qtde = 200, inverso = True, dias = 17)

plt.hist(vector3.iloc[:,0], bins = 40)
plt.ylabel('Quantas vezes')
plt.xlabel('Sharpe')
plt.title('Para o Sinal 3')
plt.show()

## Sinal 4

vector4 = ap.sharpe_test_4(combined = combined, tam_p = 0.1, qtde = 200, inverso = True, dias = 21)

plt.hist(vector4.iloc[:,0], bins = 40)
plt.ylabel('Quantas vezes')
plt.xlabel('Sharpe')
plt.title('Para o Sinal 4')
plt.show()

#%% Avaliando a normalização via correlação média
## Se quer ver a avaliação, insira 1

ap.av_corr_med(insert = 0)


import math

def get_code_value(input):
    min_val = 0
    max_val = 2**len(input) - 1

    for char in input:
        mid_diff_val = (max_val - min_val) / 2
        if char in ['F', 'L']:  # Lower half
            max_val = math.floor(max_val - mid_diff_val)
        if  char in ['B', 'R']:  # Upper half
            min_val = math.ceil(max_val - mid_diff_val)

    if min_val == max_val:
        return min_val

    return -1   # Incomplete

def get_seat_id(row, column):
    return row * 8 + column

def separate_code(input):
    l_pos = input.find('L')
    r_pos = input.find('R')
    col_start = r_pos if (l_pos < 0 or (r_pos < l_pos and r_pos > 0)) else l_pos
    return (input[:col_start], input[col_start:])

def get_seat_from_code(input_code):
    row_code, col_code = separate_code(input_code)
    row_num = get_code_value(row_code)
    col_num = get_code_value(col_code)
    seat_id = get_seat_id(row_num, col_num)
    if seat_id == 3264: print(row_code, row_num, col_num, seat_id)
    return seat_id

def get_seats_from_code_list(input_code_list):
    return [get_seat_from_code(input_code) for input_code in input_code_list]

def get_seats_list(input_filename):
    f = open(input_filename, "r")
    seat_code_list = [line.strip() for line in f.readlines()]
    return get_seats_from_code_list(seat_code_list)

def find_missing_seat(seat_list):
    seat_list.sort()
    for idx, seat in enumerate(seat_list):
        if idx > 0 and seat - seat_list[idx-1] != 1: return seat - 1

if __name__ == "__main__":
    test_input = ["BFFFBBFRRR", "FFFBBBFRRR", "BBFFBBFRLL"]
    part_one_seat_list = get_seats_list("../real-input.txt")
    part_one_max_seat = max(part_one_seat_list)
    part_two_missing_seat = find_missing_seat(part_one_seat_list)
    print("Part 1: The highest seat ID is {}.".format(part_one_max_seat))
    print("Part 2: The missing seat ID is {}.".format(part_two_missing_seat))


from __future__ import print_function

import os.path
import sys
import densenet
import numpy as np
import sklearn.metrics as metrics

from keras.datasets import cifar10
from keras.utils import np_utils
from keras.preprocessing.image import ImageDataGenerator
from keras.optimizers import Adam
from keras.callbacks import ModelCheckpoint, ReduceLROnPlateau, TensorBoard
from keras import backend as K

batch_size = 100
nb_classes = 10
nb_epoch = 40

img_rows, img_cols = 32, 32
img_channels = 3

img_dim = (img_channels, img_rows, img_cols) if K.image_dim_ordering() == "th" else (img_rows, img_cols, img_channels)
depth = 40
nb_dense_block = 3
growth_rate = 12
nb_filter = -1
dropout_rate = 0.0  # 0.0 for data augmentation
if len(sys.argv) > 1:
    augment = sys.argv[1]
else:
    augment = 'false'

(trainX, trainY), (testX, testY) = cifar10.load_data()

trainX = trainX.astype('float32')
testX = testX.astype('float32')

trainX = densenet.preprocess_input(trainX)
testX = densenet.preprocess_input(testX)

Y_train = np_utils.to_categorical(trainY, nb_classes)
Y_test = np_utils.to_categorical(testY, nb_classes)

# GENERATOR
generator = ImageDataGenerator(rotation_range=15,
                               width_shift_range=5. / 32,
                               height_shift_range=5. / 32,
                               horizontal_flip=True)

generator.fit(trainX, seed=0)

# MODELS

model2k = densenet.DenseNet(img_dim, classes=nb_classes, depth=depth, nb_dense_block=nb_dense_block,
                            growth_rate=growth_rate, nb_filter=nb_filter, dropout_rate=dropout_rate, weights=None,
                            bottleneck=True, growth_rate_factor=2)

print("Models created")

# 2K MODEL
print("Building model 2k...")
model2k.summary()
optimizer = Adam(lr=1e-3)  # Using Adam instead of SGD to speed up training
model2k.compile(loss='categorical_crossentropy', optimizer=optimizer, metrics=["accuracy"])
print("Finished compiling")

# Load model
weights_file_2k = "weights/DenseNet-40-12-CIFAR10-2K.h5"
if os.path.exists(weights_file_2k):
    # model.load_weights(weights_file, by_name=True)
    print("Model loaded.")

out_dir = "weights/"
tb_dir_2k = "tensorboard/2k"

lr_reducer = ReduceLROnPlateau(monitor='val_acc', factor=np.sqrt(0.1),
                               cooldown=0, patience=5, min_lr=1e-5, verbose=1)
model_checkpoint_2k = ModelCheckpoint(weights_file_2k, monitor="val_acc", save_best_only=True,
                                      save_weights_only=True, verbose=1)
# tensorboard_2k = TensorBoard(log_dir=tb_dir_2k+"/logs", histogram_freq=5, batch_size=batch_size, write_graph=False,
#                              write_images=True, write_grads=True)

callbacks_2k = [lr_reducer, model_checkpoint_2k]
try:
    if augment == 'true':
        print("Training with data augmentation...")
        model2k.fit_generator(generator.flow(trainX, Y_train, batch_size=batch_size),
                              steps_per_epoch=len(trainX) // batch_size, epochs=nb_epoch,
                              callbacks=callbacks_2k,
                              validation_data=(testX, Y_test),
                              validation_steps=testX.shape[0] // batch_size, verbose=1)
    else:
        print("Training without data augmentation...")
        model2k.fit(trainX, Y_train, batch_size=batch_size, epochs=nb_epoch, callbacks=callbacks_2k,
                    validation_data=(testX, Y_test), verbose=2)
except KeyboardInterrupt:
    print("Training interrupted")
    sys.exit(1)

yPreds_2k = model2k.predict(testX)
yPred_2k = np.argmax(yPreds_2k, axis=1)
yTrue = testY

accuracy_2k = metrics.accuracy_score(yTrue, yPred_2k) * 100
error_2k = 100 - accuracy_2k
print("2K Accuracy : ", accuracy_2k)
print("2K Error : ", error_2k)
del model2k

# 4K MODEL
model4k = densenet.DenseNet(img_dim, classes=nb_classes, depth=depth, nb_dense_block=nb_dense_block,
                            growth_rate=growth_rate, nb_filter=nb_filter, dropout_rate=dropout_rate, weights=None,
                            bottleneck=True, growth_rate_factor=4)
print("Building model 4k...")
model4k.summary()
optimizer = Adam(lr=1e-3)  # Using Adam instead of SGD to speed up training
model4k.compile(loss='categorical_crossentropy', optimizer=optimizer, metrics=["accuracy"])
print("Finished compiling")

# Load model
weights_file_4k = "weights/DenseNet-40-12-CIFAR10-4K.h5"
if os.path.exists(weights_file_4k):
    # model.load_weights(weights_file, by_name=True)
    print("Model loaded.")

out_dir = "weights/"
tb_dir_4k = "tensorboard/4k"

lr_reducer = ReduceLROnPlateau(monitor='val_acc', factor=np.sqrt(0.1),
                               cooldown=0, patience=5, min_lr=1e-5, verbose=1)
model_checkpoint_4k = ModelCheckpoint(weights_file_4k, monitor="val_acc", save_best_only=True,
                                      save_weights_only=True, verbose=1)

# tensorboard_4k = TensorBoard(log_dir=tb_dir_4k+"/logs", histogram_freq=5, batch_size=batch_size, write_graph=False,
#                              write_images=True, write_grads=True)

callbacks_4k = [lr_reducer, model_checkpoint_4k]
try:
    if augment == 'true':
        print("Training with data augmentation...")
        model4k.fit_generator(generator.flow(trainX, Y_train, batch_size=batch_size),
                              steps_per_epoch=len(trainX) // batch_size, epochs=nb_epoch,
                              callbacks=callbacks_4k,
                              validation_data=(testX, Y_test),
                              validation_steps=testX.shape[0] // batch_size, verbose=1)
    else:
        print("Training without data augmentation...")
        model4k.fit(trainX, Y_train, batch_size=batch_size, epochs=nb_epoch, callbacks=callbacks_4k,
                    validation_data=(testX, Y_test), verbose=2)
except KeyboardInterrupt:
    print("Training interrupted")
    sys.exit(1)

yPreds_4k = model4k.predict(testX)
yPred_4k = np.argmax(yPreds_4k, axis=1)
yTrue = testY

accuracy_4k = metrics.accuracy_score(yTrue, yPred_4k) * 100
error_4k = 100 - accuracy_4k
print("4K Accuracy : ", accuracy_4k)
print("4K Error : ", error_4k)
del model4k

# 6K MODEL
print("Building model 6k...")

model6k = densenet.DenseNet(img_dim, classes=nb_classes, depth=depth, nb_dense_block=nb_dense_block,
                            growth_rate=growth_rate, nb_filter=nb_filter, dropout_rate=dropout_rate, weights=None,
                            bottleneck=True, growth_rate_factor=6)

model6k.summary()
optimizer = Adam(lr=1e-3)  # Using Adam instead of SGD to speed up training
model6k.compile(loss='categorical_crossentropy', optimizer=optimizer, metrics=["accuracy"])
print("Finished compiling")

# Load model
weights_file_6k = "weights/DenseNet-40-12-CIFAR10-6K.h5"
if os.path.exists(weights_file_6k):
    # model.load_weights(weights_file, by_name=True)
    print("Model loaded.")

out_dir = "weights/"
tb_dir_6k = "tensorboard/6k"

model_checkpoint_6k = ModelCheckpoint(weights_file_6k, monitor="val_acc", save_best_only=True,
                                      save_weights_only=True, verbose=1)

# tensorboard_6k = TensorBoard(log_dir=tb_dir_6k+"/logs", histogram_freq=5, batch_size=batch_size, write_graph=False,
#                              write_images=True, write_grads=True)

callbacks_6k = [lr_reducer, model_checkpoint_6k]
try:
    if augment == 'true':
        print("Training with data augmentation...")
        model6k.fit_generator(generator.flow(trainX, Y_train, batch_size=batch_size),
                              steps_per_epoch=len(trainX) // batch_size, epochs=nb_epoch,
                              callbacks=callbacks_6k,
                              validation_data=(testX, Y_test),
                              validation_steps=testX.shape[0] // batch_size, verbose=1)
    else:
        print("Training without data augmentation...")
        model6k.fit(trainX, Y_train, batch_size=batch_size, epochs=nb_epoch, callbacks=callbacks_6k,
                    validation_data=(testX, Y_test), verbose=2)
except KeyboardInterrupt:
    print("Training interrupted")
    sys.exit(1)

yPreds_6k = model6k.predict(testX)
yPred_6k = np.argmax(yPreds_6k, axis=1)

accuracy_6k = metrics.accuracy_score(yTrue, yPred_6k) * 100
error_6k = 100 - accuracy_6k
print("6K Accuracy : ", accuracy_6k)
print("6K Error : ", error_6k)
del model6k

# 8K MODEL
print("Building model 8k...")

model8k = densenet.DenseNet(img_dim, classes=nb_classes, depth=depth, nb_dense_block=nb_dense_block,
                            growth_rate=growth_rate, nb_filter=nb_filter, dropout_rate=dropout_rate, weights=None,
                            bottleneck=True, growth_rate_factor=8)

model8k.summary()
optimizer = Adam(lr=1e-3)  # Using Adam instead of SGD to speed up training
model8k.compile(loss='categorical_crossentropy', optimizer=optimizer, metrics=["accuracy"])
print("Finished compiling")

# Load model
weights_file_8k = "weights/DenseNet-40-12-CIFAR10-8K.h5"
if os.path.exists(weights_file_8k):
    # model.load_weights(weights_file, by_name=True)
    print("Model loaded.")

out_dir = "weights/"
tb_dir_8k = "tensorboard/8k"

model_checkpoint_8k = ModelCheckpoint(weights_file_8k, monitor="val_acc", save_best_only=True,
                                      save_weights_only=True, verbose=1)

# tensorboard_8k = TensorBoard(log_dir=tb_dir_8k+"/logs", histogram_freq=5, batch_size=batch_size, write_graph=False,
#                              write_images=True, write_grads=True)

callbacks_8k = [lr_reducer, model_checkpoint_8k]
try:
    if augment == 'true':
        print("Training with data augmentation...")
        model8k.fit_generator(generator.flow(trainX, Y_train, batch_size=batch_size),
                              steps_per_epoch=len(trainX) // batch_size, epochs=nb_epoch,
                              callbacks=callbacks_8k,
                              validation_data=(testX, Y_test),
                              validation_steps=testX.shape[0] // batch_size, verbose=1)
    else:
        print("Training without data augmentation...")
        model8k.fit(trainX, Y_train, batch_size=batch_size, epochs=nb_epoch, callbacks=callbacks_8k,
                    validation_data=(testX, Y_test), verbose=2)
except KeyboardInterrupt:
    print("Training interrupted")
    sys.exit(1)

yPreds_8k = model8k.predict(testX)
yPred_8k = np.argmax(yPreds_8k, axis=1)

accuracy_8k = metrics.accuracy_score(yTrue, yPred_8k) * 100
error_8k = 100 - accuracy_8k
print("8K Accuracy : ", accuracy_8k)
print("8K Error : ", error_8k)
del model8k


from wsgiref.simple_server import make_server
import psutil,datetime
import sqlite3

def interview_scores(environ, start_response):
    conn_result=sqlite3.connect("results.sqlite")
    cursor_result = conn_result.cursor()
    print_results = cursor_result.execute("select * from interview_results")
    status = '200 OK'
    headers = [('Content-type', 'html; charset=utf-8')]
    start_response(status, headers)
    message = "
Interview Scores
"
    message +="
"
    message += "
"
    message +="Username	"
    message +="Correct Answers	"
    message +="Total Questions	"
    message +="Result
"

    for data in print_results:
        message += "
"
        message += ""+(str(data[0]))+"	"
        message += ""+(str(data[1]))+"	"
        message += ""+(str(data[2]))+"	"
        message += ""+(str(data[3]))+"	"
        message += "
"
    return[bytes(message,'utf-8')]

httpd = make_server('', 8000,interview_scores)
print("Serving on port 8000...")

httpd.serve_forever()


from sys import stdin
stdin = open("input.txt", "r")

res = 0
in_group = 0
seen = {chr(key): 0 for key in range(ord('a'), ord('z') + 1)}
for line in stdin:
    if line == '' or line == '\n':
        res += sum([v == in_group for v in seen.values()])
        seen = {chr(key): 0 for key in range(ord('a'), ord('z') + 1)}
        in_group = 0
    else:
        in_group += 1
        for ch in line:
            if ch != '\n':
                seen[ch] += 1
res += sum([v == in_group for v in seen.values()])
print(res)


import os
# force TF to use CPU instead of GPU (sadly my discrete card is not support the latest CUDA version)
os.environ['CUDA_VISIBLE_DEVICES'] = '-1'

import gym

from gym import envs
import numpy as np
from keras.models import Sequential
from keras.layers import Dense
from keras.optimizers import Adam
import matplotlib.pyplot as plt

import time

# build DQN model from keras layers
def dqn_model(input_layer_size, output_layer_size, learning_rate=0.001):
    model = Sequential()
    model.add(Dense(128, input_dim=input_layer_size, activation='relu'))
    model.add(Dense(64, activation='relu'))
    model.add(Dense(output_layer_size, activation='linear'))
    model.compile(loss='mse', optimizer=Adam(lr=learning_rate))

    return model

if __name__ == "__main__":
    print(envs.registry.all())

    env = gym.make('LunarLander-v2')

    print(env.action_space)
    print(env.observation_space)

    OBSERVATION_SPACE_SIZE = env.observation_space.shape[0]
    ACTION_SPACE_SIZE = env.action_space.n

    model = dqn_model(OBSERVATION_SPACE_SIZE, ACTION_SPACE_SIZE)

    NUMBER_OF_EPISODES = 1000
    MAX_NUMBER_OF_STEPS_IN_EPISODE = 750

    BATCH_SIZE = 64

    DISCOUNT_RATE = 0.99

    exploration_rate = 1.0
    EXPLORATION_RATE_MINIMUM = 0.1
    EXPLORATION_RATE_CHANGE = (exploration_rate - EXPLORATION_RATE_MINIMUM) / ((NUMBER_OF_EPISODES / 2) * 100)

    obs_arr = np.array([])
    next_obs_arr = np.array([])
    actions_arr = np.array([], dtype=int)
    rewards_arr = np.array([])
    done_arr = np.array([])

    total_rewards = np.array([])

    for episode_idx in range(NUMBER_OF_EPISODES):
        start_time = time.time()
        # Restart the environment to start a new episode
        obs = env.reset()
        obs = np.reshape(obs, (1, OBSERVATION_SPACE_SIZE))

        episode_total_reward = 0

        explore_count = 0
        exploit_count = 0

        for step_idx in range(MAX_NUMBER_OF_STEPS_IN_EPISODE):
            # render a view with the environment current state
            # env.render()

            # choose action greedily (exploration-exploitation trade-off)
            if np.random.random() < exploration_rate:
                # explore
                explore_count += 1
                action = env.action_space.sample()
            else:
                # exploit: ask DQN to make a prediction of which action is preferred here
                exploit_count += 1
                prediction = model.predict(obs)[0]
                # print("prediction: ", prediction)
                action = np.argmax(prediction)

            # do the action
            next_obs, reward, is_done, info = env.step(action)
            next_obs = np.reshape(next_obs, (1, OBSERVATION_SPACE_SIZE))

            episode_total_reward += reward

            if len(obs_arr) == 0:
                obs_arr = np.array(obs)
                next_obs_arr = np.array(next_obs)
            else:
                obs_arr = np.vstack((obs_arr, obs))
                next_obs_arr = np.vstack((next_obs_arr, next_obs))
            actions_arr = np.append(actions_arr, action)
            rewards_arr = np.append(rewards_arr, reward)
            done_arr = np.append(done_arr, is_done)

            obs = next_obs

            if len(obs_arr) >= BATCH_SIZE:
                # print(episode_idx, ":", step_idx)
                indexes = np.random.randint(len(done_arr), size=BATCH_SIZE)

                batch_obs = np.squeeze(obs_arr[indexes])
                batch_next_obs = np.squeeze(next_obs_arr[indexes])
                batch_action = actions_arr[indexes]
                batch_reward = rewards_arr[indexes]
                batch_done = done_arr[indexes]

                all_targets = model.predict_on_batch(batch_obs)
                targets = batch_reward + DISCOUNT_RATE * (np.amax(model.predict_on_batch(batch_next_obs), axis=1)) * (1 - batch_done)

                all_targets[[np.array([i for i in range(BATCH_SIZE)])], batch_action] = targets

                # train the model
                model.fit(batch_obs, all_targets, verbose=0)

            # change exploration rate at every step until it becomes less or eq than exploration_rate_min
            # if exploration_rate > EXPLORATION_RATE_MINIMUM:
            #     exploration_rate -= EXPLORATION_RATE_CHANGE

            if exploration_rate > 0.01:
                exploration_rate *= 0.99

            # print("ep#%d:step#%d, obs=%s, reward=%s, done=%s" % (episode_idx, step_idx, observation, reward, is_done))
            if is_done:
                break

        total_rewards = np.append(total_rewards, episode_total_reward)

        print("----------------------")
        print("Episode %d reward: %d" % (episode_idx, episode_total_reward))
        print("Last step: %d" % (step_idx))
        print("Exploration rate: %f" % (exploration_rate))
        print("Explore count: %d" % (explore_count))
        print("Exploit count: %d" % (exploit_count))
        print("Time for episode: ", (time.time() - start_time), " sec.")

        # lunar lander problem is considered solved when total reward is 200+ points;
        # so we check if the last episodes was successful, the training would be stopped
        if np.mean(total_rewards[-100:]) >= 200:
            break

    # plot training progress
    x = list(range(len(total_rewards)))
    plt.plot(x, total_rewards)
    plt.xlabel("Episode")
    plt.ylabel("Total reward")
    plt.show()

    # save the model for future testing
    model.save('model.h5')

    # close gym environment
    env.close()


N = int(input())
c = list(input())

Nw, Nr = 0, 0
for i in range(len(c)):
    Nw += 1 if c[i] == "W" else 0
    Nr += 1 if c[i] == "R" else 0

if Nw == 0 or Nr == 0:
    print(0)
    exit()

left_w = 0
right_r = 0
if c[0] == "W":
    left_w = 1
    right_r = Nr
else:
    left_w = 0
    right_r = Nr - 1

#仕切りの位置をiの横とすると
ans = max(left_w, right_r)

for i in range(len(c)):
    if i > 0:
        if c[i] == "W":
            left_w += 1
        else:
            right_r -= 1
    swap = max(left_w, right_r)
    ans = min(swap, ans)
print(ans)


from flask import Flask, render_template, request, redirect, flash, session, config
from flask_debugtoolbar import DebugToolbarExtension
from surveys import satisfaction_survey as survey

app = Flask(__name__)
app.config['SECRET_KEY'] = "austin"
debug = DebugToolbarExtension(app)

responses = []
currentNum = 0
RESPONSES_KEY = "responses"

@app.route('/')
def show_home():
    """Main home page viewing."""
    global responses
    answers = responses
    responses = []
    instruction_text = str(survey.instructions)
    return render_template('base.html', instruction_text=instruction_text, answers=answers)

@app.route('/questions/1')
def question1():
    if len(responses) == 0:
        answers = responses
        global currentNum
        currentNum = 1
        question = survey.questions[0].question
        choices = survey.questions[0].choices
        return render_template('questions.html', question=question, num=currentNum, choices=choices, answers=answers)
    else:
        flash(f"Invalid question ID. Please take the survey in sequential order.")
        return redirect("/")

@app.route('/questions/2')
def question2():
    if len(responses) == 1:
        answers = responses
        global currentNum
        currentNum = 2
        question = survey.questions[1].question
        choices = survey.questions[1].choices
        return render_template('questions.html', question=question, num=currentNum, choices=choices, answers=answers)
    else:
        flash(f"Invalid question ID. Please take the survey in sequential order.")
        return redirect("/")

@app.route('/questions/3')
def question3():
    if len(responses) == 2:
        answers = responses
        global currentNum
        currentNum = 3
        question = survey.questions[2].question
        choices = survey.questions[2].choices
        return render_template('questions.html', question=question, num=currentNum, choices=choices, answers=answers)
    else:
        flash(f"Invalid question ID. Please take the survey in sequential order.")
        return redirect("/")

@app.route('/questions/4')
def question4():
    if len(responses) == 3:
        answers = responses
        global currentNum
        currentNum = 4
        question = survey.questions[3].question
        choices = survey.questions[3].choices
        return render_template('questions.html', question=question, num=currentNum, choices=choices, answers=answers)
    else:
        flash(f"Invalid question ID. Please take the survey in sequential order.")
        return redirect("/")

@app.route('/questions/5')
def question5():
    return redirect('/thankyou')

@app.route('/thankyou')
def thankyou_page():
    answers = responses
    session[RESPONSES_KEY] = responses
    return render_template('thankyou.html', answers=answers)

@app.route("/answer", methods=["POST"])
def post_answer():
    choice = request.form['answer']
    responses.append(choice)
    global currentNum
    newPageNum = currentNum + 1
    # return redirect('/questions/{newPageNum}')
    return redirect(f"/questions/{newPageNum}")


# Write a program which will select a random name from a list of names.
# The person selected will have to pay for everybody's food bill.

names_string = input("Give me everybody's names, separated by a comma. ")
names = names_string.split(", ")
# ðŸš¨ Don't change the code above ðŸ‘†

import random
i = random.randint(0,len(names))
print("{} is going to pay the bill".format(names[i]))

#Write your code below this line ðŸ‘‡


# Given a nested list of integers, return the sum of all integers in the list weighted by their depth. Each element is either an integer,
# or a list -- whose elements may also be integers or other lists.

def depthSum(nestedList):
    def dfs(array, depth):
        nonlocal sumDepth
        for item in array:
            if type(item) == int:
                sumDepth += item * depth
            else:
                dfs(item, depth + 1)

    sumDepth = 0
    dfs(nestedList, 1)
    return sumDepth

# print(depthSum([[1,1],2,[1,1]]))
# print(depthSum([1,[4,[6]]]))


from flask.views import MethodView
from flask_jwt_extended import jwt_required
from flask_smorest import Blueprint, abort

from db import db
from Models import NoteModel, CategoryModel
from schemas import NoteSchema, NoteQuerySchema, CategorySchema
from sqlalchemy.exc import IntegrityError

blp = Blueprint("note", __name__, description="Operations on note")

@blp.route("/note")
class NoteList(MethodView):
    @jwt_required()
    @blp.arguments(NoteQuerySchema, location="query", as_kwargs=True)
    @blp.response(200, NoteSchema(many=True))
    def get(self, kwargs):
        user_id = kwargs.get("user_id")
        category_id = kwargs.get("category_id")
        if user_id and category_id:
            query = NoteModel.query.filter_by(user_id=user_id, category_id=category_id)
            return query
        if user_id:
            query = NoteModel.query.filter_by(user_id=user_id)
            return query
        if category_id:
            query = NoteModel.query.filter_by(category_id=category_id)
            return query
        return NoteModel.query.all()

    @jwt_required()
    @blp.arguments(NoteSchema)
    @blp.response(200, NoteSchema)
    def post(self, request_data):
        note = NoteModel(**request_data)
        category_id = request_data.get("category_id")
        category_owner_id = CategoryModel.query.with_entities(CategoryModel.owner_id).filter_by(id=category_id).scalar()
        if category_owner_id == request_data["user_id"] or category_owner_id is None:
            try:
                db.session.add(note)
                db.session.commit()
            except IntegrityError:
                abort(400, message="Error when creating note")
            return note
        abort(403, message="User has no access to this category")


'''
rate limit problem
'''

accepted_ip_addresses = []
accepted_time_stamps = []

def accept_or_reject(time_stamps, ip_addresses, limit, lower_ts_threshold, ip_address, time_stamp):
    '''
    Decision making function
    '''
    count = 0
    for i,j in zip(ip_addresses, time_stamps):
        if j >= lower_ts_threshold and str(i) == str(ip_address):
            count += 1
    if count < limit:
        result = 1
        accepted_ip_addresses.append(ip_address)
        accepted_time_stamps.append(time_stamp)
    else:
        result = 0
    return result

def sol(time_stamps, ip_addresses, limit, time_window):
    '''
    Function that returns soltion
    '''
    sol_arr = []
    for ip_address, time_stamp in zip(ip_addresses, time_stamps):
        lower_ts_threshold = time_stamp - time_window
        result = accept_or_reject(accepted_time_stamps, accepted_ip_addresses,
                                    limit, lower_ts_threshold,
                                    ip_address, time_stamp)
        sol_arr.append(result)

    print(sol_arr)
    return sol_arr

if __name__ == "__main__" :
    sol([1600040547954, 1600040547957, 1600040547958], ["127.105.232.211", "127.105.232.211", "127.105.232.211"], 1, 3)
    sol([1600000000000, 1600000000000, 1600000000001], ["56.75.0.49", "62.2.159.38", "62.2.159.38"], 2, 10)


import bson
import ujson
from bson import ObjectId

from .utils import db

def retrieve_info(object_id):
    # Retrieve info from DB
    mongo = db.MongoDBConnection()
    result = list()

    with mongo:
        database = mongo.connection['mydb']
        collection = database['registrations']

        if object_id is not None:
            # Retrieve particular object
            try:
                single_object = collection.find_one({"_id": ObjectId(object_id)})
                if single_object is None:
                    return {"error": "Object id does not exist!"}
            except bson.errors.InvalidId:
                # catch the exception calling ObjectId
                return {"err": "Invalid object_id"}

            return {
                'id': object_id,
                'first_name': single_object['first_name'],
                'last_name': single_object['last_name'],
                'email': single_object['email']
            }

        else:
            # Retrieve all info
            for user in collection.find():
                result.append({
                    'id': str(user["_id"]),
                    'first_name': user['first_name'],
                    'last_name': user['last_name'],
                    'email': user['email']
                })
        return result

def lambda_handler(event, context):
    try:
        print(event)
        object_id = event['pathParameters']['id']
        # print("#######OBJECT_ID#########\n" + object_id)
    except TypeError:
        object_id = None
    except KeyError:
        object_id = None

    try:
        return {
            "statusCode": 200,
            "body": ujson.dumps({
                "message": "Success",
                "data": retrieve_info(object_id)
            })
        }
    except Exception as err:
        return {
            "statusCode": 400,
            "body": ujson.dumps({
                "message": "Something went wrong. Unable to parse data !",
                "error": str(err)
            })

        }


def solution(s):
    answer = []
    result = []
    dic = {}

#     아이디어
# 1. 문자열 s를 {}별로 쪼개서 리스트에 넣는다.
# 2. 해당리스트를 오름차순 정렬한다.
# 3. 하나씩 꺼내면서 딕셔너리에 들어가는 값을 결과 리스트에넣는다.

    arr = []
    tmp = ''
    open_mark = False
    for i in range(1,len(s)-1):
        if s[i] == '{':
            arr = []
            tmp = ''
            open_mark = True
        elif s[i] == '}':
            arr.append(tmp)
            answer.append(arr)
            open_mark = False

        elif open_mark == False and s[i] == ',':
            continue

        elif open_mark == True and s[i] == ',':
            arr.append(tmp)
            tmp = ''

        else:
            tmp += s[i]

    answer.sort(key=lambda x : len(x))

    for a in answer:
        for i in range(len(a)):
            if a[i] not in dic:
                dic[a[i]]=1
                result.append(int(a[i]))

    return result


config = {
  # Dollar-Cost Averaging config
  'SYMBOL': 'AAPL',        # Stock symbol, string type
  'ALLOCATION': 200,       # Amount of money to allocate for each DCA in USD, int type

  # config for TD
  'TD_ID': '',             # TD Ameritrade Account ID, string type
  'TD_ACCESS_TOKEN': '',   # Access Token, string type
  'TD_CONSUMER_KEY': '',   # Consumer key, string type
  'TD_CALLBACK_URL': 'http://localhost',
  'TD_REFRESH_URL': 'https://auth.tdameritrade.com/auth?response_type=code&redirect_uri={callback_url}&client_id={consumer_key}%40AMER.OAUTHAP',
  'TD_REFRESH_TOKEN': '',  # Refresh token, string type
  'TD_CODE': '',           # TD Ameritrade Code, string type

  # config for MooMoo
  'MOOMOO_IP': '127.0.0.1',  # Default IP used
  'MOOMOO_PORT': 11111,      # Default Port used

  # config for IBKR
  'IBKR_URL': '127.0.0.1',  # Default IP used
  'IBKR_PORT': 4002,        # Default Port used, 4001 for IB Gateway live trading, 4002 for IB Gateway paper trading
  'IBKR_ID': 0,             # IBKR Master API client ID, int type

  # config for tiger
  'PRIVATE_KEY_PATH': '',   # Path to your private key, string type
  'TIGER_ID': 0,            # Tiger_ID, int type
  'TIGER_ACCOUNT': 0,       # Tiger Account (Live/Paper), int type
}