from logbook import Logger
from collections import defaultdict
from copy import copy

from six import iteritems

from zipline.assets import Equity, Future, Asset
from .blotter import Blotter
from zipline.extensions import register
from zipline.finance.order import Order
from zipline.finance.slippage import (
    DEFAULT_FUTURE_VOLUME_SLIPPAGE_BAR_LIMIT,
    VolatilityVolumeShare,
    FixedBasisPointsSlippage,
)
from zipline.finance.commission import (
    DEFAULT_PER_CONTRACT_COST,
    FUTURE_EXCHANGE_FEES_BY_SYMBOL,
    PerContract,
    PerShare,
)
from zipline.utils.input_validation import expect_types

log = Logger('Blotter')
warning_logger = Logger('AlgoWarning')

@register(Blotter, 'default')
class SimulationBlotter(Blotter):
    def __init__(self,
                 equity_slippage=None,
                 future_slippage=None,
                 equity_commission=None,
                 future_commission=None,
                 cancel_policy=None):
        super(SimulationBlotter, self).__init__(cancel_policy=cancel_policy)

        # these orders are aggregated by asset
        self.open_orders = defaultdict(list)

        # keep a dict of orders by their own id
        self.orders = {}

        # holding orders that have come in since the last event.
        self.new_orders = []

        self.max_shares = int(1e+11)

        self.slippage_models = {
            Equity: equity_slippage or FixedBasisPointsSlippage(),
            Future: future_slippage or VolatilityVolumeShare(
                volume_limit=DEFAULT_FUTURE_VOLUME_SLIPPAGE_BAR_LIMIT,
            ),
        }
        self.commission_models = {
            Equity: equity_commission or PerShare(),
            Future: future_commission or PerContract(
                cost=DEFAULT_PER_CONTRACT_COST,
                exchange_fee=FUTURE_EXCHANGE_FEES_BY_SYMBOL,
            ),
        }

    def __repr__(self):
        return """
{class_name}(
    slippage_models={slippage_models},
    commission_models={commission_models},
    open_orders={open_orders},
    orders={orders},
    new_orders={new_orders},
    current_dt={current_dt})
""".strip().format(class_name=self.__class__.__name__,
                   slippage_models=self.slippage_models,
                   commission_models=self.commission_models,
                   open_orders=self.open_orders,
                   orders=self.orders,
                   new_orders=self.new_orders,
                   current_dt=self.current_dt)

    @expect_types(asset=Asset)
    def order(self, asset, amount, style, order_id=None):
        """Place an order.

        Parameters
        ----------
        asset : zipline.assets.Asset
            The asset that this order is for.
        amount : int
            The amount of shares to order. If ``amount`` is positive, this is
            the number of shares to buy or cover. If ``amount`` is negative,
            this is the number of shares to sell or short.
        style : zipline.finance.execution.ExecutionStyle
            The execution style for the order.
        order_id : str, optional
            The unique identifier for this order.

        Returns
        -------
        order_id : str or None
            The unique identifier for this order, or None if no order was
            placed.

        Notes
        -----
        amount > 0 :: Buy/Cover
        amount < 0 :: Sell/Short
        Market order:    order(asset, amount)
        Limit order:     order(asset, amount, style=LimitOrder(limit_price))
        Stop order:      order(asset, amount, style=StopOrder(stop_price))
        StopLimit order: order(asset, amount, style=StopLimitOrder(limit_price,
                               stop_price))
        """
        # something could be done with amount to further divide
        # between buy by share count OR buy shares up to a dollar amount
        # numeric == share count  AND  "$dollar.cents" == cost amount

        if amount == 0:
            # Don't bother placing orders for 0 shares.
            return None
        elif amount > self.max_shares:
            # Arbitrary limit of 100 billion (US) shares will never be
            # exceeded except by a buggy algorithm.
            raise OverflowError("Can't order more than %d shares" %
                                self.max_shares)

        is_buy = (amount > 0)
        order = Order(
            dt=self.current_dt,
            asset=asset,
            amount=amount,
            stop=style.get_stop_price(is_buy),
            limit=style.get_limit_price(is_buy),
            id=order_id
        )

        self.open_orders[order.asset].append(order)
        self.orders[order.id] = order
        self.new_orders.append(order)

        return order.id

    def cancel(self, order_id, relay_status=True):
        if order_id not in self.orders:
            return

        cur_order = self.orders[order_id]

        if cur_order.open:
            order_list = self.open_orders[cur_order.asset]
            if cur_order in order_list:
                order_list.remove(cur_order)

            if cur_order in self.new_orders:
                self.new_orders.remove(cur_order)
            cur_order.cancel()
            cur_order.dt = self.current_dt

            if relay_status:
                # we want this order's new status to be relayed out
                # along with newly placed orders.
                self.new_orders.append(cur_order)

    def cancel_all_orders_for_asset(self, asset, warn=False,
                                    relay_status=True):
        """
        Cancel all open orders for a given asset.
        """
        # (sadly) open_orders is a defaultdict, so this will always succeed.
        orders = self.open_orders[asset]

        # We're making a copy here because `cancel` mutates the list of open
        # orders in place.  The right thing to do here would be to make
        # self.open_orders no longer a defaultdict.  If we do that, then we
        # should just remove the orders once here and be done with the matter.
        for order in orders[:]:
            self.cancel(order.id, relay_status)
            if warn:
                # Message appropriately depending on whether there's
                # been a partial fill or not.
                if order.filled > 0:
                    warning_logger.warn(
                        'Your order for {order_amt} shares of '
                        '{order_sym} has been partially filled. '
                        '{order_filled} shares were successfully '
                        'purchased. {order_failed} shares were not '
                        'filled by the end of day and '
                        'were canceled.'.format(
                            order_amt=order.amount,
                            order_sym=order.asset.symbol,
                            order_filled=order.filled,
                            order_failed=order.amount - order.filled,
                        )
                    )
                elif order.filled < 0:
                    warning_logger.warn(
                        'Your order for {order_amt} shares of '
                        '{order_sym} has been partially filled. '
                        '{order_filled} shares were successfully '
                        'sold. {order_failed} shares were not '
                        'filled by the end of day and '
                        'were canceled.'.format(
                            order_amt=order.amount,
                            order_sym=order.asset.symbol,
                            order_filled=-1 * order.filled,
                            order_failed=-1 * (order.amount - order.filled),
                        )
                    )
                else:
                    warning_logger.warn(
                        'Your order for {order_amt} shares of '
                        '{order_sym} failed to fill by the end of day '
                        'and was canceled.'.format(
                            order_amt=order.amount,
                            order_sym=order.asset.symbol,
                        )
                    )

        assert not orders
        del self.open_orders[asset]

    def execute_cancel_policy(self, event):
        if self.cancel_policy.should_cancel(event):
            warn = self.cancel_policy.warn_on_cancel
            for asset in copy(self.open_orders):
                self.cancel_all_orders_for_asset(asset, warn,
                                                 relay_status=False)

    def reject(self, order_id, reason=''):
        """
        Mark the given order as 'rejected', which is functionally similar to
        cancelled. The distinction is that rejections are involuntary (and
        usually include a message from a broker indicating why the order was
        rejected) while cancels are typically user-driven.
        """
        if order_id not in self.orders:
            return

        cur_order = self.orders[order_id]

        order_list = self.open_orders[cur_order.asset]
        if cur_order in order_list:
            order_list.remove(cur_order)

        if cur_order in self.new_orders:
            self.new_orders.remove(cur_order)
        cur_order.reject(reason=reason)
        cur_order.dt = self.current_dt
        # we want this order's new status to be relayed out
        # along with newly placed orders.
        self.new_orders.append(cur_order)

    def hold(self, order_id, reason=''):
        """
        Mark the order with order_id as 'held'. Held is functionally similar
        to 'open'. When a fill (full or partial) arrives, the status
        will automatically change back to open/filled as necessary.
        """
        if order_id not in self.orders:
            return

        cur_order = self.orders[order_id]
        if cur_order.open:
            if cur_order in self.new_orders:
                self.new_orders.remove(cur_order)
            cur_order.hold(reason=reason)
            cur_order.dt = self.current_dt
            # we want this order's new status to be relayed out
            # along with newly placed orders.
            self.new_orders.append(cur_order)

    def process_splits(self, splits):
        """
        Processes a list of splits by modifying any open orders as needed.

        Parameters
        ----------
        splits: list
            A list of splits.  Each split is a tuple of (asset, ratio).

        Returns
        -------
        None
        """
        for asset, ratio in splits:
            if asset not in self.open_orders:
                continue

            orders_to_modify = self.open_orders[asset]
            for order in orders_to_modify:
                order.handle_split(ratio)

    def get_transactions(self, bar_data):
        """
        Creates a list of transactions based on the current open orders,
        slippage model, and commission model.

        Parameters
        ----------
        bar_data: zipline._protocol.BarData

        Notes
        -----
        This method book-keeps the blotter's open_orders dictionary, so that
         it is accurate by the time we're done processing open orders.

        Returns
        -------
        transactions_list: List
            transactions_list: list of transactions resulting from the current
            open orders.  If there were no open orders, an empty list is
            returned.

        commissions_list: List
            commissions_list: list of commissions resulting from filling the
            open orders.  A commission is an object with "asset" and "cost"
            parameters.

        closed_orders: List
            closed_orders: list of all the orders that have filled.
        """

        closed_orders = []
        transactions = []
        commissions = []

        if self.open_orders:
            for asset, asset_orders in iteritems(self.open_orders):
                slippage = self.slippage_models[type(asset)]

                for order, txn in \
                        slippage.simulate(bar_data, asset, asset_orders):
                    commission = self.commission_models[type(asset)]
                    additional_commission = commission.calculate(order, txn)

                    if additional_commission > 0:
                        commissions.append({
                            "asset": order.asset,
                            "order": order,
                            "cost": additional_commission
                        })

                    order.filled += txn.amount
                    order.commission += additional_commission

                    order.dt = txn.dt

                    transactions.append(txn)

                    if not order.open:
                        closed_orders.append(order)

        return transactions, commissions, closed_orders

    def prune_orders(self, closed_orders):
        """
        Removes all given orders from the blotter's open_orders list.

        Parameters
        ----------
        closed_orders: iterable of orders that are closed.

        Returns
        -------
        None
        """
        # remove all closed orders from our open_orders dict
        for order in closed_orders:
            asset = order.asset
            asset_orders = self.open_orders[asset]
            try:
                asset_orders.remove(order)
            except ValueError:
                continue

        # now clear out the assets from our open_orders dict that have
        # zero open orders
        for asset in list(self.open_orders.keys()):
            if len(self.open_orders[asset]) == 0:
                del self.open_orders[asset]


import sys

import pytest
from pandas import Series

from src.modules import named_entity_recognition as ner

class TestRetrieveNamedEntities:
    @pytest.mark.skipif(
        sys.platform.startswith("linux"), reason="Unknown error during CI"
    )
    def test_retrieve_named_entities(self):
        test_data = Series(
            [
                "The ONS has just released an article on the UK Government's policy.",
                "my own care for nothing",
                "Hollywood actors now have their own statue",
            ]
        )
        actual = ner.retrieve_named_entities(test_data)
        expected = [["ONS", "the UK Government's"], [], ["Hollywood"]]
        assert actual == expected, "Did not successfully retrieve named entities"


'''
Created on 24 de fev de 2017

@author: Thiago Nobrega
'''

import zipfile
import io

import csv

#head powershell
#gc log.txt | select -first 10 # head

from datetime import datetime
from parsers import base
import os

from datetime import datetime

def convertData(file,headers= 0,delimiter = '\,', quote=csv.QUOTE_ALL):
    """
        Read data from ziped file
    """
#     import codecs
#     f = codecs.iterdecode(file, "utf-8")
# #     f = codecs.iterdecode(file, "ISO-8859-1")
#
#     data = []
#
#     reader = csv.reader(f,delimiter=delimiter,quotechar='"',quoting=quote, skipinitialspace=True)
#
#     count = 0

    from util.csvutil import readQuoted
    data = readQuoted(file,delimiter = ',')

    dm = []

    if(headers != 0):
        dm.append(headers)

    count = 0
    for row in data:
        dm.append(filterData(row))
#         count+=1
#         if count % 10000 == 0:
#             print(count)

    return dm

def filterData(data):
    row = data
#     fdata = []

    ##
    ## Adress Basic Data : data about voter adress
    #
    ### adress
    ### res_addr, res_city, res_state , res_zip
    ead = [row[11] ,row[13] , row[14] , row[15] ]

    ##
    ## Personal Data : data about the voter (name,gender,bith,etc...)
    ##
    ### basic personal data
    ###  lastname , firstname , midlename ,  name_sufix
    bpd = [ row[3],row[4],row[5],row[6] ]

    ### extra personal data
    ### birth_date , register_date
    epd = [ row[7], row[8] ]
    ### party
    ### party_affiliation
    ext = [ row[10] ]

    entity = bpd + epd + ext + ead

    return entity

def listFiles(dir):
    import os
    lf = []
    for file in os.listdir(dir):
        if file.startswith("SWVF"):
            fr = os.path.join(dir, file)
            lf.append(fr)
    return lf

if __name__ == '__main__':

    dir = "F:\\etapa_02\\Voters\\Ohio\\"
    files = listFiles(dir)

    header = "lastname","firstname","middlename","namesufix","birth_date","register_date","party_affiliation","res_addr", "res_city", "res_state" , "res_zip"
    alldata = convertData(files[0],headers=header)
    print(len(alldata))
    for file in files[1:]:
        print(file)
        data = convertData(file)
        alldata += data

    print(len(alldata))
    print(alldata[0])
    print(alldata[1])

    file = dir + 'ohio_voters_striped_full.csv'
    from util.csvutil import write2csv2
    write2csv2(file,alldata)
    import sys
    sys.exit()

    print(file)

#     ofile  = open(outfile, "w" ,encoding="UTF-8")
#     writer = csv.writer(ofile, delimiter=out_delimiter, quotechar='"', quoting=quote ,lineterminator='\n')
#
#     data = convertData(zfile, fo)
#
    print("Done!")

#fast fix in data (remove later)
#"birth_date","register_date"
import zipfile
import io
import csv
from datetime import datetime
from parsers import base
import os

from datetime import datetime

def fix_date(din):
    d = str(din)
    dt = datetime.strptime(str(d),'%Y-%m-%d')
    newdate = str(dt.day) + "/" + str(dt.month) + "/" + str(dt.year)
    return newdate

in_dir ="F:"+os.path.sep+"z_dados"+os.path.sep+"us_voters"+os.path.sep
in_dir =os.path.sep+"home/thiago/dados"+os.path.sep+"us_voters"+os.path.sep
file = "ohio_voters_striped_full.csv"
data = base.readData(in_dir+file, sep=",")

data['birth_date'] = data['birth_date'].apply(fix_date)
data['register_date'] = data['register_date'].apply(fix_date)

base.writeData(data,in_dir+'ohio_voters.csv')

import sys
sys.exit()


import os

from datetime import date

cache_dir = 'cache'
conf_dir = 'conf'

cache_extensions = ('.json', '.png')

def get_cache_filename_generic(symbol, extension):
    prefix = Global.get_cache_filename_prefix()
    Global.try_create_cache_dir()
    cache_file = cache_dir + os.sep + '{}_{}{}'.format(prefix, symbol, extension)
    return cache_file

class Global:

    def try_create_cache_dir():
        if not os.path.exists(cache_dir):
            os.makedirs(cache_dir)

    def get_cache_filename_prefix():
        today = date.today()
        prefix = today.strftime('%Y-%m-%d')
        return prefix

    def get_cache_filename(symbol):
        return get_cache_filename_generic(symbol, '.json')

    def get_cache_chart_filename(symbol, chart_type):
        extension = '_chart_{}.png'.format(chart_type)
        return get_cache_filename_generic(symbol, extension)

    def clean_old_cached_files():
        Global.try_create_cache_dir()
        prefix = Global.get_cache_filename_prefix()
        count = 0
        for filename in os.listdir(cache_dir):
            if not filename.endswith(cache_extensions):
                continue
            if not filename.startswith(prefix):
                file_path = cache_dir + os.sep + filename
                os.remove(file_path)
                count += 1
        return count


import logging

import azure.functions as func

def main(req: func.HttpRequest, recommendations: func.DocumentList) -> func.HttpResponse:
    logging.info('Python HTTP trigger function processed a request.')

    if not recommendations or len(recommendations) == 0:
        logging.warning("Recommendation item not found")
        return func.HttpResponse(
            "Recommendation item not found",
            status_code=404,
        )

    return func.HttpResponse(
        recommendations[0].to_json(),
        mimetype="application/json",
        status_code=200,
    )


"""Data processing."""

import pandas as pd
import torch
import numpy as np
from torchvision import transforms

transformer = transforms.Compose([
    transforms.RandomRotation(10),
])

class MNISTDataset(torch.utils.data.Dataset):
    """Dataset."""

    def __init__(self, df: pd.DataFrame, transformer: transforms.Compose = None):
        """Init."""
        x_cols = [x for x in df.columns if x != "label"]
        df = df.reset_index()
        self.df_x = df[x_cols]
        self.df_y = df['label']
        self.transformer = transformer

    def __len__(self):
        return self.df_x.shape[0]

    def __getitem__(self, idx):
        """Get item."""
        y_values = self.df_y.loc[idx]
        x_values = self.df_x.loc[idx].to_numpy().astype("float")/255
        x_values = x_values.reshape((1, 28, 28))
        x_values = torch.tensor(x_values).float()
        if self.transformer and np.random.random() < 0.5:
            x_values = self.transformer(x_values)
        return x_values, y_values

if __name__ == "__main__":
    import os
    dataset = MNISTDataset(
        pd.read_csv(os.path.join('data', "train.csv")),
        transformer
    )
    dataset.__getitem__(0)


import wx
import wx.grid as  gridlib
from drumsT_SYS.SQLite_lib import School_Class

class PanelTwo(wx.Panel):
    """
    Show a grid with tabular data.
    It was inspired on codes from:
    http://www.blog.pythonlibrary.org/2013/10/31/wxpython-how-to-get-selected-cells-in-a-grid/
    http://www.blog.pythonlibrary.org/2010/04/04/wxpython-grid-tips-and-tricks/
    http://www.blog.pythonlibrary.org/2010/03/18/wxpython-an-introduction-to-grids/
    Official Documents:
    http://wxpython.org/Phoenix/docs/html/grid.Grid.html
    """
    def __init__(self, parent, nameSur, IDclass, path_db):
        """
        Display a list with data of all previous lessons of
        the student in object and relating to school
        year selected only
        """
        wx.Panel.__init__(self, parent, -1, style=wx.TAB_TRAVERSAL)
        #### set attributes:
        self.currentlySelectedCell = (0, 0) # row, col default
        self.rowEdit = None # tracking what row is was edited
        self.newsEdit = [] # list of all item edited
        self.backUp = [] # last backup for recovery
        self.index = 0 # how many items (rows)
        self.path_db = path_db
        self.IDclass = IDclass
        self.IDlesson = None

        self.InitUI()

    def InitUI(self):
        """
        Start with widget and panel setup
        """
        self.editBtn = wx.Button(self, wx.ID_ANY, ("Changes"))
        self.rollbackBtn = wx.Button(self, wx.ID_ANY, ("Rollback"))
        self.applyBtn = wx.Button(self, wx.ID_ANY, ("Apply Commit"))
        self.myGrid = gridlib.Grid(self)
        #### properties:
        self.myGrid.EnableEditing(False) # make all in read only
        self.myGrid.CreateGrid(150, 15)
        self.myGrid.SetColLabelValue(0, "ID lesson")
        self.myGrid.SetColLabelValue(1, "ID class")
        self.myGrid.SetColLabelValue(2, "Attendances")
        self.myGrid.SetColLabelValue(3, "Lesson Date")
        self.myGrid.SetColLabelValue(4, "Chart Reading")
        self.myGrid.SetColLabelValue(5, "Hands/foots Setting")
        self.myGrid.SetColLabelValue(6, "Rudiments")
        self.myGrid.SetColLabelValue(7, "Coordination")
        self.myGrid.SetColLabelValue(8, "Styles")
        self.myGrid.SetColLabelValue(9, "Minus One")
        self.myGrid.SetColLabelValue(10, "Other-1")
        self.myGrid.SetColLabelValue(11, "Other-2")
        self.myGrid.SetColLabelValue(12, "Other-3")
        self.myGrid.SetColLabelValue(13, "Votes")
        self.myGrid.SetColLabelValue(14, "Note/Reminder")
        #### set columns 0-1-2 in read only
        # see above address: www.../wxpython-an-introduction-to-grids/
        #attr = gridlib.GridCellAttr()
        #attr.SetReadOnly(True)
        #self.myGrid.SetColAttr(0, attr)
        #self.myGrid.SetColAttr(1, attr)
        #self.myGrid.SetColAttr(2, attr)
        ## oppure: self.myGrid.SetReadOnly(3, 3, True)
        #### properties
        self.editBtn.SetToolTipString("Changes text or value into the "
                                     "cells and append")
        self.rollbackBtn.SetToolTipString("Rollback to the last state or first "
                                     "to the last 'Apply-Commit'")
        self.applyBtn.SetFont(wx.Font(10, wx.DEFAULT, wx.NORMAL, wx.BOLD, 0, ""))
        self.applyBtn.SetForegroundColour('#ff3f15')
        self.applyBtn.SetToolTipString("Make an update and commit new "
                                       "changes into database")
        self.editBtn.Disable()
        self.rollbackBtn.Disable()
        self.applyBtn.Disable()
        #### go to popular the grid:
        self.setting()
        #### Build Layout:
        sizer = wx.BoxSizer(wx.VERTICAL)
        gridSiz = wx.GridSizer(1,3,0,40)
        sizer.Add(self.myGrid, 1, wx.EXPAND, 5)
        sizer.Add(gridSiz, 0, wx.ALL, 5)
        gridSiz.Add(self.editBtn, 0, wx.ALL, 5)
        gridSiz.Add(self.rollbackBtn, 0, wx.ALL, 5)
        gridSiz.Add(self.applyBtn, 0, wx.ALL, 5)
        self.SetSizer(sizer)
        sizer.Fit(self)
        #### binding
        self.myGrid.Bind(gridlib.EVT_GRID_SELECT_CELL, self.onSingleSelect)
        self.Bind(wx.EVT_BUTTON, self.editCells, self.editBtn)
        self.Bind(wx.EVT_BUTTON, self.restroreLast, self.rollbackBtn)
        self.Bind(wx.EVT_BUTTON, self.makeChange, self.applyBtn)
    #-------------------------
    def setting(self):
        """
        Set properties and set the grid cells with values
        of the query.
        """
        lessons = School_Class().showInTable(self.IDclass, self.path_db)
        for n, item in enumerate(lessons):
            self.index += 1
            #------------IDlesson
            self.myGrid.SetCellValue(n , 0, str(item[0]))
            self.myGrid.SetCellAlignment(n, 0, wx.ALIGN_CENTRE, wx.ALIGN_CENTRE)
            #------------IDclass
            self.myGrid.SetCellValue(n , 1, str(item[1])) # IDclass
            self.myGrid.SetCellAlignment(n, 1, wx.ALIGN_CENTRE, wx.ALIGN_CENTRE)
            #------------attendances
            self.myGrid.SetCellValue(n , 2, item[2])
            if item[2] == 'All Present':
                self.myGrid.SetCellTextColour(n, 2, '#516c1a')
            elif item[2] == 'Student is absent':
                self.myGrid.SetCellTextColour(n, 2, wx.RED)
            elif item[2] == 'Teacher is absent':
                self.myGrid.SetCellTextColour(n, 2, '#e1cf37')
            self.myGrid.SetCellFont(n, 2, wx.Font(10, wx.DEFAULT, wx.NORMAL, wx.BOLD))
            self.myGrid.SetCellAlignment(n, 2, wx.ALIGN_CENTRE, wx.ALIGN_CENTRE)
            #-----------date
            self.myGrid.SetCellValue(n , 3, item[3])# date
            self.myGrid.SetCellBackgroundColour(n, 3, '#deffb4')
            #-----------
            if item[4] == 'NONE':
                self.myGrid.SetCellValue(n, 4, '')
            else:
                self.myGrid.SetCellValue(n , 4, item[4]) # reading

            if item[5] == 'NONE':
                self.myGrid.SetCellValue(n, 5, '')
            else:
                self.myGrid.SetCellValue(n , 5, item[5]) # setting

            if item[6] == 'NONE':
                self.myGrid.SetCellValue(n, 6, '')
            else:
                self.myGrid.SetCellValue(n , 6, item[6]) # rudiments

            if item[7] == 'NONE':
                self.myGrid.SetCellValue(n, 7, '')
            else:
                self.myGrid.SetCellValue(n , 7, item[7]) # coordination

            if item[8] == 'NONE':
                self.myGrid.SetCellValue(n, 8, '')
            else:
                self.myGrid.SetCellValue(n , 8, item[8]) # styles

            if item[9] == 'NONE':
                self.myGrid.SetCellValue(n, 9, '')
            else:
                self.myGrid.SetCellValue(n , 9, item[9]) # minusone

            if item[10] == 'NONE':
                self.myGrid.SetCellValue(n, 10, '')
            else:
                self.myGrid.SetCellValue(n , 10, item[10]) # other1

            if item[11] == 'NONE':
                self.myGrid.SetCellValue(n, 11, '')
            else:
                self.myGrid.SetCellValue(n , 11, item[11]) # other2

            self.myGrid.SetCellValue(n , 12, item[12]) # other3
            if item[12] == 'NONE':
                self.myGrid.SetCellValue(n, 12, '')

            if item[13] == 'NONE':
                self.myGrid.SetCellValue(n, 13, '')
            else:
                self.myGrid.SetCellValue(n , 13, item[13]) # votes

            if item[14] == 'NONE':
                self.myGrid.SetCellValue(n , 14, '')
            else:
                self.myGrid.SetCellValue(n , 14, item[14]) # notes
            self.myGrid.SetCellBackgroundColour(n, 14, '#fffa9a')

        self.myGrid.AutoSizeColumns(setAsMin=True) # resize all columns
        self.myGrid.AutoSizeRows(setAsMin=True) # resize all rows
    #--------------------------------------------------------------------#
    #--------------------------------EVENT-------------------------------#
    def editCells(self, event):
        """
        Make editable the columns in the row where the
        cell is selected only
        """
        row = self.currentlySelectedCell[0]
        col = self.currentlySelectedCell[1]
        val = self.myGrid.GetCellValue(row,col)

        dlg = wx.TextEntryDialog(self, 'Insert a new string:',
                                 "Change cell value",val,
                                 style=wx.TE_MULTILINE|wx.OK|wx.CANCEL
                                 )
        choices = ["All Present","Student is absent",
                   "Teacher is absent"
                   ]
        choiceDlg = wx.SingleChoiceDialog(self, "Change Attendance",
                                          "Choices",choices
                                          )
        if self.rowEdit is None or self.rowEdit == row:
            if col == 0 or col == 1:
                wx.MessageBox("This column can not be changed",
                'Change Not Allowed', wx.ICON_EXCLAMATION, self)
                return

            if self.IDlesson not in self.backUp:
                del self.backUp[:] # first clear list
                for n in range(15):
                    i = self.myGrid.GetCellValue(row, n)
                    self.backUp.append(i)

            if col == 2:
                if choiceDlg.ShowModal() == wx.ID_OK:
                    ret = choiceDlg.GetStringSelection()
                    dlg.Destroy()
                else:
                    return
            else:
                if dlg.ShowModal() == wx.ID_OK:
                    ret = dlg.GetValue()
                    dlg.Destroy()
                else:
                    return

            self.myGrid.SetCellValue(row , col, ret)

            del self.newsEdit[:] # first clear list
            for n in range(15):
                i = self.myGrid.GetCellValue(row, n)
                self.newsEdit.append(i)

            self.rowEdit = row
            self.rollbackBtn.Enable()
            self.applyBtn.Enable()
        else:
            msg = ("Before to edit cells in others rows, you must\n"
                   "push  'Apply Commit' button for render changes\n"
                   "into the edited columns selected in gray.\n\n"
                   "Instead, if you want to remove any change push\n"
                   "'Uncommit Last' button")
            self.myGrid.SelectRow(self.rowEdit, addToSelected=True)
            wx.MessageBox(msg, 'Change Not Allowed', wx.ICON_EXCLAMATION, self)
    #----------------------------------------------------------------------
    def restroreLast(self, event):
        """
        Retrieve last change and reset attributes. The data
        retrieving of previous setting it is restored.
        WARNING: this not restore after a apply-commit
        """
        for n, item in enumerate(self.backUp):
            self.myGrid.SetCellValue(self.rowEdit , n, self.backUp[n])
        self.editBtn.Disable()
        self.rollbackBtn.Disable()
        self.applyBtn.Disable()
        self.rowEdit = None
        del self.newsEdit[:]
        del self.backUp[:]
        self.IDlesson = None
    #----------------------------------------------------------------------
    def makeChange(self, event):
        """
        Allow to save changes in db (table Lesson)
        """
        for n, item in enumerate(self.newsEdit):# if empty str fill out with NONE str
            if item.strip() == '':
                self.newsEdit[n] = 'NONE'

        change = School_Class().change_lesson_items(self.newsEdit, self.path_db)

        if change[0]:
            wx.MessageBox(change[1], 'Error', wx.ICON_ERROR, self)
            return

        self.editBtn.Disable()
        self.rollbackBtn.Disable()
        self.applyBtn.Disable()
        self.rowEdit = None
        del self.newsEdit[:]
        del self.backUp[:]
        self.IDlesson = None

        self.index = 0
        self.setting()
        wx.MessageBox("Successfull storing !", "Success", wx.OK, self)
        #----------------------------------------------------------------------
    def onSingleSelect(self, event):
        """
        Get the selection of a single cell by clicking or
        moving the selection with the arrow keys
        """
        self.currentlySelectedCell = (event.GetRow(),
                                    event.GetCol())
        self.IDlesson = self.myGrid.GetCellValue(self.currentlySelectedCell[0],
                                                 0)
        if event.GetRow() >= self.index:
            self.editBtn.Disable()
            return
        else:
            self.editBtn.Enable()
        event.Skip()
    #----------------------------------------------------------------------


from os import environ
import requests
from flask import (Blueprint, render_template, redirect,
                   url_for, flash, request, abort)
from flask_login import login_required, current_user
from sqlalchemy.exc import IntegrityError
from sqlalchemy.sql import func
from application import db
from application.forms import AddEntryForm, UpdateEntryForm, SearchForm
from application.models import Word

main = Blueprint('main', __name__,
                 template_folder='templates',
                 static_folder='static')

@main.route('/')
def index():
    '''Index route'''

    words = Word.query.order_by(func.random()).limit(1)
    return render_template('main/index.html', words=words)

def query_api(word):
    '''Query API for translation'''

    api_key = environ.get('API_KEY')

    params = (
        ('l', 'enes'),
        ('q', word),
    )
    headers = {"X-Secret": api_key}
    response = requests.get('https://api.pons.com/v1/dictionary',
                            params=params, headers=headers)
    return response

@main.route('/translate', methods=['GET', 'POST'])
def translation():
    '''Translate ES => EN or EN => ES'''

    form = SearchForm()
    if form.validate_on_submit():
        if current_user.is_anonymous:
            flash('Please sign in to translate words.', 'warning')
            return redirect(url_for('main.translation'))
        else:
            query_api(form.word.data)
            return
    return render_template('main/translation.html', form=form)

@main.route('/add-word', methods=['GET', 'POST'])
@login_required
def add_word():
    '''Add a word to database'''

    form = AddEntryForm()
    if form.validate_on_submit():
        try:
            word = Word(word_es=form.word_es.data,
                        sentence1_es=form.sentence1_es.data,
                        sentence1_en=form.sentence1_en.data,
                        sentence2_es=form.sentence2_es.data,
                        sentence2_en=form.sentence2_en.data,
                        sentence3_es=form.sentence3_es.data,
                        sentence3_en=form.sentence3_en.data,
                        definition1_en=form.definition1_en.data,
                        definition2_en=form.definition2_en.data,
                        definition3_en=form.definition3_en.data,
                        definition4_en=form.definition4_en.data,
                        user_id=current_user.id)
            db.session.add(word)
            db.session.commit()
            db.session.remove()
            flash('Word added successfully', 'success')
            return redirect(url_for('main.add_word', _external=True))
        except IntegrityError:
            db.session.rollback()
            return redirect(url_for('main.add_word', _external=True))
    user_initials = current_user.firstname[0] + current_user.lastname[0]
    return render_template('main/add_word.html', form=form,
                           user_initials=user_initials)

@main.route('/word/update/<int:word_id>', methods=['GET', 'POST'])
@login_required
def update_word(word_id):
    '''Update a word'''

    word = Word.query.get_or_404(word_id)
    if word.author != current_user:
        abort(403)
    form = UpdateEntryForm()
    if request.method == 'GET':
        form.word_es.data = word.word_es
        form.sentence1_es.data = word.sentence1_es
        form.sentence1_en.data = word.sentence1_en
        form.sentence2_es.data = word.sentence2_es
        form.sentence2_en.data = word.sentence2_en
        form.sentence3_es.data = word.sentence3_es
        form.sentence3_en.data = word.sentence3_en
        form.definition1_en.data = word.definition1_en
        form.definition2_en.data = word.definition2_en
        form.definition3_en.data = word.definition3_en
        form.definition4_en.data = word.definition4_en
    elif form.validate_on_submit():
        try:
            word.word_es = form.word_es.data
            word.sentence1_es = form.sentence1_es.data
            word.sentence1_en = form.sentence1_en.data
            word.sentence2_es = form.sentence2_es.data
            word.sentence2_en = form.sentence2_en.data
            word.sentence3_es = form.sentence3_es.data
            word.sentence3_en = form.sentence3_en.data
            word.definition1_en = form.definition1_en.data
            word.definition2_en = form.definition2_en.data
            word.definition3_en = form.definition3_en.data
            word.definition4_en = form.definition4_en.data
            db.session.commit()
            db.session.remove()
            flash('Word updated successfully', 'success')
            return redirect(url_for('main.display_word',
                            word_id=word_id, _external=True))
        except IntegrityError:
            db.session.rollback()
            return redirect(url_for('main.update_word', _external=True))
    content = {
            'form': form,
            'word': word
            }
    return render_template('main/update_word.html', **content)

@main.route('/word/<int:word_id>', methods=['GET', 'POST'])
@login_required
def display_word(word_id):
    '''Display a vocabulary word'''

    word = Word.query.get_or_404(word_id)
    return render_template('main/word.html', word=word)

@main.route('/vocabulary')
@login_required
def vocabulary():
    '''Vocabulary route'''

    page = request.args.get('page', 1, type=int)
    words = Word.query.paginate(page=page, per_page=2)
    user_initials = current_user.firstname[0] + current_user.lastname[0]
    return render_template('main/vocabulary.html', words=words,
                           user_initials=user_initials)

@main.route('/mywords')
@login_required
def display_user_words():

    words = Word.query.filter(Word.user_id == current_user.id).all()
    return render_template('main/mywords.html', words=words)

@main.app_errorhandler(404)
def page_not_found(error):
    '''404 Page not found'''

    return render_template('404.html'), 404

@main.app_errorhandler(500)
def internal_server_error(error):
    '''500 Internal server error'''

    return render_template('500.html'), 500


#!/usr/bin/python
import json
from bson import json_util
import bottle
from bottle import route, run, request, abort
import datetime
from pymongo import MongoClient

connection = MongoClient('localhost', 27017)
db = connection['market']
collection = db['stocks']
# set up URI paths for REST service

@route('/update', method='GET')
def update():
  id=request.query.id
  result=request.query.result
  findJson={"id":id}
  updateJson={"result":result}
  return update_document(findJson, updateJson)

def update_document(findDocument, newDocument):
  try:
    result=collection.update(findDocument, {"$set": newDocument})
  except Exception as ve:
      return False

if __name__ == '__main__':
 #app.run(debug=True)
 run(host='localhost', port=8080)


class 수학:
    def __init__(self):
        self.원주율=3.14
    def 원뿔부피(self,반지름,높이):
        부피=self.원주율*반지름*반지름*높이/3
        return 부피

대학수학=수학()
반지름=input("반지름을 입력하세요:")
높이=input("높이를 입력하세요:")
print(f"반지름이 {반지름}이고, 높이가 {높이}이면 원뿔 부피는 {대학수학.원뿔부피(int(반지름),int(높이))}")


import pygame
import typing

class EventHandler:
    def __init__(self) -> None:
        self.events = []
        self.mouse_rel = (0, 0)

        self._keypressed_callbacks: dict[int, list[typing.Callable]] = {}
        self._keydown_callbacks: dict[int, list[typing.Callable]] = {}
        self._keyup_callbacks: dict[int, list[typing.Callable]] = {}

        self._buttonpressed_callbacks: dict[int, list[typing.Callable]] = {}
        self._buttondown_callbacks: dict[int, list[typing.Callable]] = {}
        self._buttonup_callbacks: dict[int, list[typing.Callable]] = {}

        self._mouse_move_callbacks: list[typing.Callable[[tuple[int, int]], None]] = []

        self._quit_callbacks: list[typing.Callable] = []

    def remove_key_binding(self,
                                 key: int) -> None:
        """Removes all callbacks from the key."""

        if key in self._keypressed_callbacks:
            self._keypressed_callbacks.pop(key)
        if key in self._keydown_callbacks:
            self._keydown_callbacks.pop(key)
        if key in self._keyup_callbacks:
            self._keyup_callbacks.pop(key)

    def remove_button_binding(self,
                                    button: int) -> None:
        """Removes all callbacks from the button."""

        if button in self._buttonpressed_callbacks:
            self._buttonpressed_callbacks.pop(button)
        if button in self._buttondown_callbacks:
            self._buttondown_callbacks.pop(button)
        if button in self._buttonup_callbacks:
            self._buttonup_callbacks.pop(button)

    def remove_callback(self,
                              callback: typing.Callable) -> None:
        """Removes all callbacks from the callback."""

        for key in self._keypressed_callbacks:
            while callback in self._keypressed_callbacks[key]:
                self._keypressed_callbacks[key].remove(callback)
        for key in self._keydown_callbacks:
            while callback in self._keydown_callbacks[key]:
                self._keydown_callbacks[key].remove(callback)
        for key in self._keyup_callbacks:
            while callback in self._keyup_callbacks[key]:
                self._keyup_callbacks[key].remove(callback)
        for button in self._buttonpressed_callbacks:
            while callback in self._buttonpressed_callbacks[button]:
                self._buttonpressed_callbacks[button].remove(callback)
        for button in self._buttondown_callbacks:
            while callback in self._buttondown_callbacks[button]:
                self._buttondown_callbacks[button].remove(callback)
        for button in self._buttonup_callbacks:
            while callback in self._buttonup_callbacks[button]:
                self._buttonup_callbacks[button].remove(callback)
        while callback in self._mouse_move_callbacks:
            self._mouse_move_callbacks.remove(callback)
        while callback in self._quit_callbacks:
            self._quit_callbacks.remove(callback)

    def clear(self) -> None:
        """Removes all callbacks."""

        self._keypressed_callbacks = {}
        self._keydown_callbacks = {}
        self._keyup_callbacks = {}
        self._buttonpressed_callbacks = {}
        self._buttondown_callbacks = {}
        self._buttonup_callbacks = {}
        self._mouse_move_callbacks = []
        self._quit_callbacks = []

    def register_keypressed_callback(self,
                                     key: int,
                                     callback: typing.Callable) -> None:
        """Registers a callback to be called when the key is pressed."""

        if key not in self._keypressed_callbacks:
            self._keypressed_callbacks[key] = []
        self._keypressed_callbacks[key].append(callback)

    def register_keydown_callback(self,
                                  key: int,
                                  callback: typing.Callable) -> None:
        """Registers a callback to be called when the key is down."""

        if key not in self._keydown_callbacks:
            self._keydown_callbacks[key] = []
        self._keydown_callbacks[key].append(callback)

    def register_keyup_callback(self,
                                key: int,
                                callback: typing.Callable) -> None:
        """Registers a callback to be called when the key is up."""
        if key not in self._keyup_callbacks:
            self._keyup_callbacks[key] = []
        self._keyup_callbacks[key].append(callback)

    def register_buttonpressed_callback(self,
                                        button: int,
                                        callback: typing.Callable) -> None:
        """Registers a callback to be called when the button is pressed."""
        if button-1 not in self._buttonpressed_callbacks:
            self._buttonpressed_callbacks[button-1] = []
        self._buttonpressed_callbacks[button-1].append(callback)

    def register_buttondown_callback(self,
                                     button: int,
                                     callback: typing.Callable) -> None:
        """Registers a callback to be called when the button is down."""
        if button not in self._buttondown_callbacks:
            self._buttondown_callbacks[button] = []
        self._buttondown_callbacks[button].append(callback)

    def register_buttonup_callback(self,
                                   button: int,
                                   callback: typing.Callable) -> None:
        """Registers a callback to be called when the button is up."""
        if button not in self._buttonup_callbacks:
            self._buttonup_callbacks[button] = []
        self._buttonup_callbacks[button].append(callback)

    def register_mouse_move_callback(self,
                                     callback: typing.Callable[[tuple[int, int]], None]) -> None:
        """Registers a callback to be called when the cursor is dragging."""
        self._mouse_move_callbacks.append(callback)

    def register_quit_callback(self,
                               callback: typing.Callable) -> None:
        """Registers a callback to be called when the game is quit."""
        self._quit_callbacks.append(callback)

    async def handle_events(self) -> None:
        """Handles all events."""
        self.events = pygame.event.get()
        self.mouse_rel = pygame.mouse.get_rel()

        for event in self.events:
            if event.type == pygame.QUIT:
                await self._quit()
                continue

            if event.type == pygame.KEYDOWN:
                await self._keydown(event.key)
                continue

            if event.type == pygame.KEYUP:
                await self._keyup(event.key)
                continue

            if event.type == pygame.MOUSEBUTTONDOWN:
                await self._buttondown(event.button)
                continue

            if event.type == pygame.MOUSEBUTTONUP:
                await self._buttonup(event.button)
                continue

            if event.type == pygame.MOUSEMOTION:
                await self._mouse_move()

        key_pressed = pygame.key.get_pressed()
        button_pressed = pygame.mouse.get_pressed(5)

        for key in self._keypressed_callbacks:
            if key_pressed[key]:
                await self._keypressed(key)

        for button in self._buttonpressed_callbacks:
            if button_pressed[button]:
                await self._buttonpressed(button)

    async def _keypressed(self,
                          key: int) -> None:
        """Calls all callbacks registered to the key pressed."""
        if key not in self._keypressed_callbacks:
            return

        for callback in self._keypressed_callbacks[key]:
            await callback()

    async def _keydown(self,
                       key: int) -> None:
        """Calls all callbacks registered to the key down."""
        if key not in self._keydown_callbacks:
            return

        for callback in self._keydown_callbacks[key]:
            await callback()

    async def _keyup(self,
                     key: int) -> None:
        """Calls all callbacks registered to the key leave."""
        if key not in self._keyup_callbacks:
            return

        for callback in self._keyup_callbacks[key]:
            await callback()

    async def _buttonpressed(self,
                             button: int) -> None:
        """Calls all callbacks registered to the button pressed."""
        if button not in self._buttonpressed_callbacks:
            return

        for callback in self._buttonpressed_callbacks[button]:
            await callback()

    async def _buttondown(self,
                          button: int) -> None:
        """Calls all callbacks registered to the button down."""
        if button not in self._buttondown_callbacks:
            return

        for callback in self._buttondown_callbacks[button]:
            await callback()

    async def _buttonup(self,
                        button: int) -> None:
        """Calls all callbacks registered to the button up."""
        if button not in self._buttonup_callbacks:
            return

        for callback in self._buttonup_callbacks[button]:
            await callback()

    async def _mouse_move(self) -> None:
        """Calls all callbacks registered to the mouse move."""
        for callback in self._mouse_move_callbacks:
            await callback(self.mouse_rel)

    async def _quit(self) -> None:
        """Calls all callbacks registered to the quit event."""
        for callback in self._quit_callbacks:
            await callback()


#! python

# Created by Aleksei Wan on 13.11.2019

# Imports
import os
import sys
import json
from argparse import ArgumentParser
import lightgbm as lgbm
import numpy as np
from random import shuffle

sys.path.append(os.path.join(os.path.dirname(__file__), "../scripts"))
from perturb_parameters import generate_bdst_param_pack

def train_lgbm_model(params, training_data, validation_data=None, save_model_path: str = 'lgbm-model.txt'):
    bst = lgbm.train(params, training_data, valid_sets=[validation_data])
    bst.save_model(save_model_path)
    return bst

def calculate_acc(predictions, labels):
    acc = 0
    for idx, val in enumerate(predictions):
        if np.argmax(val) == labels[idx]:
            acc += 1
    acc /= len(labels)
    return acc

def make_printable(x) -> str: return str(round(100 * float(x), 3))

if __name__ == "__main__":
    parser = ArgumentParser(description='Create a LightGBM tree based on provided data')
    parser.add_argument('--input_file', '-i', type=str, default='results.json', help='File containing results')
    parser.add_argument('--epochs', '-e', type=int, default=3, help='File containing results')
    args = parser.parse_args()
    path_to_check = os.path.abspath(args.input_file)
    if not os.path.exists(path_to_check):
        print('Provided path', path_to_check, 'is not a valid directory. Please try again')
        sys.exit(-1)

    # Read Input JSON file
    with open(path_to_check, 'r') as file:
        contents = json.load(file)

    # Create data sets
    shuffle(contents)
    data_list = []
    labels = []
    for element in contents:
        labels.append(element[0])
        data_list.append(element[1])
    idx1 = int(0.8 * len(data_list))
    idx2 = idx1 + int(0.1 * len(data_list))
    train_data = np.array(data_list[:idx1])
    train_labels = np.array(labels[:idx1])
    valid_data = np.array(data_list[idx1:idx2])
    valid_labels = np.array(labels[idx1:idx2])
    test_data = np.array(data_list[idx2:])
    test_labels = np.array(labels[idx2:])
    training_data = lgbm.Dataset(train_data, label=train_labels, params={'verbose': -1})
    validation_data = lgbm.Dataset(valid_data, label=valid_labels, params={'verbose': -1})

    # Run training
    acc_list = np.zeros((args.epochs, 3))
    param_list = []
    for i in range(args.epochs):
        param_list.append(generate_bdst_param_pack())

        bst = train_lgbm_model(params=param_list[i], training_data=training_data, validation_data=validation_data,
                               save_model_path='lgbm-model_' + str(i) + '.txt')

        train_acc = calculate_acc(bst.predict(train_data), train_labels)
        valid_acc = calculate_acc(bst.predict(valid_data), valid_labels)
        test_acc = calculate_acc(bst.predict(test_data), test_labels)

        acc_list[i][0] = calculate_acc(bst.predict(train_data), train_labels)
        acc_list[i][1] = calculate_acc(bst.predict(valid_data), valid_labels)
        acc_list[i][2] = calculate_acc(bst.predict(test_data), test_labels)

    np.savetxt('lgbm_model_accuracies.csv', acc_list, delimiter=",", fmt='%s')
    with open('lgbm_model_params.txt', 'w') as outfile:
        json.dump(param_list, outfile)

    vt_acc_list = np.array([0.5 * (a[1] + a[2]) for a in acc_list.tolist()])

    best_tree_idx = np.argmax(vt_acc_list)
    print('\nBest Tree:', best_tree_idx, '(with validation/test accuracy',
          make_printable(vt_acc_list[best_tree_idx]) + '%)')
    print('Best Tree Params:', param_list[best_tree_idx], '\n')

    vt_acc_list[best_tree_idx] = 0
    best_tree_idx = np.argmax(vt_acc_list)
    print('Second Best Tree:', best_tree_idx, '(with validation/test accuracy',
          make_printable(vt_acc_list[best_tree_idx]) + '%)')
    print('Second Best Tree Params:', param_list[best_tree_idx])

    vt_acc_list[best_tree_idx] = 0
    best_tree_idx = np.argmax(vt_acc_list)
    print('Third Best Tree:', best_tree_idx, '(with validation/test accuracy',
          make_printable(vt_acc_list[best_tree_idx]) + '%)')
    print('Third Best Tree Params:', param_list[best_tree_idx])

    print('Training Samples:', len(train_labels))
    print('Validation Samples:', len(valid_labels))
    print('Testing Samples:', len(test_labels))


import logging
import unittest
from unittest.mock import patch

import arrow

import omicron
from omicron.models.valuation import Valuation
from tests import init_test_env, start_omega

logger = logging.getLogger(__name__)

class ValuationTest(unittest.IsolatedAsyncioTestCase):
    async def asyncSetUp(self) -> None:
        self.cfg = init_test_env()
        self.omega = await start_omega()

        # hack: enable postgres during unittest
        self.cfg.postgres.enabled = True
        await omicron.init()

    async def asyncTearDown(self) -> None:
        await omicron.shutdown()
        if self.omega:
            self.omega.kill()

    async def test_crud(self):
        await Valuation.truncate()

        date = arrow.get("2020-10-26").date()
        # step 1, fetch from remote, and create/update into database
        logger.info("step 1: fetch from remote")
        with patch("omicron.has_db", return_value=False):
            recs = await Valuation.get("000001.XSHE", date)
            self.assertEqual(recs[0]["code"], "000001.XSHE")

        # step 2, now data should exist in database
        logger.info("step 2: get data from database")
        recs = await Valuation.get("000001.XSHE", date)
        self.assertEqual(recs[0]["code"], "000001.XSHE")

        # step 3, to fetch more than one securities
        date = arrow.get("2020-11-04").date()
        logger.info("step 3: fetch more than one securities")
        with patch("omicron.has_db", return_value=False):
            recs = await Valuation.get(["000001.XSHE", "600000.XSHG"], date)
            self.assertEqual(2, len(recs))
            self.assertEqual("000001.XSHE", recs[0]["code"])

        # step 4: fetch more than one day, from remote, make sure the order is asc
        logger.info("step 4: one sec many day")
        with patch("omicron.has_db", return_value=False):
            recs = await Valuation.get(["000001.XSHE"], date, n=3)
            self.assertEqual(3, len(recs))
            self.assertEqual(date, recs[2]["frame"])
            self.assertEqual(arrow.get("2020-11-2").date(), recs[0]["frame"])

        # step 5: fetch more than one day, from database, make sure the order is asc
        logger.info("step 5: more than one day")
        recs = await Valuation.get(["000001.XSHE"], date, n=3)
        self.assertEqual(3, len(recs))
        self.assertEqual(date, recs[2]["frame"])
        self.assertEqual(arrow.get("2020-11-2").date(), recs[0]["frame"])

        # step 6: more than one day, more than one sec
        logger.info("step 6: more than one day, more than one sec")
        recs = await Valuation.get(["000001.XSHE", "600000.XSHG"], date, n=3)
        self.assertEqual(6, len(recs))

    async def test_get_circulating_cap(self):
        sec = "000001.XSHE"
        date = arrow.get("2020-11-4").date()
        recs = await Valuation.get_circulating_cap(sec, date, 3)
        self.assertAlmostEqual(1940575.25, recs[0]["circulating_cap"], places=0)
        self.assertEqual(date, recs[-1]["frame"])


def FrabricacióndeFocos():
    # Procesos y datos de entrada
     n= int(input("Digite la cantidad de focos que hay en el lote:"))
     rojo=0
     verde=0
     blanco=0
     foco=0
     for i in range(1,n+1):
            foco = input("Digite el color del foco: rojo, verde o blanco: ")
            if foco =='rojo':
                   rojo = rojo + 1
            elif foco == 'verde':
                   verde = verde + 1
            elif foco =='blanco':
                    blanco = blanco + 1

     print("los focos rojos son:", rojo, "los focos verdes son:", verde, "los focos blancos son:",blanco)
FrabricacióndeFocos()


from __future__ import annotations
import hashlib

class Node:
    def __init__(self, key, value, next_node):
        self.key = key
        self.value = value
        self.next_node = next_node

class ChainedHash:
    def __init__(self, capacity):
        self.capacity = capacity
        self.table = [None] * self.capacity
        self.p = None
        self.pp = None

    def hash_value(self, key):
        if isinstance(key, int):
            return key % self.capacity
        return int(hashlib.sha256(str(key).encode()).hexdigest(), 16) % self.capacity

    def search(self, key):

        hash_index = self.hash_value(key)
        self.p = self.table[hash_index]
        self.pp = None
        while self.p:
            if self.p.key == key:
                return self.p.value
            self.pp = self.p
            self.p = self.p.next_node

        return None

    def add(self, key, value):
        hash_index = self.hash_value(key)
        p = self.table[hash_index]
        while p:
            if p.key == key:
                return False
            p = p.next_node

        temp = Node(key, value, self.table[hash_index])
        self.table[hash_index] = temp
        return True

    def remove(self, key):
        target = self.search(key)
        if target:
            if self.pp:
                self.pp = self.p.next_node
            else:
                self.table[self.hash_value(key)] = self.p.next_node
            return True
        return False

    def dump(self):
        for i in range(self.capacity):
            self.p = self.table[i]
            print(i, end=' ')
            while self.p:
                print(f'  ->{self.p.key} ({self.p.value})', end=' ')
                self.p = self.p.next_node
            print()

table = ChainedHash(13)
while True:
    s = int(input())
    if s == 0:
        break
    else:
        table.add(s, s)

table.dump()


#!/bin/python3

import math
import os
import random
import re
import sys

#
# Complete the 'getTotalX' function below.
#
# The function is expected to return an INTEGER.
# The function accepts following parameters:
#  1. INTEGER_ARRAY a
#  2. INTEGER_ARRAY b
#

def getTotalX(a, b):
    maxval = min(b)
    minval= max(a)
    fac = []

    for i in range(minval,maxval+1):
        pot_fac = [i for x in a if i % x == 0]
        if len(pot_fac) == len(a):
            fac.append(pot_fac[0])
    result = 0
    for i in fac:
        pot_fac = [i for x in b if x % i == 0]
        if len(pot_fac) == len(b):
            result+=1
    return result

a = [2,4]
b = [16,32,96]
getTotalX(a,b)
# if __name__ == '__main__':
#     fptr = open(os.environ['OUTPUT_PATH'], 'w')

#     first_multiple_input = input().rstrip().split()

#     n = int(first_multiple_input[0])

#     m = int(first_multiple_input[1])

#     arr = list(map(int, input().rstrip().split()))

#     brr = list(map(int, input().rstrip().split()))

#     total = getTotalX(arr, brr)

#     fptr.write(str(total) + '\n')

#     fptr.close()


import asyncio

from databases import Database

database = Database("sqlite+aiosqlite:///database.sqlite")

async def bootstrap():
    await database.connect()

    # Create a table.
    query = "CREATE TABLE IF NOT EXISTS HighScores (id INTEGER PRIMARY KEY, name VARCHAR(100), score INTEGER)"
    await database.execute(query=query)

    # Insert some data.
    query = "INSERT INTO HighScores(name, score) VALUES (:name, :score)"
    values = [
        {"name": "Daisy", "score": 92},
        {"name": "Neil", "score": 87},
        {"name": "Carol", "score": 43},
    ]
    await database.execute_many(query=query, values=values)

    # Run a database query.
    query = "SELECT * FROM HighScores"
    rows = await database.fetch_all(query=query)

    print("High Scores:")
    for _ in rows:
        print(_)

if __name__ == "__main__":
    asyncio.run(bootstrap())


from django.shortcuts import render, redirect
from django.urls import reverse
from django.forms import ModelForm

from plus.utils.filters import FilterList
from plus.utils.pager import Pager
from django.db.models import ForeignKey, ManyToManyField
from django.http.request import QueryDict
from django.utils.safestring import mark_safe

import copy

class ChangeList():
    def __init__(self, pma, result_list):
        '''
        PlusModelAdmin对象
        :param pma:
        '''
        self.pma = pma
        self.site = pma.site
        self.request = pma.request

        self.is_edit = pma.is_edit
        self.show_checkbox_col = pma.show_checkbox_col
        self.list_display = pma.list_display
        self.filter_list = pma.filter_list

        self.model_class = pma.model_class
        self.changelist_url = pma.changelist_url
        self.action_list = pma.action_list

        all_count = result_list.count()
        query_params = copy.deepcopy(self.request.GET)
        query_params._mutable = True

        self.pager = Pager(all_counts=all_count, current_page=self.request.GET.get("page"),
                           base_url=self.changelist_url,
                           params_dict=query_params)
        self.result_list = result_list[self.pager.start_index:self.pager.stop_index]

    def option_filter_list(self):
        '''
        组合搜索
        :return:
        '''
        for option in self.filter_list:
            if option.is_func:  # 接收函数的返回值
                obj_list = option.field_or_func(self, option, self.request)
            else:
                # 获取字段（django.db.models下的字段类型）
                field = self.model_class._meta.get_field(option.field_or_func)
                if isinstance(field, ForeignKey):  # 如果是外键字段
                    # rel.model ：当前字段相关联的表
                    obj_list = FilterList(option, field.rel.model.objects.all(), self.request)
                elif isinstance(field, ManyToManyField):
                    obj_list = FilterList(option, field.rel.model.objects.all(), self.request)
                else:  # 当前model内的正常字段
                    obj_list = FilterList(option, field.model.objects.all(), self.request)

            yield obj_list

    def add_btn(self):
        """
        列表页面定制新建数据按钮
        :return:
        """
        pass
        add_url = reverse(
            '%s:%s_%s_add' % (
                self.site.namespace, self.model_class._meta.app_label, self.model_class._meta.model_name))

        _change = QueryDict(mutable=True)
        _change['_params'] = self.request.GET.urlencode()

        tpl = " 新建数据".format(
            add_url,
            _change.urlencode())
        return mark_safe(tpl)

class PlusModelAdmin(object):
    # 行是否可点击（行编辑功能）
    is_edit = False

    # 是否有行勾选按钮
    show_checkbox_col = True

    # 显示哪些字段
    list_display = "__str__"

    # 自定义的批量处理事件
    action_list = []

    def action_delete(self, request):
        pk_list = request.POST.getlist("pk")
        self.model_class.objects.filter(pk__in=pk_list).delete()
        return True

    # action_delete也是一个对象，可以自定义属性
    action_delete.title = "批量删除"

    action_list = [action_delete, ]

    # 过滤的组合条件
    filter_list = []

    # 添加或修改数据时的ModelForm对象（可以定义操作的字段，出错时的提示等）
    model_form = None

    def __init__(self, model_class, site):
        self.model_class = model_class
        self.site = site

        self.app_label = self.model_class._meta.app_label
        self.model_name = self.model_class._meta.model_name

    @property
    def urls(self):
        from django.conf.urls import url, include

        info = (self.model_class._meta.app_label, self.model_class._meta.model_name)

        # 最基本的增删改查
        urlpatterns = [
            url(r'^$', self.changelist_view, name='%s_%s_changelist' % info),
            url(r'^add/$', self.add_view, name='%s_%s_add' % info),
            url(r'^(.+)/delete/$', self.delete_view, name='%s_%s_delete' % info),
            url(r'^(.+)/change/$', self.change_view, name='%s_%s_change' % info),
        ]
        return urlpatterns

    def get_url_params(self, request):
        '''
        获取url的参数
        :param request:
        :return:
        '''

        # request.GET其类型就是一个QueryDict，所以有一个urlencode方法，获取所有的参数
        from django.http.request import QueryDict
        querydict = QueryDict(mutable=True)

        # 如果有参数，在添加完数据之后，需要跳转回原来的页面，所以需要保存之前的这些参数（name=yangzai&page=10）
        if request.GET:
            # 重新自定一个参数{"_params":'name=yangzai&page=10'}
            # 当跳转的时候，去除_params的值，和url拼接
            querydict["_params"] = request.GET.urlencode()  # name=yangzai&page=10
        else:
            querydict["_params"] = ""

        return querydict.urlencode()

    @property
    def changelist_param_url(self):
        '''
        获取数据列表页的url（带参数）
        :return:
        '''
        base_url = reverse(
            "%s:%s_%s_changelist" % (
                self.site.namespace, self.app_label, self.model_name))
        return "%s?%s" % (base_url, self.request.GET.urlencode())

    @property
    def changelist_url(self):
        '''
        获取数据列表页的url
        :return:
        '''
        return reverse(
            "%s:%s_%s_changelist" % (
                self.site.namespace, self.app_label, self.model_name))

    def get_change_list_condition(self, query_params):
        '''
        过滤不合法的查询字段
        :param query_params:
        :return:
        '''

        field_list = [item.name for item in self.model_class._meta._get_fields()]
        condition = {}
        for k in query_params:
            if k not in field_list:
                # raise Exception('条件查询字段%s不合法，合法字段为：%s' % (k, ",".join(field_list)))
                continue
            condition[k + "__in"] = query_params.getlist(k)
        return condition

    def get_model_form(self):
        '''
        生成一个默认的ModelForm
        :return:
        '''
        if self.model_form: return self.model_form

        # ModelForm可以自动生成标签
        class MyModelForm(ModelForm):
            class Meta:
                model = self.model_class
                fields = "__all__"

        return MyModelForm

    def changelist_view(self, request):
        '''
        显示数据列表
        :param request:
        :return:
        '''

        self.request = request
        result_list = self.model_class.objects.filter(**self.get_change_list_condition(request.GET))

        if request.method == "POST":
            action_event = request.POST.get("action")

            if hasattr(self, action_event):
                # 执行函数
                self_action = getattr(self, action_event)
                if self_action(request):  # 跳转原地址
                    return redirect(self.changelist_param_url)
                else:  # 跳转到数据列表首页
                    return redirect(self.changelist_url)
            else:
                return redirect(self.changelist_param_url)

        change_list = ChangeList(self, result_list)

        context = {
            'chl': change_list,
        }
        return render(request, "plus/change_list.html", context)

    def add_view(self, request):
        '''
        增加数据项
        :param request:
        :return:
        '''
        self.request = request
        if request.method == "GET":
            model_form = self.get_model_form()()
            from  django.forms.boundfield import BoundField
            return render(request, "plus/add.html", {"form": model_form, "modeladmin_obj": self})
        else:
            obj = self.get_model_form()(data=request.POST, files=request.FILES)
            _params = request.GET.get("_params")
            if obj.is_valid():
                popup_obj = obj.save()
                changelist_url = reverse(
                    "{0}:{1}_{2}_changelist".format(self.site.namespace, self.app_label, self.model_name))
                changelist_url = "%s?%s" % (changelist_url, _params)

                popup_id = request.GET.get("_popup_id")
                # 这个的话是表示这个一个新弹出的popup窗口的提交请求
                if popup_id:
                    return render(request, "plus/form_add_popup.html",
                                  {"pk": popup_obj.pk, "text": str(popup_obj), "popup_id": popup_id})
                else:
                    # 正常的请求，跳回页面
                    return redirect(changelist_url)
            else:

                return render(request, "plus/add.html", {"form": obj, "modeladmin_obj": self})

    def delete_view(self, request, pk):
        '''
        删除数据项
        :param request:
        :param pk: 删除的主键
        :return:
        '''
        obj = self.model_class.objects.filter(pk=pk).delete()
        if not obj:
            return HttpResponse("出错了")

        _params = request.GET.get("_params")
        changelist_url = reverse(
            "{0}:{1}_{2}_changelist".format(self.site.namespace, self.app_label, self.model_name))
        changelist_url = "%s?%s" % (changelist_url, _params)

        # 跳回页面
        return redirect(changelist_url)

    def change_view(self, request, pk):
        '''
        修改数据项
        :param request:
        :param pk: 删除的主键
        :return:
        '''
        obj = self.model_class.objects.filter(pk=pk).first()
        if not obj:
            return HttpResponse("出错了")

        if request.method == "GET":
            model_form = self.get_model_form()(instance=obj)
            return render(request, "plus/add.html", {"form": model_form, "modeladmin_obj": self})
        else:
            # 这里要加instance，才能去处理如果库里有就更新
            obj = self.get_model_form()(data=request.POST, files=request.FILES, instance=obj)
            _params = request.GET.get("_params")
            if obj.is_valid():
                obj.save()
                changelist_url = reverse(
                    "{0}:{1}_{2}_changelist".format(self.site.namespace, self.app_label, self.model_name))
                changelist_url = "%s?%s" % (changelist_url, _params)
                return redirect(changelist_url)
            else:
                return render(request, "plus/add.html", {"form": obj, "modeladmin_obj": self})

from django.shortcuts import HttpResponse

class PlusSite(object):
    def __init__(self):
        self._registry = {}
        self.namespace = "plus"
        self.app_name = "plus"

    def register(self, model_class, model_admin=PlusModelAdmin):
        self._registry[model_class] = model_admin(model_class, self)

    def login(self, request):
        return HttpResponse("login")

    def get_urls(self):
        from django.conf.urls import url, include

        ret = [
            url(r"^login/", self.login, name="login")
        ]

        for model_cls, model_am in self._registry.items():
            app_label = model_cls._meta.app_label
            model_name = model_cls._meta.model_name
            # 做路由分发include(model_am.urls)
            ret.append(url(r"^%s/%s/" % (app_label, model_name), include(model_am.urls)))
        return ret

    @property
    def urls(self):
        return self.get_urls(), self.app_name, self.namespace

# 始终只有一个site对象
site = PlusSite()


class Jedi:
    def __init__(self, nombre, especie, anio_nacimiento, color_sable, ranking, maestros):
        self.nombre = nombre
        self.especie = especie
        self.anio_nacimiento = anio_nacimiento
        self.color_sable = color_sable
        self.ranking = ranking
        self.maestros = maestros

def crear_arboles(jedis):
    arbol_nombre = {}
    arbol_ranking = {}
    arbol_especie = {}

    for jedi in jedis:
        arbol_nombre[jedi.nombre] = jedi

        if jedi.ranking not in arbol_ranking:
            arbol_ranking[jedi.ranking] = []
        arbol_ranking[jedi.ranking].append(jedi)

        if jedi.especie not in arbol_especie:
            arbol_especie[jedi.especie] = []
        arbol_especie[jedi.especie].append(jedi)

    return arbol_nombre, arbol_ranking, arbol_especie

def barrido_inorden(arbol):
    for key in sorted(arbol.keys()):
        if isinstance(arbol[key], list):
            for jedi in arbol[key]:
                print(jedi.nombre, jedi.ranking)
        else:
            print(arbol[key].nombre, arbol[key].ranking)

def barrido_por_nivel(arbol):
    for key in sorted(arbol.keys()):
        print(key)
        for jedi in arbol[key]:
            print("  ", jedi.nombre)

def mostrar_info(jedis, nombres):
    for nombre in nombres:
        jedi = jedis.get(nombre)
        if jedi:
            print(f"Nombre: {jedi.nombre}, Especie: {jedi.especie}, Año de nacimiento: {jedi.anio_nacimiento}, "
                  f"Color de sable: {jedi.color_sable}, Ranking: {jedi.ranking}, Maestros: {jedi.maestros}")
        else:
            print(f"No se encontró información para {nombre}")

def listar_jedi_color_verde(jedis):
    jedi_color_verde = [jedi.nombre for jedi in jedis if jedi.color_sable.lower() == 'verde']
    print("Jedi con sable de luz verde:", jedi_color_verde)

def listar_jedi_con_maestros(jedis):
    maestros_en_archivo = set(jedi.nombre for jedi in jedis)
    jedi_con_maestros = [jedi.nombre for jedi in jedis if any(maestro in maestros_en_archivo for maestro in jedi.maestros)]
    print("Jedi con maestros en el archivo:", jedi_con_maestros)

def mostrar_jedi_por_especie(jedis, especies):
    jedi_por_especie = [jedi for jedi in jedis if jedi.especie in especies]
    for jedi in jedi_por_especie:
        print(f"Nombre: {jedi.nombre}, Especie: {jedi.especie}")

def listar_jedi_letra_a_y_guion(jedis):
    jedi_letra_a_o_guion = [jedi.nombre for jedi in jedis if jedi.nombre.lower().startswith('a') or '-' in jedi.nombre]
    print("Jedi que comienzan con A o contienen un '-':", jedi_letra_a_o_guion)

jedi1 = Jedi("Yoda", "Desconocida", 896, "Verde", "Jedi Master", ["Desconocido"])
jedi2 = Jedi("Luke-Skywalker", "Humano", 19, "Azul", "Jedi Knight", ["Yoda", "Obi-Wan Kenobi"])
jedi3 = Jedi("Darth-Vader", "Humano", 300, "Rojo", "Padawan", ["yoda"])

jedis = [jedi1, jedi2, jedi3]
arbol_nombre, arbol_ranking, arbol_especie = crear_arboles(jedis)

print("Barrido inorden por nombre:")
barrido_inorden(arbol_nombre)

print("\nBarrido inorden por ranking:")
barrido_inorden(arbol_ranking)

print("\nBarrido por nivel por ranking:")
barrido_por_nivel(arbol_ranking)

print("\nBarrido por nivel por especie:")
barrido_por_nivel(arbol_especie)

print("\nMostrar información de Yoda y Luke-Skywalker:")
mostrar_info({jedi.nombre: jedi for jedi in jedis}, ["Yoda", "Luke-Skywalker"])

listar_jedi_color_verde(jedis)

listar_jedi_con_maestros(jedis)

mostrar_jedi_por_especie(jedis, ["Togruta", "Cerean"])

listar_jedi_letra_a_y_guion(jedis)


# part of the ASTA project to align wav2vec and cgn with nw
# further analysis done here.

import glob
import random
import os
from utils import needleman_wunch as nw
# from text.models import Textgrid

cgn_wav2vec_dir = '/vol/tensusers3/mbentum/cgn_wav2vec/'
cgn_align = '/vol/tensusers3/mbentum/cgn_wav2vec_align/'

def table_filenames():
    fn = glob.glob(cgn_wav2vec_dir + '*.table')
    return fn

def text_filename():
    fn = glob.glob(cgn_wav2vec_dir + '*.txt')
    return fn

def load_table(filename):
    with open(filename) as fin:
        t = fin.read()
    temp= [x.split('\t') for x in t.split('\n') if x]
    table = []
    for grapheme, start, end in temp:
        table.append([grapheme,float(start), float(end)])
    return table

def load_text(filename):
    with open(filename) as fin:
        t = fin.read()
    return t

def table_filename_to_cgn_id(f):
    cgn_id = f.split('/')[-1].split('.')[0]
    return cgn_id

def make_alignments():
    fn = table_filenames()
    random.shuffle(fn)
    for f in fn:
        cgn_id = table_filename_to_cgn_id(f)
        align_filename = cgn_align + cgn_id
        if os.path.isfile(align_filename):
            print('skiping',cgn_id)
            continue
        print('handling',cgn_id)
        Align(cgn_id)

class Align:
    def __init__(self,cgn_id):
        self.cgn_id = cgn_id
        self.textgrid = Textgrid.objects.get(cgn_id = cgn_id)
        self.awd_words = self.textgrid.word_set.all()
        self.awd_text = ' '.join([w.awd_word for w in self.awd_words])
        self._set_wav2vec_table_and_text()
        self._set_align()

    def _set_wav2vec_table_and_text(self):
        self.wav2vec_base_filename = cgn_wav2vec_dir + self.textgrid.cgn_id
        self.wav2vec_table=load_table(self.wav2vec_base_filename+'.table')
        self.wav2vec_text=load_text(self.wav2vec_base_filename+'.txt')

    def _set_align(self):
        self.align_filename = cgn_align + self.cgn_id
        if os.path.isfile(self.align_filename):
            with open(self.align_filename) as fin:
                self.align = fin.read()
        else:
            self.align = nw.nw(self.awd_text, self.wav2vec_text)
            with open(self.align_filename, 'w') as fout:
                fout.write(self.align)


import unittest
from app import create_app

from fractions import Fraction
from flask_pymongo import PyMongo
from sum import sum
from mockupdb import go, MockupDB, OpQuery

class TestOther(unittest.TestCase):
    def test_list_int(self):
        """
        Test that it can sum a list of integers
        """
        data = [1, 2, 3]
        result = sum(data)
        self.assertEqual(result,6)

    def test_list_fraction(self):
        """
        Test sums fractions
        """
        data = [Fraction(1,4), Fraction(1,4), Fraction(2,5)]
        result = sum(data)
        self.assertEqual(result,Fraction(9,10))

    def test_auto_pass(self):
        pass

    def test_code_error(self):
        with self.assertRaises(NameError):
            some_method()

class TestDb(unittest.TestCase):
    def setUp(self):
        self.server = MockupDB(auto_ismaster={"maxWireVersion": 3})
        self.server.run()
        app = create_app("config_default.TestConfig",self.server.uri+"/test")
        self.app = app.test_client()

    def test_home_status(self):
        result = self.app.get('/')

        self.assertEqual(result.status_code,200)
    def test_home_data(self):
        result = self.app.get('/')
        attrs = vars(result)

        self.assertGreater(len(result.data),0,"Page Length Should not be 0")

    def test_api_home(self):

        future = go(self.app.get,"/api/")
        request = self.server.receives(OpQuery)
        request.reply({"test":"t"});
        http_response = future()
        print(http_response.get_data(as_text=True))
        self.assertIn(b"api",http_response.get_data())

if __name__ == '__main__':
    unittest.main()


from classes.weapons.weapon import Weapon
from tools.math_ops import normalize_victor
import time
from classes.creatures.bullet import Bullet

class TihiyPistolet(Weapon):
    def __init__(self, hero, name='Тихий пистолет', damage=6, recharge_time=0.5, max_bullets=150):
        super().__init__(hero, name, damage, recharge_time, max_bullets, description='Очень тихий но слабый пистолет')

class AutomatBobby(Weapon):
    def __init__(self, hero, name='Автомат Бобби', damage=4, recharge_time=0.1, max_bullets=300):
        super().__init__(hero, name, damage, recharge_time, max_bullets)

class Dvoostvolka(Weapon):
    def __init__(self, hero, name='Двустволка', damage=5, distance=5, recharge_time=1, max_bullets=70):
        super().__init__(hero, name, damage, recharge_time, max_bullets)

    def shoot(self, x, y, bullets):
        if self.bullets > 0:
            if time.time() - self.last_shoot_time >= self.recharge_time:
                vector = [x - self.hero.x, y - self.hero.y]
                perp1 = normalize_victor([-vector[1], vector[0]], 5)
                perp2 = normalize_victor([vector[1], -vector[0]], 5)

                bullets.append(Bullet.spawn(self.hero.x + perp1[0], self.hero.y + perp1[1], vector, 7, damage=self.damage))
                bullets.append(Bullet.spawn(self.hero.x + perp2[0], self.hero.y + perp2[1], vector, 7, damage=self.damage))
                self.last_shoot_time = time.time()
                self.bullets -= 2

store = {
    'weapons': [
        {
            'weapon': TihiyPistolet(None),
            'price': 120
        },
        {
            'weapon': AutomatBobby(None),
            'price': 250
        },
        {
            'weapon': Dvoostvolka(None),
            'price': 200
        }
    ]
}


# Problem: Two strings of sizes m and n are given,
# we have to find how many characters need to be
# removed from both the string so that they become
# anagrams of each other

# Anagrams: Words that are made from rearranging the letters of another word

# Algorithm: We will use dictionaries to keep track of characters.
# The idea is to get the common occuring characters and derive
# uncommon characters

import string

# letters will be a string of the form "abc...xyz"
# CHARACTER_HASH looks like this {'a'0, 'b':0 ...., 'z':0}
letters = string.ascii_lowercase
CHARACTER_HASH = dict(zip(letters, [0] * len(letters)))

# This method will mark all the letters occuring in 'text_a'
def mapLettersToHash(text_a):
    for char in text_a:
        if char in CHARACTER_HASH.keys():
            CHARACTER_HASH[char] += 1

# This method will count the letters present in 'text_b', also found in 'text_a'
# These will be charcaters whose frequency in HASH is greater than zero
def computeCommonLetters(text_b):
    common_letters = 0
    for char in text_b:
        if CHARACTER_HASH[char] > 0:
            common_letters += 1
    return common_letters

# Now we derive how many uncommon letters are present,
# This is done by subtracting twice the count of common letters
# from the total length of both the strings
def computeUncommonLetters(text_a, text_b, common_letters):
    return abs(len(text_a) + len(text_b) - (2 * common_letters))

if __name__ == "__main__":
    text_1 = "hello"
    text_2 = "billion"

    mapLettersToHash(text_1)
    common = computeCommonLetters(text_2)
    result = computeUncommonLetters(text_1, text_2, common)
    print(result)