from sklearn.linear_model import LinearRegression
from sklearn.ensemble import RandomForestRegressor, GradientBoostingRegressor, RandomForestClassifier
from sklearn.neighbors import KNeighborsClassifier
from sklearn.naive_bayes import GaussianNB

import argparse
import pathlib
import pandas as pd
import numpy as np
import scipy

from util import nmse, percentage_difference

TIE = 'tie'
COMBINATION = 'combination'

class MetaStream():

    # TODO: add error message if the size of the initial meta-table has less instances than features
    def __init__(self, meta_learner, learners, base_window=100, base_delay_window=0, base_sel_window=10, meta_window=200, strategy=None, default=False, ensemble=False, threshold=None, pairs=False):

        self.meta_learner = meta_learner
        self.learners = learners

        self.base_window = base_window
        self.base_delay_window = base_delay_window
        self.base_sel_window = base_sel_window
        self.meta_window = meta_window
        self.strategy = strategy
        self.default = default
        if self.default:
            self.default_scores = []
            self.default_recommended = []

        self.ensemble = ensemble
        if self.ensemble: self.ensemble_scores = []
        self.threshold = threshold
        self.pairs = pairs
        if self.pairs:
            self.reg_1_scores = []
            self.reg_2_scores = []
        self.num_learners = len(self.learners)

        if self.strategy != COMBINATION and len(self.learners) > 2:
            raise ValueError("when using 'tie' strategy MetaStream must receive exactly 2 learners")
        elif self.strategy != None and self.strategy != TIE and self.strategy != COMBINATION:
            raise ValueError("strategy can only be 1 of 3 options (None, 'tie', 'combination')")
        elif self.strategy == TIE and self.threshold == None:
            raise ValueError("When using 'tie' strategy threshold must be provided")
        elif self.pairs == True and self.num_learners > 2:
            raise ValueError("full regressor report is only generated for pairs of regressors")

        self.meta_table = pd.DataFrame()

        self.recommended = []
        self.score_recommended = []
        self.actual = []

    def _meta_features(self, X_train, y_train, X_sel):

        temp = {}

        # train window
        for i, col in enumerate(X_train):
            X_train_percentiles = np.percentile(X_train[col], (25, 75))
            X_train_iqr = X_train_percentiles[1] - X_train_percentiles[0]

            temp.update({"X_train_mean_"+str(i): np.mean(X_train[col])})
            temp.update({"X_train_var_"+str(i): np.var(X_train[col])})
            temp.update({"X_train_min_"+str(i): np.min(X_train[col])})
            temp.update({"X_train_max_"+str(i): np.max(X_train[col])})
            temp.update({"X_train_median_"+str(i): np.median(X_train[col])})
            temp.update({"X_sel_dispersion_"+str(i): X_train_iqr})

        # train window
        y_train_percentiles = np.percentile(y_train, (25, 75))
        y_train_iqr = y_train_percentiles[1] - y_train_percentiles[0]
        y_train_lower_outliers = np.where(y_train < y_train_percentiles[0] - 1.5 * y_train_iqr)[0]
        y_train_upper_outliers = np.where(y_train > y_train_percentiles[1] + 1.5 * y_train_iqr)[0]
        y_train_prob_outliers = (len(y_train_lower_outliers) + len(y_train_upper_outliers)) / len(y_train)

        temp.update({"y_train_mean_"+str(i): np.mean(y_train)})
        temp.update({"y_train_var_"+str(i): np.var(y_train)})
        temp.update({"y_train_min_"+str(i): np.min(y_train)})
        temp.update({"y_train_max_"+str(i): np.max(y_train)})
        temp.update({"y_train_median_"+str(i): np.median(y_train)})
        temp.update({"y_train_prob_outliers_"+str(i): y_train_prob_outliers})
        temp.update({"y_train_dispersion_"+str(i): y_train_iqr})

        # selection window
        for i, col in enumerate(X_sel):
            X_sel_percentiles = np.percentile(X_sel[col], (25, 75))
            X_sel_iqr = X_sel_percentiles[1] - X_sel_percentiles[0]
            X_sel_lower_outliers = np.where(X_sel[col] < X_sel_percentiles[0] - 1.5 * X_sel_iqr)[0]
            X_sel_upper_outliers = np.where(X_sel[col] > X_sel_percentiles[1] + 1.5 * X_sel_iqr)[0]
            X_sel_prob_outliers = (len(X_sel_lower_outliers) + len(X_sel_upper_outliers)) / len(X_sel)

            temp.update({"X_sel_mean_"+str(i): np.mean(X_sel[col])})
            temp.update({"X_sel_var_"+str(i): np.var(X_sel[col])})
            temp.update({"X_sel_min_"+str(i): np.min(X_sel[col])})
            temp.update({"X_sel_max_"+str(i): np.max(X_sel[col])})
            temp.update({"X_sel_median_"+str(i): np.median(X_sel[col])})
            temp.update({"X_sel_prob_outliers_"+str(i): X_sel_prob_outliers})

        # selection window
        # correlation between numerical attributes
        for i, col_i in enumerate(X_sel):
            for j, col_j in enumerate(X_sel):
                if i != j:
                    temp.update({"X_sel_corr_"+str(i)+"_"+str(j) : np.correlate(X_sel[col_i], X_sel[col_j])})

        # train windown
        # correlation between numberical attributes and target
        for i, col in enumerate(X_train):
            temp.update({"X_train_corr_"+str(i) : np.correlate(X_train[col], y_train)})

        # skewness and kurtosis of numeric attrributes
        for i, col in enumerate(X_sel):
            temp.update({"X_sel_skew_"+str(i): scipy.stats.skew(X_sel[col])})
            temp.update({"X_sel_kurtosis_"+str(i): scipy.stats.kurtosis(X_sel[col])})

        return temp

    def _ensemble(self, X_train, y_train, X_sel, y_sel):
        scores = [learner.fit(X_train, y_train).predict(X_sel) for learner in self.learners]
        scores = np.array([sum(i)/len(self.learners) for i in zip(*scores)])
        score = nmse(list(y_sel), scores)
        return score

   # NOTE: initial base fit
    def base_train(self, data, target):
        """
        params:
        - data: pandas dataframe
        - target: string
        """
        for idx in range(self.meta_window):

            train = data.iloc[idx * self.base_sel_window : idx * self.base_sel_window + self.base_window]
            sel = data.iloc[self.base_delay_window + idx * self.base_sel_window + self.base_window : (idx + 1) * self.base_sel_window + self.base_window]
            # print(train.index)
            # print(sel.index)
            X_train, y_train = train.drop(target, axis=1), train[target]
            X_sel, y_sel = sel.drop(target, axis=1), sel[target]

            meta_features = self._meta_features(X_train, y_train, X_sel)
            self._base_fit(X_train, y_train)

            preds = self._base_predict(X_sel)
            scores = [nmse(pred, y_sel) for pred in preds]
            if self.strategy == None:
                meta_features.update({'regressor' : np.argmin(scores)})
            elif self.strategy == TIE:
                if percentage_difference(scores) <= self.threshold:
                    meta_features.update({'regressor' : self.num_learners})
                else:
                    meta_features.update({'regressor' : np.argmin(scores)})
            elif self.strategy == COMBINATION:
                pred_combination = np.array([sum(i)/len(self.learners) for i in zip(*preds)])
                scores.append(nmse(pred_combination, y_sel))
                meta_features.update({'regressor' : np.argmin(scores)})

            self.meta_table = self.meta_table.append(meta_features, ignore_index=True)

    # NOTE: base fit is performed on the base-learners
    def _base_fit(self, X, y):
        """
        fit the base-learners using training data
        """
        [learner.fit(X, y) for learner in self.learners]

    # NOTE: base predict is performed on the base-learners
    def _base_predict(self, X):
        """
        returns: a prediction for each of the base-learners
        """
        return [learner.predict(X) for learner in self.learners]

    # TODO: could probably optimize by only running each regressor once uniquely
    def meta_train(self, data, target):

        # initial meta-fit
        self._meta_fit(self.meta_table.drop(['regressor'], axis=1), self.meta_table['regressor'])

        max_data_size = int((data.shape[0] - self.base_window) / self.base_sel_window)

        for idx in range(self.meta_window, max_data_size):

            train = data.iloc[idx * self.base_sel_window : idx * self.base_sel_window + self.base_window]
            sel = data.iloc[self.base_delay_window + idx * self.base_sel_window + self.base_window : (idx + 1) * self.base_sel_window + self.base_window]

            X_train, y_train = train.drop(target, axis=1), train[target]
            X_sel, y_sel = sel.drop(target, axis=1), sel[target]

            meta_features = self._meta_features(X_train, y_train, X_sel)
            pred = int(self._meta_predict(np.array(list(meta_features.values()), dtype=object).reshape(1, -1)))
            self.recommended.append(pred)

            if self.strategy != None and pred == self.num_learners:
               self.score_recommended.append(self._ensemble(X_train, y_train, X_sel, y_sel))
            else:
                score = nmse(list(y_sel), self.learners[pred].fit(X_train, y_train).predict(X_sel))
                self.score_recommended.append(score)

            if self.pairs:
                scores = [learner.fit(X_train, y_train).predict(X_sel) for learner in self.learners]
                self.reg_1_scores.append(nmse(list(y_sel), scores[0]))
                self.reg_2_scores.append(nmse(list(y_sel), scores[1]))

            if self.default:
                default_learner = int(self.meta_table['regressor'].value_counts().idxmax())
                self.default_recommended.append(default_learner)
                if default_learner == self.num_learners and self.strategy != None:
                    self.default_scores.append(self._ensemble(X_train, y_train, X_sel, y_sel))
                else:
                    default_score = nmse(list(y_sel), self.learners[default_learner].fit(X_train, y_train).predict(X_sel))
                    self.default_scores.append(default_score)

            if self.ensemble:
                self.ensemble_scores.append(self._ensemble(X_train, y_train, X_sel, y_sel))

            self._base_fit(X_train, y_train)
            preds = self._base_predict(X_sel)
            scores = [nmse(pred, y_sel) for pred in preds]
            if self.strategy == None:
                regressor = np.argmin(scores)
                self.actual.append(np.argmin(regressor))
                meta_features.update({'regressor' : np.argmin(regressor)})

            elif self.strategy == 'tie':
                if percentage_difference(scores) > self.threshold:
                    regressor = np.argmin(scores)
                    self.actual.append(regressor)
                    meta_features.update({'regressor' : regressor})
                else:
                    self.actual.append(self.num_learners)
                    meta_features.update({'regressor' : self.num_learners})

            elif self.strategy == 'combination':
                pred_combination = np.array([sum(i)/len(self.learners) for i in zip(*preds)])
                scores.append(nmse(pred_combination, y_sel))
                regressor = np.argmin(scores)
                self.actual.append(regressor)
                meta_features.update({'regressor' : regressor})

            # sliding window for the meta-table
            self._meta_fit(self.meta_table.drop(['regressor'], axis=1)[-self.meta_window:], self.meta_table['regressor'][-self.meta_window:])

    # NOTE: meta fit is performed on the meta-learner
    def _meta_fit(self, X, y):
        """
        fit the meta-learner using training data
        """
        self.meta_learner.fit(X.values, y.values)

    # NOTE: meta predict is performed on the meta-learner
    def _meta_predict(self, X):
        """
        returns: a prediction for the meta-learner
        """
        return self.meta_learner.predict(X)

    def get_results(self):
        base_results = {}
        meta_results = {}

        base_results['recommended'] = np.mean(self.score_recommended)
        meta_results['recommended'] = 1 - len([i for i, j in zip(self.actual, self.recommended) if i == j]) / len(self.actual)

        if self.default:
            base_results['default'] = np.mean(self.default_scores)
            meta_results['default'] = 1 - len([i for i, j in zip(self.actual, self.default_recommended) if i == j]) / len(self.actual)

        if self.ensemble:
            base_results['ensemble'] = np.mean(self.ensemble_scores)

        if self.pairs:
            base_results['regressor 1'] = np.mean(self.reg_1_scores)
            base_results['regressor 2'] = np.mean(self.reg_2_scores)

        return base_results, meta_results

    def print_results(self):

        print("Mean score recommended {:.3f}+-{:.3f}".format(np.mean(self.score_recommended), np.std(self.score_recommended)))
        print("Meta-level score recommended {:.3f}".format(1 - len([i for i, j in zip(self.actual,self.recommended) if i == j]) / len(self.actual)))

        if self.default:
            print("Mean score default {:.3f}+-{:.3f}".format(np.mean(self.default_scores), np.std(self.default_scores)))
            print("Meta-level score default {:.3f}".format(1 - len([i for i, j in zip(self.actual, self.default_recommended) if i == j]) / len(self.actual)))

        if self.ensemble:
            print("Mean score ensemble {:.3f}+-{:.3f}".format(np.mean(self.ensemble_scores), np.std(self.ensemble_scores)))

        if self.pairs:
            print("Mean score regressor 1 {:.3f}".format(np.mean(self.reg_1_scores)))
            print("Mean score regressor 2 {:.3f}".format(np.mean(self.reg_2_scores)))

# TODO: need to remove this after experiimentation
if __name__ == "__main__":

    parser = argparse.ArgumentParser()
    parser.add_argument('datapath', type=pathlib.Path)

    parser.add_argument('-base_data_window', default=100, type=int)
    parser.add_argument('-base_delay_window', default=0, type=int)
    parser.add_argument('-base_sel_window', default=10, type=int)
    parser.add_argument('-meta_data_window', default=200, type=int)

    base_data_window = parser.parse_args().base_data_window
    base_delay_window = parser.parse_args().base_delay_window
    base_sel_window = parser.parse_args().base_sel_window
    meta_data_window = parser.parse_args().meta_data_window

    df = pd.read_csv(parser.parse_args().datapath)
    df = df[['period', 'nswprice', 'nswdemand', 'vicprice', 'vicdemand', 'transfer']]

    # NOTE: list of regression algorithms
    models =    [
                # SVR(),
                RandomForestRegressor(random_state=42),
                # LinearRegression(),
                # Lasso(),
                # Ridge(),
                GradientBoostingRegressor(random_state=42)
                ]

    # NOTE: meta-learner
    meta_learner = RandomForestClassifier()

    metas = MetaStream(meta_learner, models, base_data_window, base_delay_window, base_sel_window, meta_data_window, strategy='combination', default=True, ensemble=True, pairs=True, threshold=0.1)

    # creates baseline meta-data
    metas.base_train(data=df, target='nswdemand')

    metas.meta_train(data=df, target='nswdemand')

    metas.print_results()

    base, meta = metas.get_results()
    print(base)
    print(meta)


#!/usr/bin/python3
import random
import time

print("贴贴我的百花酱！数字打字练习\n")
print("程序会随机生成若干组指定位数的整数，每输入一组按回车键继续；要结束练习，请输入-1并回车。")
print("练习结束后会显示所用时间、完成数目和输入速度，并列出输入错误的数字。\n")
num_len = int(input("请输入要生成的随机数位数，练习会立即开始："))

wrongList = []
sum = 0
start_time = time.time()
while True:
    target = ""
    for i in range(num_len):
        target = target + str(random.randint(0,9))
    print(str(target)+": ", end='')
    answer = input()
    if answer == "-1":
        break
    sum += 1
    if target != answer:
        wrongNum = (target, answer)
        wrongList.append(wrongNum)
end_time = time.time()

print("\n错误列表：")
print("正确答案\t你的输入")
for wrongNum in wrongList:
    print(wrongNum[0] + "\t" + wrongNum[1])
used_time = end_time - start_time
print("\n练习" + str(sum) + "个，错误" + str(len(wrongList)) + "个，用时" + str(int(used_time)) + "秒，有效平均速度为每分钟" + str(format(float((sum-len(wrongList))/(used_time/60)), '.1f')) + "个。\n")

print("加油呀，爱你喔~\n")
input("按回车键退出……")


# file: ir_receiver.py
# date: 2020-05-08

from machine import Pin, Timer
import utime as time
from micropython import const

HEAD_INIT_MARK_MIN    = const(4000)
HEAD_INIT_SPACE_MIN   = const(4000)
HEAD_REPEAT_MARK_MIN  = const(HEAD_INIT_MARK_MIN)
HEAD_REPEAT_SPACE_MIN = const(HEAD_INIT_SPACE_MIN//2)
BIT_MARK_MIN   = const(400)
BIT_MARK_MAX   = const(700)
BIT0_SPACE_MIN = const(BIT_MARK_MIN)
BIT0_SPACE_MAX = const(BIT_MARK_MAX)
BIT1_SPACE_MIN = const(1500)
BIT1_SPACE_MAX = const(1800)

class IR_RECV():
    """This class implements an IR receiver/decoder for NEC protocol."""

    def __init__(self, pin, timer_id=-1,timeout=100):
        self._ts = 128*[0] # array for timestamp values (usec)
        self._saved_ts = 0
        self._index    = -1
        self._max_cnt  = 0
        self._timeout  = timeout
        self._pin = pin # IR input pin
        self._pin.init( mode=Pin.IN, pull=Pin.PULL_UP )
        trig_mode = (Pin.IRQ_FALLING | Pin.IRQ_RISING)
        self._pin.irq( trigger=trig_mode, handler=self._pin_cb )
        self._tim = Timer( timer_id ) # software timer
        self._codes = []

    def _decode(self):
        mark, space = self._ts[0], self._ts[1]
        if mark < HEAD_INIT_MARK_MIN:
            return
        if space > HEAD_INIT_SPACE_MIN:
            # found start sequence
            bits = []
            for i in range(2,self._max_cnt,2):
                mark, space = self._ts[i], self._ts[i+1]
                if BIT_MARK_MIN < mark < BIT_MARK_MAX:
                    if BIT0_SPACE_MIN < space < BIT0_SPACE_MAX:
                        bits.append('0')
                    elif BIT1_SPACE_MIN < space < BIT1_SPACE_MAX:
                        bits.append('1')
                else: # error
                    return
            bin_str = ''.join(bits)
            try:
                if len(bin_str) > 0:
                    # only 32-bit value
                    code = (int(bin_str,2)) & 0xffffffff
                    hex_str = hex(code)[2:]
                    self._codes.append( hex_str )
            except Exception as ex:
                pass
        elif space > HEAD_REPEAT_SPACE_MIN:
            if self._max_cnt == 3:
                self._codes.append( '0' ) # repeat code

    def _timer_cb(self, t):
        self._tim.init(callback=None)
        self._max_cnt = self._index
        self._index = -1
        if self._max_cnt > 1:
            self._decode() # decode bits

    def read(self):
        _codes = self._codes[:]
        self._codes = []
        return _codes

    def _pin_cb(self, p):
        # read current timestamp
        ts = time.ticks_us()
        if self._index == -1:
            # detected the first event (transition)
            # start timer in one-shot mode
            self._tim.init( period=self._timeout,
                            mode=Timer.ONE_SHOT,
                            callback=self._timer_cb )
        elif self._index < len(self._ts):
            t_width = time.ticks_diff(ts, self._saved_ts)
            self._ts[ self._index ] = t_width
        self._index += 1
        self._saved_ts = ts

    def deinit(self):
        self._pin.irq(handler=None)
        self._tim.deinit()


import sqlite3
from datetime import datetime

from aiogram import types
from aiogram.dispatcher import FSMContext
from aiogram.dispatcher.filters.builtin import CommandStart
from aiogram.utils.markdown import hcode
from data.config import admins
from data.content import greatings, capture_greatings
from loader import dp, db
from states import LockState
from utils.misc import rate_limit
from utils.capture import gen_capture

@rate_limit(3, 'start')
@dp.message_handler(CommandStart())
async def bot_start(message: types.Message):
    user_name = message.from_user.full_name
    for admin in admins:
        if admin == message.from_user.id:
            await message.answer('Bot started!')
        else:
            if message.from_user.id in db.select_users_id():
                await message.answer(f'{user_name}, ты уже в БД. Можешь теперь просто отправлять сообщения '
                                     f'не запуская бота.')
            else:
                capture_text, adding_text, result_text = gen_capture()
                text = capture_greatings.format(user_name=user_name)
                with open ('documents/capture_out.jpg', 'rb') as photo:
                    await message.reply_photo(photo, caption=text)
                db.delete_capture()
                try:
                    db.add_capture(result_text)
                except sqlite3.IntegrityError as err:
                    print(err)
                await message.answer(adding_text)
                await LockState.CapTure.set()

@dp.message_handler(state=LockState.CapTure)
async def get_capture(message: types.Message, state: FSMContext):
    user_name = message.from_user.full_name
    current_date_time = datetime.now()
    date_time = current_date_time.strftime("%d-%m-%Y %H:%M")
    insert_text = message.text.strip()
    cap_text = db.select_all_capture()

    if cap_text == insert_text:
        try:
            db.add_user(id=message.from_user.id, name=user_name, date_time=date_time)
        except sqlite3.IntegrityError as err:
            print(err)
        count = db.count_users()
        await message.answer(
            "\n".join(
                [
                    hcode(f'Привет, {user_name} и добро пожаловать!'),
                    hcode(f'Ты был занесен в базу данных.'),
                    f'Колличество абонентов в базе данных: <b>{count}</b>',
                    greatings
                ]))
    else:
        await message.answer(f'Ты ввел {insert_text}, это неверный ответ. Попробуй еще раз '
                             f'используя команду /start')
    await state.reset_state()


import json, requests, subprocess

def run():
    managerIP = input("Enter the IP of the manager: ")
    managerPort = input("Enter the port of the manager: ")
    numCommitsDone = 0

    r = requests.get("http://{}:{}/repo".format(managerIP,managerPort), json={'pullStatus': False})  # Don't have repo yet
    json_data = json.loads(r.text)
    repoUrl = json_data['repo']
    subprocess.call(["bash", "workerInitScript.sh", repoUrl])  # Call the initialisation script to pull repo

    r = requests.get("http://{}:{}/repo".format(managerIP,managerPort), json={'pullStatus': True})  # Have repo and are now ready

    stillHaveCommits = True
    while stillHaveCommits:
        r = requests.get("http://{}:{}/cyclomatic".format(managerIP,managerPort))  # get commit from manager
        json_data = json.loads(r.text)
        print(json_data)
        print("Received: {}".format(json_data['sha']))
        if json_data['sha'] == -2:  # Polling for manager to start giving commits
            # (manager is still setting up or waiting on workers)
           print("Polling")
        else:
            if json_data['sha'] == -1:
                print("No items left")
                break
            subprocess.call(["bash", "workerGetCommit.sh", json_data['sha']])
            # Call radon on the python repository and store its output
            binRadonCCOutput = subprocess.check_output(["radon", "cc", "-s", "-a" , "workerData"])
            radonCCOutput = binRadonCCOutput.decode("utf-8")  # Convert radon output from binary to string
            print(radonCCOutput)
            # Find last open bracket in radon output to find location of calculated average for repository
            avgCCstartPos = radonCCOutput.rfind("(")
            if radonCCOutput[avgCCstartPos+1:-2] == "":  # There are no files which radon can calculate C.C. for
                print("NO RELEVENT FILES")
                r = requests.post("http://{}:{}/cyclomatic".format(managerIP,managerPort),
                                  json={'commitSha': json_data['sha'], 'complexity': -1})
            else:
                averageCC = float(radonCCOutput[avgCCstartPos+1:-2])  # Get the average cyclomatic complexity from the output
                r = requests.post("http://{}:{}/cyclomatic".format(managerIP,managerPort),
                                  json={'commitSha': json_data['sha'], 'complexity': averageCC})
            numCommitsDone += 1  # Increment the number of commits this node has completed
    print("Completed having computed {} commits (including non-computable commits)".format(numCommitsDone))

if __name__ == "__main__":
    run()


from nfstream import NFStreamer, NFPlugin
import numpy as np
from scapy.all import IP, IPv6, rdpcap, raw

class NBytesPerPacket(NFPlugin):
    '''
        Extracts the first n_bytes from each packet in the flow, the bytes are taken
        from the transport layer payload (L4). if the flow have less than n_bytes bytes,
        then the rest of the bytes are zero-valued.

        remove_empty_payload flag tells the plugin to do not add empty payload packets such as acks in TCP.
        max_packets param determines the highest amount of packets to save/extract from flow.
    '''
    def __init__(self, n=1024, remove_empty_payload=True, max_packets=None):
        self.n = n
        self.remove_empty_payload = remove_empty_payload
        self.max_packets = max_packets

    def on_init(self, packet, flow):
        flow.udps.n_bytes_value = self.n
        flow.udps.n_bytes_per_packet = np.zeros((self.max_packets,self.n))
        flow.udps.n_bytes_curr_packets = 0

        self.on_update(packet, flow)

    def on_update(self, packet, flow):
        if packet.payload_size == 0 and self.remove_empty_payload == True:
            return

        if self.max_packets is not None and flow.udps.n_bytes_curr_packets == self.max_packets:
            return

        amount_to_copy = min(self.n, packet.payload_size)
        if amount_to_copy == 0:
            flow.udps.n_bytes_curr_packets += 1
            return

        max_index_to_copy = -packet.payload_size+amount_to_copy if -packet.payload_size+amount_to_copy != 0 else None
        flow.udps.n_bytes_per_packet[flow.udps.n_bytes_curr_packets,:amount_to_copy] = np.frombuffer(self.get_payload_as_binary(packet, flow.ip_version)[-packet.payload_size:max_index_to_copy], dtype=np.uint8)
        flow.udps.n_bytes_curr_packets += 1

    def on_expire(self, flow):
        flow.udps.n_bytes_per_packet /= 255
        flow.udps.n_bytes_per_packet = [list(i) for i in flow.udps.n_bytes_per_packet]
        #[int(i) for i in list(flow.udps.n_bytes_per_packet)]
        #flow.udps.n_bytes_per_packet = list(flow.udps.n_bytes_per_packet)

    def get_payload_as_binary(self, packet, ip_version):
        if ip_version == 4:
            scapy_packet = IP(packet.ip_packet)
        elif ip_version == 6:
            scapy_packet = IPv6(packet.ip_packet)

        return raw(scapy_packet.payload.payload)


import matplotlib
matplotlib.rcParams = matplotlib.rc_params_from_file('../../matplotlibrc')

import numpy as np
from matplotlib import pyplot as plt

def mc_circle():
    np.random.seed(42)
    points = np.random.rand(2, 500).T
    points = 4*(points-.5)
    pointsNorm = np.hypot(points[:,0],points[:,1]) <= 1
    InCircle = points[pointsNorm]
    OutCircle = points[~pointsNorm]
    plt.plot(InCircle[:,0], InCircle[:,1], 'r.')
    plt.plot(OutCircle[:,0], OutCircle[:,1], 'b.')

    # Plot the circle
    theta = np.linspace(0, 2*np.pi, 50)
    plt.plot(np.cos(theta),np.sin(theta),'k')

    plt.axes().set_aspect('equal')
    plt.axis([-2, 2, -2, 2])

    plt.savefig("MC_Circle.pdf")
    plt.clf()

if __name__ == "__main__":
    mc_circle()


__all__ = ["CsvImportWdg"]

import csv, os

from pyasm.web import Widget, DivWdg, Table, SpanWdg
from pyasm.search import Search, SearchType, SObjectFactory
from pyasm.biz import CsvParser
from pyasm.web import Widget, HtmlElement, WebContainer, AjaxCmd
from pyasm.widget import SelectWdg, SimpleUploadWdg, IconSubmitWdg, IconButtonWdg, IconWdg, HiddenWdg, TextWdg, HintWdg, CheckboxWdg, SiteMenuWdg, ProgressWdg, FilterCheckboxWdg, TextAreaWdg

from pyasm.command import FileUpload
from pyasm.prod.web import SearchTypeSelectWdg
from tactic.ui.common import BaseRefreshWdg

class CsvImportWdg(BaseRefreshWdg):

    def get_display(self):
        widget = Widget()
        widget.add( self.get_first_row_wdg() )
        widget.add(ProgressWdg())
        return widget

    def get_upload_wdg(self):
        widget = Widget()

        # get the search type
        widget.add( "1. Select type of asset: ")

        # handle new search_types
        new_search_type = CheckboxWdg("new_search_type_checkbox")
        new_search_type.add_event("onclick", "toggle_display('new_search_type_div')")
        #span = SpanWdg(css="med")
        #span.add(new_search_type)
        #span.add("Create new type")
        #span.add(" ... or ... ")
        #widget.add(span)

        new_search_type_div = DivWdg()
        new_search_type_div.set_id("new_search_type_div")

        name_input = TextWdg("asset_name")
        title = TextWdg("asset_title")
        description = TextAreaWdg("asset_description")

        table = Table()
        table.add_style("margin: 10px 20px")
        table.add_col().set_attr('width','140')
        table.add_col().set_attr('width','400')

        table.add_row()
        table.add_header("Search Type: ").set_attr('align','left')
        table.add_cell(name_input)
        table.add_row()
        table.add_header("Title: ").set_attr('align','left')
        table.add_cell(title)
        table.add_row()
        table.add_header("Description: ").set_attr('align','left')
        table.add_cell(description)
        new_search_type_div.add(table)
        new_search_type_div.add_style("display: none")
        #widget.add(new_search_type_div)

        # or use a pre-existing one
        search_type_select = SearchTypeSelectWdg("filter|search_type")
        search_type_select.add_empty_option("-- Select --")
        search_type_select.set_persist_on_submit()
        search_type_select.set_submit_onchange()
        widget.add(search_type_select)

        self.search_type = search_type_select.get_value()
        if self.search_type:
            sobj = SObjectFactory.create(self.search_type)
            required_columns = sobj.get_required_columns()

            widget.add(SpanWdg("Required Columns: ", css='med'))
            if not required_columns:
                required_columns = ['n/a']
            widget.add(SpanWdg(', '.join(required_columns), css='med'))

        widget.add( HtmlElement.br(2) )
        widget.add( "2. Upload a csv file: ")
        upload_wdg = HtmlElement.upload("uploaded_file")
        widget.add(upload_wdg)
        submit = IconSubmitWdg("Upload", IconWdg.UPLOAD, True)
        widget.add(submit)

        web = WebContainer.get_web()
        field_storage = web.get_form_value("uploaded_file")
        if field_storage != "":
            upload = FileUpload()
            upload.set_field_storage(field_storage)
            upload.set_create_icon(False)
            upload.execute()

            files = upload.get_files()
            if files:
                self.file_path = files[0]
            else:
                self.file_path = web.get_form_value("file_path")

        if self.file_path:
            hidden = HiddenWdg("file_path", self.file_path)
            widget.add(hidden)

        return widget

    def get_first_row_wdg(self):

        # read the csv file
        self.file_path = ""

        div = DivWdg()

        div.add( self.get_upload_wdg() )

        if not self.search_type:
            return div

        if not self.file_path:
            return div

        if not self.file_path.endswith(".csv"):
            div.add( "Uploaded file [%s] is not a csv file"% self.file_path)
            return div

        if not os.path.exists(self.file_path):
            raise Exception("Path '%s' does not exists" % self.file_path)

        div.add(HtmlElement.br(2))

        div.add( HtmlElement.b("The following is taken from first line in the uploaded csv file.  Select the appropriate column to match.") )
        div.add(HtmlElement.br())
        div.add(  HtmlElement.b("Make sure you have all the required columns** in the csv."))
        option_div = DivWdg()

        option_div.add_style("float: left")
        option_div.add_style("margin-right: 30px")

        option_div.add("
3. Parsing Options:
")

        self.search_type_obj = SearchType.get(self.search_type)

        # first row and second row
        option_div.add( HtmlElement.br(2) )
        option_div.add("Use Title Row: ")
        title_row_checkbox = FilterCheckboxWdg("has_title")
        title_row_checkbox.set_default_checked()
        option_div.add(title_row_checkbox)
        option_div.add( HintWdg("Set this to use the first row as a title row to match up columns in the database") )

        option_div.add( HtmlElement.br(2) )
        option_div.add("Sample Data Row: ")
        data_row_text = TextWdg("data_row")
        data_row_text.set_attr("size", "3")
        option_div.add(data_row_text)
        option_div.add( HintWdg("Set this as a sample data row to match the columns to the database") )

        option_div.add( HtmlElement.br(2) )

        div.add(option_div)
        self.has_title = title_row_checkbox.is_checked()

        # parse the first fow
        csv_parser = CsvParser(self.file_path)
        if self.has_title:
            csv_parser.set_has_title_row(True)
        else:
            csv_parser.set_has_title_row(False)
        csv_parser.parse()
        csv_titles = csv_parser.get_titles()
        csv_data = csv_parser.get_data()

        data_row = data_row_text.get_value()
        if not data_row:
            data_row = 0
        else:
            try:
                data_row = int(data_row)
            except ValueError:
                data_row = 0

            if data_row >= len(csv_data):
                data_row = len(csv_data)-1
        data_row_text.set_value(data_row)

        table = Table()
        table.set_attr("cellpadding", "10")

        table.add_row()
        table.add_header("CSV Column Value")
        table.add_header("TACTIC Column")
        table.add_header("Create New Column")

        columns = self.search_type_obj.get_columns()
        search_type = self.search_type_obj.get_base_search_type()
        sobj = SObjectFactory.create(search_type)
        required_columns = sobj.get_required_columns()

        row = csv_data[data_row]
        labels = []
        for column in columns:
            if column in required_columns:
                label = '%s**'%column
            else:
                label = column
            labels.append(label)

        for j, cell in enumerate(row):
            table.add_row()
            table.add_cell(cell)

            column_select = SelectWdg("column_%s" % j)
            column_select.add_event("onchange", "if (this.value!='') {set_display_off('new_column_div_%s')} else {set_display_on('new_column_div_%s')}" % (j,j))

            column_select.add_empty_option("-- Select --")
            column_select.set_option("values", columns)
            column_select.set_option("labels", labels)

            # only set the value if it is actually in there
            if csv_titles[j] in columns:
                column_select.set_option("default", csv_titles[j])
            column_select.set_persist_on_submit()
            column_select_value = column_select.get_value()

            display = column_select.get_buffer_display()
            td = table.add_cell( display )

            if csv_titles[j] not in columns:
                td.add(" *")

                # new property
                new_column_div = DivWdg()

                if column_select_value:
                    new_column_div.add_style("display", "none")
                else:
                    new_column_div.add_style("display", "block")

                new_column_div.set_id("new_column_div_%s" % j)

                td = table.add_cell( new_column_div )
                text = TextWdg("new_column_%s" % j)
                text.set_persist_on_submit()

                if self.has_title:
                    text.set_value(csv_titles[j])

                new_column_div.add( " ... or ..." )
                new_column_div.add( text )

        self.num_columns = len(row)
        hidden = HiddenWdg("num_columns", self.num_columns)

        # need to somehow specify defaults for columns

        div.add(table)

        div.add("

")

        div.add(self.get_preview_wdg())

        return div

    def get_preview_wdg(self):

        widget = Widget()

        web = WebContainer.get_web()

        csv_parser = CsvParser(self.file_path)
        csv_parser.parse()
        csv_titles = csv_parser.get_titles()
        csv_data = csv_parser.get_data()

        ajax = AjaxCmd()
        ajax.set_option("search_type", self.search_type)
        ajax.set_option("file_path", self.file_path)
        ajax.add_element_name("has_title")

        event = WebContainer.get_event_container()
        caller = event.get_event_caller(SiteMenuWdg.EVENT_ID)
        div = ajax.generate_div()
        div.set_post_ajax_script(caller)
        widget.add(div)

        columns = []
        num_columns = len(csv_titles)
        ajax.set_option("num_columns", num_columns)
        for i in range(0, num_columns):
            column = web.get_form_value("column_%s" % i)
            if column:
                column = csv_titles[i]
            else:
                column = web.get_form_value("column_new_%s" % i)

            columns.append(column)

            ajax.add_element_name("column_%s" % i)
            ajax.add_element_name("new_column_%s" % i)

        ajax.register_cmd("pyasm.command.csv_import_cmd.CsvImportCmd")
        import_button = IconButtonWdg("Import", IconWdg.REFRESH, True)
        import_button.add_event("onclick", ajax.get_on_script(show_progress=False))
        import_button.add_style("float: right")
        widget.add( import_button )

        preview_submit = IconSubmitWdg("Preview", IconWdg.REFRESH, True)
        preview_submit.add_style("float: right")
        widget.add(preview_submit)

        sobject_title = self.search_type_obj.get_title()
        widget.add("
4. Import
")
        widget.add(HtmlElement.br())
        widget.add("
The following table will be imported into %s (Showing Max: 100)
" % sobject_title)

        table = Table(css="table")
        table.add_style("width: 100%")

        table.add_row()
        for i, title in enumerate(columns):
            if not title:
                title = "*"
            table.add_header(title)

        for i, row in enumerate(csv_data):
            if i > 100:
                break
            table.add_row()
            for j, cell in enumerate(row):
                table.add_cell(cell)

        widget.add(table)

        return widget


# Author: Satyam Patel
# Date: 12:53 PM 6/02/2021
# Description: Implements the Kuba game.

class Player:
    """
    Holds all data for a player object.
    """
    def __init__(self, player_info):
        """
        initializes the name, color and captured marbles for the player
        """
        self._name = player_info[0]
        self._color = player_info[1]
        self._captured = []

    def get_name(self):
        """
        returns player name
        """
        return self._name

    def get_color(self):
        """
        returns marble color of player
        """
        return self._color

    def get_captured(self):
        """
        returns captured marbles of player
        """
        return self._captured

    def capture(self, marble):
        """
        captures marble
        """
        self._captured.append(marble)

    def get_captured_count(self, color):
        """
        returns the number of input color marbles captured
        """
        count = 0
        for marble in self._captured:
            if marble == color:
                count += 1
        return count

    def get_captured_counts(self):
        """
        returns a dict of the marble counts captured
        """
        counts = {"W":0, "B":0, "R":0}
        for marble in self.get_captured():
            if marble in counts:
                counts[marble] += 1
        return counts

class KubaGame:
    """
    Main class for the game.
    """

    def __init__(self, player_a_info, player_b_info):
        """
        Initializes the game board and also maps players to their color.
        Initializes current player turn as well
        Initializes game win state.
        Initializes the board history list.
        player_x_info needs to be passed in as a tuple: ("Name", "W") or ("Name", "B")
        """
        self._board = [['W','W','X','X','X','B','B'],
                       ['W','W','X','R','X','B','B'],
                       ['X','X','R','R','R','X','X'],
                       ['X','R','R','R','R','R','X'],
                       ['X','X','R','R','R','X','X'],
                       ['B','B','X','R','X','W','W'],
                       ['B','B','X','X','X','W','W']]

        self._board_history = []
        self._current_turn = None
        self._winner = None

        self._player_a = Player(player_a_info)
        self._player_b = Player(player_b_info)

        self._players = {self._player_a.get_name() : self._player_a,
                         self._player_b.get_name() : self._player_b}

        self._error_messages = []

    def get_board(self):
        """
        returns the board
        """
        return self._board

    def _set_board(self, board):
        """
        sets the board to the passed in one
        """
        self._board = board

    def get_board_history(self):
        """
        returns the board history
        """
        return self._board_history

    def get_current_turn(self):
        """
        returns the name of the player whose turn it is. Returns None if no player has started yet
        """
        if self._current_turn is not None:
            return self._current_turn.get_name()
        else:
            return None

    def _set_current_turn(self, player):
        """
        sets the current turn of the game
        """
        self._current_turn = player

    def get_player(self, playername):
        """
        returns player object from player name
        """
        return self._players[playername]

    def get_players(self):
        """
        returns the entire player dict
        """
        return self._players

    def get_player_a(self):
        """
        returns the player_a object
        """
        return self._player_a

    def get_player_b(self):
        """
        returns the player_b object
        """
        return self._player_b

    def get_winner(self):
        """
        Returns the name of the winner of the game.
        Returns None if no winner yet.
        """
        if self._winner is not None:
            return self._winner.get_name()
        return None

    def _set_winner(self, player):
        """
        sets the winner of the game
        """
        self._winner = player

    def get_captured(self, playername):
        """
        Returns the number of red marbles captured by this player.
        """

        return self.get_player(playername).get_captured_count("R")

    def get_marble(self, coordinates):
        """
        Returns the marble at this coordinate
        Returns X if no marble is present.
        """
        return self.get_board()[coordinates[0]][coordinates[1]]

    def get_marble_count(self):
        """
        returns the number of white, black, and red marbles in a tuple.
        (W,B,R)
        """
        counts = {"W":0, "B":0, "R":0}

        for row in self.get_board():
            for marble in row:
                if marble in counts:
                    counts[marble] += 1

        return (counts["W"], counts["B"], counts["R"])

    def print_board(self):
        """
        Prints out the board to the console.
        """
        print("      0  1  2  3  4  5  6")
        row_num = 0
        for row in self.get_board():
            print("   ", row_num, "", end="")
            row_num += 1
            for marble in row:
                char = marble
                if marble == "X":
                    char = "■"
                print(char, end="  ")
            print()

    def _document_error(self, message):
        """
        pushes message to the error stack
        """
        self._error_messages.append(message)

    def pop_error(self):
        """
        pops the last error message
        """
        return self._error_messages.pop()

    def _is_valid_push(self, coordinates, direction, player_marble):
        """
        checks if we can move in this direction at the given coordinates
        Note this function is called in a larger validation function: _move_is_valid()
        """
        # coordinates of interest
        right      = (coordinates[0], coordinates[1]+1) # immediately right
        left       = (coordinates[0], coordinates[1]-1) # immediately left
        above      = (coordinates[0]-1, coordinates[1]) # immediately above
        below      = (coordinates[0]+1, coordinates[1]) # immediately below
        leftmost   = (coordinates[0], 0) # the leftmost extreme of this row
        rightmost  = (coordinates[0], 6) # the rightmost extreme of row
        topmost    = (0, coordinates[1]) # the topmost extreme of column
        bottommost = (6, coordinates[1]) # the bottommost extreme of column

        def helper(coord_index, extreme_index, immediate, extreme):
            """
            helper that consolidates the checks into one function
            """
            row_or_col = []
            slice = []

            if coord_index == 0:
                row_or_col = self._get_column(coordinates[1])
            else:
                row_or_col = self._get_row(coordinates[0])

            if (extreme_index < coordinates[coord_index]):
                slice = row_or_col[coordinates[coord_index]:]
            else:
                slice = row_or_col[:coordinates[coord_index]]

            if player_marble == self.get_marble(extreme) and "X" not in slice:
                self._document_error("You cannot capture your own marble!")
                return False
            if coordinates[coord_index] == extreme_index:
                return True
            if self.get_marble(immediate) == "X":
                return True
            else:
                self._document_error("Cant push from this direction!")
                return False

        if direction == "L":
            return helper(1, 6, right, leftmost)

        if direction == "R":
            return helper(1, 0, left, rightmost)

        if direction == "B":
            return helper(0, 0, above, bottommost)

        if direction == "F":
            return helper(0, 6, below, topmost)

    def _move_is_valid(self, playername, coordinates, direction):
        """
        Validates move by checking:
        if game is already won,
        if it is the players turn or first move,
        if coordinates has current players marble color,
        if move can be made at all in given direction,
        """
        invalid_direction = direction not in "FBLR"
        if invalid_direction:
            self._document_error("Not a valid direction: F,B,L,R")
            return False

        invalid_player = playername not in self.get_players()
        if invalid_player:
            self._document_error("Player doesn't exist!")
            return False

        already_won = self.get_winner() != None
        if already_won:
            self._document_error("A player has already won: " + self.get_winner())
            return False

        coords_in_range = 0 <= coordinates[0] <= 6 and 0 <= coordinates[1] <= 6
        if not coords_in_range:
            self._document_error("Coordinates are not in range!")
            return False

        not_player_turn = False
        if self.get_current_turn() != None:
            not_player_turn = playername != self.get_current_turn()
        if not_player_turn:
            self._document_error("Not your turn. Current turn: " + self.get_current_turn())
            return False

        not_player_marble = self.get_marble(coordinates) != self.get_player(playername).get_color()
        if not_player_marble:
            self._document_error("Not your marble!")
            return False

        cant_push = not self._is_valid_push(coordinates, direction, self.get_player(playername).get_color())
        if cant_push:
            self._document_error("Cant push because: " + self.pop_error())
            return False

        return True

    def _check_win_conditions(self):
        """
        Checks to see if any of the players have 7 reds or 8 of the opponents marbles.
        """
        for playername, player in self.get_players().items():
            red_count   = player.get_captured_count("R")
            black_count = player.get_captured_count("B")
            white_count = player.get_captured_count("W")
            if red_count == 7:
                self._set_winner(player)
                return
            elif black_count == 8:
                self._set_winner(player)
                return
            elif white_count == 8:
                self._set_winner(player)
                return
            #elif not self._are_moves_available(player):
            #    player_a = self.get_player_a()
            #    player_b = self.get_player_b()
            #    if player_a.get_name() != playername:
            #        self._set_winner(player_a)
            #    else:
            #        self._set_winner(player_b)

    def _replace_column(self, column_index, column, board):
        """
        replaces the column in the board at column_index with the given column
        """
        row_num = 0
        for row in board:
            row[column_index] = column[row_num]
            row_num += 1

    def _replace_row(self, row_index, row, board):
        """
        replaces the row in the board at row_index with the given row
        """
        board[row_index] = list(row)

    def _get_row(self, row_index):
        """
        returns the row at row_index of the board
        """
        return list(self.get_board()[row_index])

    def _get_column(self, column_index):
        """
        returns the column at the column_index of the board
        """
        return [row[column_index] for row in self.get_board()]

    def _is_same_board(self, board_1, board_2):
        """
        returns true if board_1 matches board_2
        """
        for index in range(len(board_1)):
            if board_1[index] != board_2[index]:
                return False
        return True

    def _copy_board(self, board):
        """
        returns a copy of the input board
        """
        copy = []
        for row in board:
            copy.append(list(row))
        return copy

    def _push_right(self, position, a_list):
        """
        takes a list and pushes the element to the right. If there is something there, it pushes that element as well.
        If an element gets pushed out of the list we return that
        """
        for index in range(position, len(a_list)):
            if a_list[index] == "X":
                a_list.pop(index)
                a_list.insert(position,"X")
                return None
        a_list.insert(position, "X")
        return a_list.pop()

    def _set_next_turn(self, current_player):
        """
        Sets the next turn of the game
        """
        if current_player == self.get_player_a():
            self._set_current_turn(self.get_player_b())
        else:
            self._set_current_turn(self.get_player_a())

    def _are_moves_available(self, player):
        """
        returns true if there is at least one move available for this player
        """
        moves = "LRFB"
        name = player.get_name()
        player_marble = player.get_color()

        for row_index, row in enumerate(self.get_board()):
            for col_index, marble in enumerate(row):
                if marble == player_marble:
                    for move in moves:
                        if self._move_is_valid(name, (row_index, col_index), move):
                            return True
        return False

    def make_move(self, playername, coordinates, direction):
        """
        Win conditions are analyzed.
        Attempts to make a move for playername at coordinates in direction.
        If initial validation passes, we make the move on a copy of the current
        board and compare it to the board 1 move prior.
        If move is unique: the board, current turn, and captured marbles for current
        player are updated.
        Player turn is updated (no repeated turns for our implementation).
        """
        self._check_win_conditions()

        if (not self._move_is_valid(playername, coordinates, direction)):
            return False

        # make copy of board
        board_copy = self._copy_board(self.get_board())
        captured = None

        # make move on the copy
        if direction == "R":
            row_index = coordinates[0]
            row = self._get_row(row_index)
            captured = self._push_right(coordinates[1], row)
            self._replace_row(row_index, row, board_copy)

        elif direction == "B":
            column_index = coordinates[1]
            column = self._get_column(column_index)
            captured = self._push_right(coordinates[0], column)
            self._replace_column(column_index, column, board_copy)

        elif direction == "L":
            row_index = coordinates[0]
            row = self._get_row(row_index)
            row.reverse()
            captured = self._push_right(6 - coordinates[1], row)
            row.reverse()
            self._replace_row(row_index, row, board_copy)

        elif direction == "F":
            column_index = coordinates[1]
            column = self._get_column(column_index)
            column.reverse()
            captured = self._push_right(6 - coordinates[0], column)
            column.reverse()
            self._replace_column(column_index, column, board_copy)

        # check if the copy is the same as the last board
        history = self.get_board_history()
        if len(history) > 1:
            if self._is_same_board(history[-2], board_copy):
                self._document_error("Cannot make a circular move!")
                return False

        # set the board and capture marble!
        if captured is not None:
            self.get_player(playername).capture(captured)
        self._set_board(board_copy)
        history.append(board_copy)
        self._set_next_turn(self.get_player(playername))
        return True

# uncomment the lines below to play the game in the console!

def play_game():
    print("Welcome to the Kuba Game!")
    print("Enter q to quit during game loop.")
    print('All inputs need to be in the form "name row,col direction"')
    print('Valid directions are: R,L,F,B')
    print("Player 1 has black marbles and Player 2 has white marbles.")

    player_1 = input("Player 1 Name: ")
    player_2 = input("Player 2 Name: ")

    kg = KubaGame((player_1,'B'),(player_2, 'W'))
    kg.print_board()

    while(kg.get_winner() == None):
        # prompt user for moves
        user_input = input("name row,col direction: ")
        if user_input.lower() == "q":
            return
        inputs = user_input.split(' ')
        name = ""
        position = (0,0)
        direction = "F"
        try:
            name = inputs[0]
            position = eval(inputs[1])
            if len(position) != 2:
                print("invalid input!")
                continue
            direction = inputs[2]
        except:
            print("Input invalid!")
            continue

        if not kg.make_move(name, position, direction):
            print()
            kg.print_board()
            print()
            print(kg.get_player_a().get_name(), " has: ", kg.get_player_a().get_captured_counts())
            print(kg.get_player_b().get_name(), " has: ", kg.get_player_b().get_captured_counts())
            print()
            print(kg.pop_error())
        else:
            print()
            kg.print_board()
            print()
            print(kg.get_player_a().get_name(), " has: ", kg.get_player_a().get_captured_counts())
            print(kg.get_player_b().get_name(), " has: ", kg.get_player_b().get_captured_counts())
    print()
    print("WINNER: ", kg.get_winner())

if __name__ == "__main__":
    play_game()


from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.chrome.options import Options
from selenium.common.exceptions import TimeoutException, WebDriverException
from selenium.webdriver.common.keys import Keys
import json
import os
import time
import yaml

class WutongSearch():

    def __init__(self,config_file="config.yaml"):

        assert os.path.isfile(config_file),'%s is not a file' % config_file
        with open(config_file,'r',encoding='utf-8') as f:
            config = yaml.load(f)
        self.chrome_config = config['chrome_config']
        self.search_engine_config = config['search_engine_config']
        self.webdriver = self.init_driver(self.chrome_config)

    def init_driver(self, chrome_config):
        '''init the driver using config

        Arguments:
            chrome_config {dict} -- dict read from config.yaml: chrome_config

        Raises:
            e -- driver init exception

        Returns:
            webdriver -- the driver
        '''

        chrome_options = Options()
        if chrome_config['disable_window']:
            chrome_options.add_argument('--headless')
            chrome_options.add_argument('--disable-gpu')
            ########### dont load image ################
            image_prefs = {
                'profile.default_content_setting_values': {
                    'images': 2
                }
            }
            chrome_options.add_experimental_option('prefs', image_prefs)
        if chrome_config['disable_image']:
            ########### dont load image ################
            image_prefs = {
                'profile.default_content_setting_values': {
                    'images': 2
                }
            }
            chrome_options.add_experimental_option('prefs', image_prefs)

        if chrome_config['user_data_dir']:
            chrome_options.add_argument("user-data-dir=%s" % chrome_config['user_data_dir'])

        if chrome_config['proxy_server']:
            chrome_options.add_argument('--proxy-server=%s' % chrome_config['proxy_server'])

        chrome_options.add_argument('--ignore-ssl-errors')
        try:
            driver = webdriver.Chrome(
                executable_path=chrome_config['chrome_driver_path'], chrome_options=chrome_options)
        except Exception as e:
            raise e
        return driver

    def click_next_page(self, selector):
        '''click to get the next page

        Arguments:
            selector {a xpath string} -- xpath locator for next page element
        '''
        ############get the next page element##################
        element = self.webdriver.find_element_by_xpath(selector)
        webdriver.ActionChains(self.webdriver).move_to_element(
            element).perform()
        ############ click next page ##############
        element.click()

    def has_next_page(self,next_page_selector):
        '''check if there is more pages

        Arguments:
            next_page_selector {a xpath selector} -- xpath locator for next page

        Returns:
            bool -- whether there is more pages
        '''

        try:
            WebDriverWait(self.webdriver, self.chrome_config['next_page_wait']).until(
                EC.presence_of_element_located((By.XPATH, next_page_selector)))
        except TimeoutException as e:
            print("No more pages",e)
            return False
        return True

    def has_result(self,result_selector):
        '''check if there is result

        Arguments:
            result_selector {xpath string} -- xpath locator for result element

        Returns:
            bool -- whether there are results
        '''

        try:
            WebDriverWait(self.webdriver, self.chrome_config['result_wait']).until(
                EC.presence_of_element_located((By.XPATH, result_selector)))
        except TimeoutException as e:
            print("No more results",e)
            return False
        return True

    def save_page_result(self, result_loacator):
        '''extract urls from the result pages

        Arguments:
            result_loacator {xpath} --  xpath locator for result element

        Returns:
            list -- (url,title) list
        '''

        page1_results = self.webdriver.find_elements(By.XPATH, result_loacator)
        res = []
        for item in page1_results:
            url = item.get_attribute('href')
            if url not in res:
                res.append((url, item.text))
        return res

    def search(self, keyword, search_engine='baidu', num_pages_per_keyword=2):
        '''choose search engine to search the keyword

        Arguments:
            keyword {str} -- the word you want to search

        Keyword Arguments:
            search_engine {str} -- search engine name (default: {'baidu'})
            num_pages_per_keyword {int} -- how many pages you want to get (default: {2})

        Returns:
            list -- (url,title) list
        '''

        assert search_engine in self.search_engine_config.keys(), "only " + str(self.search_engine_config.keys()) + "supported!"
        engine_config = self.search_engine_config[search_engine]
        search_engine_url = engine_config['search_engine_url']
        input_selector = engine_config['input_selector']
        next_page_selector = engine_config['next_page_selector']
        result_selector = engine_config['result_selector']

        if engine_config['proxy_server'] != self.chrome_config['proxy_server']:
            self.webdriver.quit()
            self.chrome_config['proxy_server'] = engine_config['proxy_server']
            self.webdriver = self.init_driver(self.chrome_config)
        # open the search website
        self.webdriver.get(search_engine_url)
        # enter the keyword
        input_element = self.webdriver.find_element_by_xpath(input_selector)
        input_element.send_keys(keyword)
        input_element.submit()

        result = []
        # wait until the result loaded
        if not self.has_result(result_selector):
            return result
        # get the result
        if not engine_config['dynamic_load_result']:
            result += self.save_page_result(result_loacator=result_selector)
        # next page
        needed_pages = num_pages_per_keyword - 1
        while needed_pages > 0:
            ### to ensure the page loaded
            time.sleep(self.chrome_config['two_pages_internal'])
            if self.has_next_page(next_page_selector):
                self.click_next_page(next_page_selector)
                # wait until the result loaded
                if self.has_result(result_selector):
                    if not engine_config['dynamic_load_result']:
                        result += self.save_page_result(result_loacator=result_selector)
                needed_pages -= 1
            else:
                break
        if engine_config['dynamic_load_result']:
            result += self.save_page_result(result_loacator=result_selector)
        return result

def main():

    kws = ['小米', '华为', '苹果']

    save_path = "add_%s" % "sensitive"
    if not os.path.exists(save_path):
        os.makedirs(save_path)
    # assert search_engine in ['baidu','duckduckgo','bing']
    wsearch = WutongSearch()
    for kw in kws:
        if os.path.exists("%s/%s.txt" % (save_path, kw)):
            continue
        print(F"Start DownLoad============{kw}")
        try:
            res2 = wsearch.search(
                kw, search_engine='baidu', num_pages_per_keyword=2)
            print(len(res2))
            res3 = wsearch.search(
                kw, search_engine='google', num_pages_per_keyword=3)
            res = res3+res2
            r_dict = {}
            for r in res:
                if r[0] not in r_dict:
                    r_dict[r[0]] = r[1]
            print(F"total num========={len(res)}")
            with open("%s/%s.txt" % (save_path, kw), 'w') as f:
                json.dump(r_dict, f)
            # time.sleep(random.uniform(10, 20))
        except Exception as e:
            print(F"error======{kw} ", e)
            wsearch.webdriver.quit()
            wsearch.webdriver = wsearch.init_driver(
                "chromedriver/chromedriver.exe")
            continue

if __name__ == '__main__':
    main()


import paramiko_ssh as paramiko_ssh

connection = paramiko_ssh.ssh("131.123.39.73", "drobin", "ppa05060")
connection.openShell()
while True:
    command = input('$ ')
    if command.startswith(" "):
        command = command[1:]
    connection.sendShell(command)


import dash_bootstrap_components as dbc

from dash import dcc

bosun_form = dbc.Form(
    dbc.Row(
        [

            dbc.Col(
            dcc.Dropdown(['1h', '4h','8h', '12h','24h','48h','72h'], '8h', id='bosun_time')),

            dbc.Col(
                dbc.Input(
                    id='bosun-submit',
                    type="text",
                    placeholder="Customer ID"),
                    className="me-3",

            ),

            dbc.Col(dbc.Button("Submit", color="primary", id='bosun-search') ),
        ],
        className="g-2",
    )
)


from pathlib import Path
import sys
##change this variable if you need to save the satellite outputs in another folder
outdir='.'
home = str(Path.home())
goes_path='%s/goes16'%home
print('Goes files save dir', goes_path)
####
# check if the number of arguments is correct
n = len(sys.argv)
print("Total arguments passed:", n)
if n!=6:
    raise Exception('argument numbers must be 5 year month day hour minute')
# Arguments passed
print("Year", sys.argv[1])
print("Month", sys.argv[2])
print("Day", sys.argv[3])
print("Hour", sys.argv[4])
print("Minute", sys.argv[5])
year =int(sys.argv[1])
month=int(sys.argv[2])
day=int(sys.argv[3])
hour=int(sys.argv[4])
minute=int(sys.argv[5])
## import the required modules##
from netCDF4 import Dataset
from pyproj import Proj
import numpy as np
import datetime as dt
import glob
import json
import random
from tqdm import trange
import h5py
import os
from sklearn.neighbors import BallTree
import pickle
#### Aux funcs
## functions that will process the satellite data to prepare it for NN
def get_filename(ano,mes,dia,hora,minu,canal):
    data=dt.datetime(ano,mes,dia,hora,minu)
    path_1='%s/%04d/%02d/%02d/ABI-L2-CMIPF/%02d/C%02d/'%(goes_path,data.year,
                                                         data.month,
                                                         data.day,
                                                         data.hour,
                                                         canal)
    tt = data.timetuple()
    jd=tt.tm_yday
    try:
        path_2='OR_ABI-L2-CMIPF-M6C%02d_G16_s%04d%03d%02d%01d*'%(canal,data.year,jd,data.hour,data.minute)
        #print(path_1+path_2)
        res=glob.glob(path_1+path_2)[0]
        print('find' , res)
        return res
    except:
        path_2='OR_ABI-L2-CMIPF-M3C%02d_G16_s%04d%03d%02d%01d*'%(canal,data.year,jd,data.hour,data.minute)
        res=glob.glob(path_1+path_2)[0]
        print('find' , res)
        return res

def get_raio_name(ano,mes,dia,hora,minu,inter=1):
    d=dt.datetime(ano,mes,dia,hora,minu)
    tt = d.timetuple()
    jd=tt.tm_yday
    path1='%s/%04d/%02d/%02d/GLM-L2-LCFA/%02d/'%(goes_path,d.year,d.month,d.day,d.hour,)
    path2='OR_GLM-L2-LCFA_G16_s%04d%03d%02d%02d*'%(d.year,jd,d.hour,d.minute)
    #print(path1+path2)
    try:

        return glob.glob(path1+path2)
    except:
        return False

def creat_raio_array(date):
    valor=1.
    raio_array=np.zeros(lat.shape[0]*lat.shape[1])
    gr_lon,gr_lat=[],[]
    val=[]
    for tdelta in range(10):
        ddate=date+dt.timedelta(minutes=tdelta)
        raio_name=get_raio_name(ddate.year,ddate.month,ddate.day,ddate.hour,ddate.minute)
        #print(nc_raio.variable)
        if len(raio_name)>0:
            for file in raio_name:
                nc_raio=Dataset(file)
                gr_lo,gr_la=nc_raio['group_lon'][:],nc_raio['group_lat'][:]
                values=np.full(len(gr_lo),valor)
                valor=0.1+(tdelta/10.)
                for idx in range(len(values)):
                    gr_lon.append(gr_lo[idx])
                    gr_lat.append(gr_la[idx])
                    val.append(values[idx])
    gr_lon,gr_lat=np.array(gr_lon),np.array(gr_lat)
    val=np.array(val)
    aj=[]
    a=0
    e=0
    target_points=[]
    for hs in trange(len(gr_lon)):
        chosen_lon=gr_lon[hs]
        chosen_lat=gr_lat[hs]
        target_points.append([chosen_lat,chosen_lon])
        a=a+1
        #print(i,j)
    target_points=np.array(target_points)
    target_points=np.deg2rad(target_points)
    distances, indices = bt.query(target_points)
    for kinx in range(len(indices)):
        raio_array[indices[kinx]]=val[kinx]
    return np.reshape(raio_array,(lat.shape))
def sat_data_creat(ano,mes,dia,hora,minu,outdir):
    data=[]
    for i in range(8,17):
        f_satel=get_filename(ano,mes,dia,hora,minu,i)
        nc = Dataset(f_satel)
        R = nc.variables['CMI'][:]
        data.append(R[cutoff:-cutoff,cutoff:-cutoff])
    path='%s/GOES_16_%04d-%02d-%02d_%02d:%02d.hdf5'%(outdir,ano,mes,dia,hora,minu)
    data=np.array(data)
    raio=creat_raio_array(dt.datetime(ano,mes,dia,hora,minu))
    f=h5py.File(path, "w")
    f.create_dataset("lon", data=lon)
    f.create_dataset("lat", data=lat)
    f.create_dataset("data", data=data)
    f.create_dataset("GLM", data=raio)
    print('file creat complete ',path)
    print('ok',ano,mes,dia,hora,minu)

####load a file to extract lat lon and index these variables into the geospatial database (bt)
filename=get_filename(year,month,day,hour,0,13)
nc = Dataset(filename)
sat_h = nc.variables['goes_imager_projection'].perspective_point_height
# Satellite longitude
sat_lon = nc.variables['goes_imager_projection'].longitude_of_projection_origin
# Satellite sweep
sat_sweep = nc.variables['goes_imager_projection'].sweep_angle_axis
# the scanning angle (in radians) multiplied by the satellite height (http://proj4.org/projections/geos.html)
X = nc.variables['x'][:] * sat_h
Y = nc.variables['y'][:] * sat_h
R = nc.variables['CMI'][:]
XX, YY = np.meshgrid(X, Y)
p = Proj(proj='geos', h=sat_h, lon_0=sat_lon, sweep=sat_sweep)
lons, lats = p(XX, YY, inverse=True)
lats[np.isnan(R)] = np.nan
lons[np.isnan(R)] = np.nan
lats[np.isinf(lats)] = np.nan
lons[np.isinf(lons)] = np.nan
cutoff=800
lat=lats[cutoff:-cutoff,cutoff:-cutoff]
lon=lons[cutoff:-cutoff,cutoff:-cutoff]
bt = pickle.load(open('preload_files/sat_dataset.pik', 'rb'))
######
print('min-max domain allow lats',np.min(lat),np.max(lat))
print('min-max domain allow lons',np.min(lon),np.max(lon))
##
## future updates will improve converter performance
## the proper code wastes a lot of time loading static parameters
sat_data_creat(year,month,day,hour,minute,outdir)


from datetime import datetime
import calendar

class BudgetService(object):
    def query(self, start, end):
        if start > end:
            return 0

        begin_month = datetime.strftime(start, "%Y%m")
        end_month = datetime.strftime(end, "%Y%m")
        budgetsList = self.get_budgets()
        amount = 0

        for budget in budgetsList:
            budget_datetime = datetime.strptime(budget.yearMonth, "%Y%m")
            budget_day = calendar.monthrange(budget_datetime.year, budget_datetime.month)[1]

            if self.is_same_year_month(budget_datetime, start):
                if self.is_same_year_month(budget_datetime, end):
                    amount += round(budget.amount * (end.day - start.day + 1) / budget_day, 2)
                    return amount
                amount += round(budget.amount * (budget_day - start.day + 1) / budget_day, 2)

            if self.is_in_period(begin_month, budget, end_month):
                amount += budget.amount

            if self.is_same_year_month(budget_datetime, end):
                amount += round(budget.amount * end.day / budget_day, 2)

        return amount

    def is_in_period(self, begin_month, budget, end_month):
        month = budget.yearMonth > begin_month and budget.yearMonth < end_month
        return month

    def is_same_year_month(self, budget_datetime, year_month):
        month = budget_datetime.year == year_month.year and budget_datetime.month == year_month.month
        return month

    def get_budgets(self):
        pass

class Budget(object):

    def __init__(self, yearMonth, amount):
        self.yearMonth = yearMonth
        self.amount = amount


# exo 3.1
# Calculez la moyenne des nombres suivants : 1, 1, 2, 3, 5, 8, 13.
# Affectez le résultat à une variable et affichez le résultat.

# réponse 3.1
moyenne = (1 + 1 + 2 + 3 + 5 + 8 + 13) / 7
print(moyenne)
# exo 3.2
# On est en vacance et on veut suivre ses dépenses quotidiennes.
# Stockez le montant de chacune des dépenses quotidiennes dans une variable différente :
# - day1 : 26,82
# - day2 : 42,00
# - day3 : 31,41
# - day4 : 63,7
# - day5 : 32
# Stockez le nombre de jours dans une variable.
# Calculez le montant total des dépenses.
# Calculez la moyenne des dépenses quotidiennes en utilisant la variable contenant le nombre de jours et le total.
# Affichez le nombre jours, le montant total et la moyenne des dépenses.

# réponse 3.2

day1 = 26.82
day2 = 42.00
day3 = 31.41
day4 = 63.7
day5 = 32

depenses_Totale = day1 + day2 + day3 + day4 + day5

days_Number = 5

depenses_Moyenne = depenses_Totale / days_Number

print(f"Le montant total des dépenses est de {depenses_Totale} € en {days_Number} jours." )

print(f"La montant moyen des dépenses chaque jour est de {depenses_Moyenne} €")
# exo 3.3
# La formule suivante permet de convertir des mètres en miles :
# miles = meters / 1609.344
# Je dois marcher 2371 m pour aller jusqu'à la plus proche boulangerie.
# Combien cela fait-il en miles ?
# Affichez un résultat arrondi

# réponse 3.3

meters = 2371

miles = meters / 1609.344

step__Boulangerie = round(miles)

print(f"Je devrais marcher environ {step__Boulangerie} miles pour aller jusqu'à la boulangerie la plus proche.")


from django.core.management.base import BaseCommand, CommandError
from django.utils import timezone
import logging
from django.db.models import Q
from django.db.models import F

from apps.user.models import User
from apps.user.helpers import ROLE_DICT
from apps.notification.transmitters import unreachable_notification, ping_device
from apps.notification.config import NOTIFICATION_DICT as NTD
from apps.location.models import Location
from apps.location.config import EVENT_DICT
from apps.billing.config import PACKAGE_IDS

task_logger = logging.getLogger('task_logger')
MAX_PING = 3

def get_unreachables_bg(caller):
    qcommon_resource = Q(
        role__in=[ROLE_DICT['Manager'], ROLE_DICT['Employee']]
    ) & Q(
        is_awol=False
    ) & Q(
        is_present=True
    )
    online_resource = User.objects.filter(
        qcommon_resource
    ).select_related('org')
    task_logger.info('Starting unreachables loop......')
    this_time = timezone.datetime.now()
    task_logger.info('Unreachables timestamp: ' + str(this_time))
    for resource in online_resource:
        tracking_packs = [PACKAGE_IDS['Full Suite'], PACKAGE_IDS['Tracking']]
        package = resource.org.subscription.package
        if package not in tracking_packs:
            continue
        loc_qs = Location.objects.filter(agent=resource)
        resource_qs = User.objects.filter(id=resource.id)
        loc_interval = resource.org.location_interval
        ping_lim = timezone.timedelta(seconds=loc_interval * 3)
        if loc_qs.exists():
            location = loc_qs.order_by('-timestamp')[0]
            time_diff = timezone.now() - location.timestamp

            if time_diff > ping_lim:
                if resource.ping_count >= MAX_PING:
                    task_logger.info(resource.username + ' went OOC!')
                    # resource.is_awol = True
                    # resource.save()
                    resource_qs.update(is_awol=True)
                    location.event = EVENT_DICT['To OOC']
                    location.save()
                    task_logger.info('Sending notification')
                    unreachable_notification(resource)

                else:
                    ping_device(resource, NTD['Ping Device'])
                    resource_qs.update(
                        ping_count=F('ping_count') + 1
                    )
            else:
                pass

class Command(BaseCommand):
    help = 'Get unreachable agents'

    def handle(self, *args, **options):
        get_unreachables_bg(self)
        msg = 'Successfully Finished get unreachable....'
        task_logger.info(msg)
        self.stdout.write(self.style.SUCCESS(msg))


print("************** 1 ***************")
x = input(str("entrez une caractere: "))
if (len(x ) < 10):
    print("string not long enough")
else:
    print("string too long\n")

print("************** 2 ***************")
list = x
print("The first character is: ",x[0], "\n")
print("The last character is: ",x[-1], "\n")
print("************** 3 ***************")
a = ""
for i in list:
    a += i
    print(a)
print("************** 4 Bonus ***************")
from random import shuffle
# t = x
b = []
for j in x:
    b.append(j)
shuffle(b)
c = ""
for z in b:
    c = c + z
print(c)


#Мастям игральных карт присвоены порядковые номера: 1– пики, 2 – трефы, 3 –
#бубны, 4 – червы. Достоинству карт, старших десятки, присвоены номера: 11 – валет,
#12 – дама, 13 – король, 14 – туз. Дано трехзначное число, в котором первая цифра
#указывает на масть, а вторые две на достоинство карты. Вывести соответствующее
#название карты вида «дама червей», «туз треф» и т.п.
cards={'1':'пик','2':'треф','3':'бубен','4':'червей','11':'валет','12':'дама','13':'король','14':'туз'}
a=input()
b=list(a)
print("дама бубновая" if cards[b[1]+b[2]]=='дама' and cards[b[0]]=='бубен'
else cards[b[1]+b[2]],cards[b[0]])


import random
from collections import Counter
from copy import copy

import numpy as np
from scipy.ndimage import binary_dilation
from skimage import measure

from .mask import Mask
from ..point_cloud import PointCloud
from ..ref_space import get_ref

def sample_mask_cube(prior_array, radius=None, seg_array=None, ref=None,
                     num_vox=None):
    """n effect centers chosen and dilated to build mask of affected volume

    Args:
        prior_array (np.array): has same shape as image.  values are
                                unweighted prob of effect center.
                                note that prior array also masks effect (no
                                effect exists where prior_array <= 0)
        radius (int, tuple): if int, acts as effect radius: center is
                             dilated this many times.  if tuple, expected
                             as shape of effect
        seg_array (np.array): segmentation array, if passed constrains
                              effect to the region of its center. has
                              same shape as prior_array
        ref : reference space of output mask
        num_vox (int): if passed, will ensure mask has exactly total_vox
                         points

    Returns:
        eff_mask (np.array): array of 1s where effect is present
    """
    # check that inputs are consistent
    assert (radius is None) != (num_vox is None), \
        'radius xor num_vox required'

    # if num_vox passed, there are constraints on prior_array and seg_array
    if num_vox is not None:
        if seg_array is not None:
            # avoid memory intersection with prior_array passed
            prior_array = copy(prior_array)

            # selection must be in intersection of seg_array + prior_array
            prior_array[np.logical_not(seg_array)] = 0
            seg_array[np.logical_not(prior_array)] = 0

            # ensure each idx of seg_array is connected
            seg_array = measure.label(seg_array)

            # rm idx in seg_array which don't have at least num_vox voxels
            c = Counter(seg_array.flatten())
            idx_invalid = [idx for idx, count in c.items()
                           if count < num_vox]
            assert len(idx_invalid) < len(c), \
                f'seg_array doesnt have regions with {num_vox} voxels'
            for idx in idx_invalid:
                prior_array[seg_array == idx] = 0

        assert prior_array.astype(bool).sum() >= num_vox, \
            f'prior_array doesnt have {num_vox} valid voxels'

    # choose effect center via prior array
    p = np.array(prior_array / prior_array.sum())
    idx = np.random.choice(range(p.size), size=1, p=p.flatten())
    center_ijk = np.unravel_index(idx[0], prior_array.shape)

    # init mask
    mask = np.zeros(prior_array.shape)
    mask[center_ijk] = 1

    # meta_mask is a mask of the mask (contains all the possible voxels
    # that an effect mask could contain)
    meta_mask = prior_array.astype(bool)
    if seg_array is not None:
        meta_mask = np.logical_and(meta_mask,
                                   seg_array == seg_array[center_ijk])

    # perform dilation
    if radius is not None:
        if isinstance(radius, int):
            # dilate radius number of times
            mask = binary_dilation(mask, iterations=radius, mask=meta_mask)
        elif len(radius) == 3:
            # shape specified
            for delta in np.ndindex(radius):
                mask[tuple(center_ijk + delta)] = 1
            mask = np.logical_and(mask, meta_mask)
        else:
            raise AttributeError('invalid radius, must be int or tuple')
        return Mask(mask, ref=get_ref(ref))

    # dilate mask until it has > num_vox voxels
    assert num_vox > 1, 'num_vox must be > 1'
    while mask.sum() < num_vox:
        mask_last = mask
        mask = binary_dilation(mask, iterations=1, mask=meta_mask,
                               structure=np.ones((3, 3, 3)))

    # rm some of the voxels added in last dilation until mask has num_vox
    shell_mask = Mask(np.logical_and(mask, np.logical_not(mask_last)))
    shell_pc = PointCloud.from_mask(shell_mask)
    ijk_to_rm = random.sample(shell_pc, k=mask.sum() - num_vox)
    for ijk in ijk_to_rm:
        mask[ijk] = False

    assert mask.sum() == num_vox, 'mask doesnt have num_vox voxels'

    return Mask(mask, ref=get_ref(ref))


'''

 Copyright (c) 2020 Fractus IT d.o.o. <http://fractus.io>

'''
import keras
import numpy as np
from keras.applications import vgg16, resnet50, mobilenet, inception_v3
from keras.preprocessing.image import load_img
from keras.preprocessing.image import img_to_array
from keras.applications.imagenet_utils import decode_predictions
from keras.applications import imagenet_utils
from keras.applications.mobilenet import preprocess_input
from keras.applications.inception_v3 import preprocess_input
import argparse,textwrap

'''
script shows how to use pretrained Keras models in order to classify image
'''
def main():

    parser = argparse.ArgumentParser()

    parser = argparse.ArgumentParser(description='Please specify model.',
                                     usage='use "python %(prog)s --help" for more information',
                                     formatter_class=argparse.RawTextHelpFormatter)

    parser.add_argument('-m',
                        '--model',
                        required=True,
                        help= textwrap.dedent('''\
                        Possible MODELS:
                        vgg
                        inception
                        resnet
                        mobilenet
                        '''))

    args = vars(parser.parse_args())
    model_name = args["model"]

    if model_name == 'vgg':
        classify_image_with_vgg()
    elif model_name == 'inception':
        classify_image_with_inception()
    elif model_name == 'resnet':
        classify_with_resnet()
    elif model_name == 'mobilenet':
        classify_image_with_mobilenet()

def classify_image_with_vgg():

    model = vgg16.VGG16(weights="imagenet")
    print(model.summary())

    image = load_image()
    image = vgg16.preprocess_input(image)

    predictions = model.predict(image)
    print(decode_predictions(predictions))

def classify_image_with_inception():

    model = inception_v3.InceptionV3(weights='imagenet')
    print(model.summary())

    image = load_image()
    image = inception_v3.preprocess_input(image)

    predicts = model.predict(image)
    print(imagenet_utils.decode_predictions(predicts))

def classify_with_resnet():

    model = resnet50.ResNet50(weights='imagenet')
    print(model.summary())

    image = load_image()
    image = imagenet_utils.preprocess_input(image)

    predicts = model.predict(image)
    print(imagenet_utils.decode_predictions(predicts))

def classify_image_with_mobilenet():

    model = mobilenet.MobileNet(weights='imagenet')
    print(model.summary())

    image = load_image()
    image = mobilenet.preprocess_input(image)

    predicts = model.predict(image)
    print(imagenet_utils.decode_predictions(predicts))

def load_image():

    filename = 'cat.jpg'

    image = load_img(filename, target_size=(224, 224))
    image = img_to_array(image)
    image = np.expand_dims(image, axis=0)
    return image

if __name__ == '__main__':
    main()


import csv
# open the file in universal line ending mode
with open("G:/CodePracticing/pythonCode/DataResources/playerData(BaseBall).csv", 'rU') as infile:
    # read the file as a dictionary for each row ({header : value})
    reader = csv.DictReader(infile)
    data = {}
    for row in reader:
        for header, value in row.items():
            try:
                data[header].append(value)
            except KeyError:
                data[header] = [value]
# extract the variables you want
names = data['Name']
ages = data['Age']
ages = list(map(float,ages))
print(type(ages))

# print(names)
# print(ages)


'''
给你一个整数数组 nums 和一个正整数 threshold  ，
你需要选择一个正整数作为除数，然后将数组里每个数都除以它，并对除法结果求和。
请你找出能够使上述结果小于等于阈值 threshold 的除数中 最小 的那个。
每个数除以除数后都向上取整，比方说 7/3 = 3 ， 10/2 = 5 。
题目保证一定有解。

示例 1：
输入：nums = [1,2,5,9], threshold = 6
输出：5
解释：如果除数为 1 ，我们可以得到和为 17 （1+2+5+9）。
如果除数为 4 ，我们可以得到和为 7 (1+1+2+3) 。如果除数为 5 ，和为 5 (1+1+1+2)。
示例 2：
输入：nums = [2,3,5,7,11], threshold = 11
输出：3
示例 3：
输入：nums = [19], threshold = 5
输出：4

来源：力扣（LeetCode）
链接：https://leetcode-cn.com/problems/find-the-smallest-divisor-given-a-threshold
著作权归领扣网络所有。商业转载请联系官方授权，非商业转载请注明出处。
'''

import math
from typing import List

class Solution:#340ms,17.9MB

    def smallestDivisor(self, nums, threshold):
        # 找到数组内最大值
        right = nums[0]
        for i in nums:
            if i > right:
                right = i
        left = 1
        result=-1
        while (left <= right):
            mid = (left + right) >> 1
            total=0
            for i in nums:
                total+=math.ceil(i/mid)
            if total>threshold:
                left=mid+1
            else:
                result=mid
                right=mid-1
        return result

s=Solution()
print(s.smallestDivisor([19],5))

#简略版本
class Solution:#296ms,17.7mb
    def smallestDivisor(self, nums: List[int], threshold: int) -> int:
        left, right = 1, max(nums)
        ans = -1
        def res_sum(p, nums):
            return sum([math.ceil(i / p) for i in nums])
        while (left <= right):
            mid = left + (right - left >> 1)
            if res_sum(mid, nums) <= threshold:
                ans = mid
                right = mid - 1
            else:
                left = mid + 1
        return ans

二分搜索/python/1283使结果不超过阈值的最小除数.py

1283使结果不超过阈值的最小除数.py


# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.db import migrations, models
import ws.utils.dates
import django.core.validators

class Migration(migrations.Migration):

    dependencies = [
        ('ws', '0031_discount_student_and_school'),
    ]

    operations = [
        migrations.CreateModel(
            name='ClimbingLeaderApplication',
            fields=[
                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
                ('time_created', models.DateTimeField(auto_now_add=True)),
                ('previous_rating', models.CharField(help_text='Previous rating (if any)', max_length=255, blank=True)),
                ('year', models.PositiveIntegerField(default=ws.utils.dates.ws_year, help_text='Year this application pertains to.', validators=[django.core.validators.MinValueValidator(2014)])),
                ('desired_rating', models.CharField(max_length=20, choices=[('Bouldering', 'Bouldering'), ('Single-pitch', 'Single-pitch'), ('Multi-pitch', 'Multi-pitch'), ('Bouldering + Single-pitch', 'Bouldering + Single-pitch'), ('Bouldering + Multi-pitch', 'Bouldering + Multi-pitch')])),
                ('years_climbing', models.IntegerField()),
                ('years_climbing_outside', models.IntegerField()),
                ('outdoor_bouldering_level', models.TextField(help_text='At what level are you comfortable bouldering outside?')),
                ('outdoor_sport_leading_level', models.TextField(help_text='At what level are you comfortable leading outside on sport routes?')),
                ('outdoor_trad_leading_level', models.TextField(help_text='At what level are you comfortable leading outside on trad routes?')),
                ('familiarity_spotting', models.CharField(max_length=16, verbose_name='Familarity with spotting boulder problems', choices=[('none', 'not at all'), ('some', 'some exposure'), ('comfortable', 'comfortable'), ('very comfortable', 'very comfortable')])),
                ('familiarity_bolt_anchors', models.CharField(max_length=16, verbose_name="Familiarity with 2-bolt 'sport' anchors", choices=[('none', 'not at all'), ('some', 'some exposure'), ('comfortable', 'comfortable'), ('very comfortable', 'very comfortable')])),
                ('familiarity_gear_anchors', models.CharField(max_length=16, verbose_name="Familiarity with trad 'gear' anchors", choices=[('none', 'not at all'), ('some', 'some exposure'), ('comfortable', 'comfortable'), ('very comfortable', 'very comfortable')])),
                ('familiarity_sr', models.CharField(max_length=16, verbose_name='Familiarity with multi-pitch self-rescue', choices=[('none', 'not at all'), ('some', 'some exposure'), ('comfortable', 'comfortable'), ('very comfortable', 'very comfortable')])),
                ('spotting_description', models.TextField(help_text='Describe how you would spot a climber on a meandering tall bouldering problem.', blank=True)),
                ('tr_anchor_description', models.TextField(help_text='Describe how you would build a top-rope anchor at a sport crag.', verbose_name='Top rope anchor description', blank=True)),
                ('rappel_description', models.TextField(help_text='Describe how you would set up a safe rappel.', blank=True)),
                ('gear_anchor_description', models.TextField(help_text='Describe what you look for when building a typical gear anchor.', blank=True)),
                ('formal_training', models.TextField(blank=True)),
                ('teaching_experience', models.TextField(blank=True)),
                ('notable_climbs', models.TextField(help_text='What are some particularly memorable climbs you have done?', blank=True)),
                ('favorite_route', models.TextField(help_text='Do you have a favorite route? If so, what is it and why?', blank=True)),
                ('extra_info', models.TextField(help_text='Is there anything else you would like us to know?', blank=True)),
                ('participant', models.ForeignKey(to='ws.Participant')),
            ],
            options={
                'ordering': ['time_created'],
                'abstract': False,
            },
        ),
    ]


from urllib.request import urlopen
from bs4 import BeautifulSoup
from urllib.error import HTTPError
import re
import random
import datetime

def getHtml(url):
    try:
        html = urlopen(url)
    #     网页在伺服器上不存在
    except HTTPError as e:
        print(e)
        # return None
    #   伺服器不存在
    else:
        if html == None:
            print("there's no this server or the site")
            return None
    return html

def getTitle(url):

    try:
        html = getHtml(url)
        bsObj = BeautifulSoup(html.read())
        title = bsObj.body.h1
    except AttributeError as e:
        print(e)
    else:
        if title == None:
            print('there\'s no the tag of body.h1')
            return None
        return title

# 02 了解 findAll()
# html = getHtml("http://www.pythonscraping.com/pages/warandpeace.html")
# bsObj = BeautifulSoup(html)
# nameList = bsObj.findAll("span",{'class':'green'})
# for name in nameList:
#     # get_text() 会把所有标签都清除，只剩中间的text值
#     print(name.get_text())
#
# nameList02 = bsObj.findAll({'h1','h2','h3','h4','h5','h6'})
# nameList03 = bsObj.findAll('span',{'class':{'green','red'}})
# nameList04 = bsObj.findAll(text='prince')
# print(len(nameList04))

# 03子标签、后代标签、兄弟标签 tr:一横列、th:标题栏（tr内的一格）、td:项目栏（tr内的一格）
# html = getHtml('http://www.pythonscraping.com/pages/page3.html')
# bsObj = BeautifulSoup(html)
# vs BeautifulSoup(html.read())

# try:
#     for child in bsObj.find('table',{'id':'giftList'}).tr.children:
#         print(child.get_text())
#     #     get_text()去掉所有标签，仅留文字
# except AttributeError as e:
#     print(e)

# for sibling in bsObj.find('table',{'id':'giftList'}).tr.next_siblings:
#     print(sibling)

# for tr in bsObj.find('table',{'id':'giftList'}).tr:
#     print(tr)
# #     就只抓第一个tr标签而已
# 04wiki
#
# random.seed(datetime.datetime.now())
# def getLinks(wikiVoc):
#     try:
#         html = getHtml('http://en.wikipedia.org'+wikiVoc)
#         # https可直接改为http
#         bsObj = BeautifulSoup(html,'html.parser')
#         # print('gotten bsObj from'+wikiVoc+': '+datetime.datetime.now()) 文字里放变量要使用%
#         print('gotten bsObj from %s: %s'%(wikiVoc,datetime.datetime.now()))
#         return bsObj.findAll('a', href=re.compile("^(/wiki/)((?!:).)*$"))
#         # 正则表达的括号要放对
#     except:
#         print('something wrong happened')
#
# links = getLinks("/wiki/Mersenne_Twister")
# while len(links) > 0:
#     newVoc = links[random.randint(0, len(links)-1)].attrs['href']
#     print(newVoc)
#     links = getLinks(newVoc)

# 05 搜集站内所有链接，且不重复

pages = set()
def getArtPages(URL):
    html = getHtml('http://www.bnext.com.tw'+URL)
    bsObj = BeautifulSoup(html,'html.parser')
    for link in bsObj.findAll('a',href=re.compile('(/article/)(.)*$')):
        if 'href' in link.attrs:
            if link.attrs['href'] not in pages:
                fullURL = link.attrs['href']
                newURL = re.findall('https://www.bnext.com.tw/article(.)*',fullURL)
                print(newURL[0])
                pages.add(newURL[0])
                getArtPages('/article'+newURL[0])

getArtPages('')
# UnboundLocalError: local variable 'html' referenced before assignment
#


import re

patern = r">>([A-Za-z]+)<<(\d+\.?\d*)\!(\d+)" #? означава че може и да го има, може и да го няма
total_cost = 0
lst = []
while True:
    command = input()
    if command == "Purchase":
        break
#     result = re.findall(patern, command)
#     for i in result:
#         lst.append(i[0])
#         total_cost += float(i[1])*int(i[2])
# print("Bought furniture:")
# for i in lst:
#     print(f"{i}")
# print(f"Total money spend: {total_cost:.2f}")
# и горният код работи

    result = re.search(patern, command)
    if result:
        #хубаво е винаги да проверяваш дали има нач, защото при крив ход това не работи
        # furniture = match.group(1)
        # price = match.group(2)
        # quantity = match.group(3)
        furniture, price, quantity = result.groups()
        lst.append(furniture)
        total_cost += float(price)*int(quantity)
print("Bought furniture:")
#print('\n'.join())
for i in lst:
    print(f"{i}")
print(f"Total money spend: {total_cost:.2f}")

# >>Sofa<<312.23!3
# >>TV<<300!5
# >Invalid<<!5
# Purchase

18. Regular Expressions - Exercise/05. Furniture.py


#!/usr/bin/env python
# -*- coding: utf-8 -*-
from slugify import slugify
import pickle

vendor=input("Вендор: ") or "August"; vendor=str(vendor)
category=input("id Категории: ") or "155"; category=str(category)
type_product=input("Тип продукта: ") or "Визиточный картон"; type_product=str(type_product)

int_counter = open('counter_id.pkl', 'rb')
counter = pickle.load(int_counter)
int_counter.close()
counter=input("последнее id Продукта в BD: ") or counter; counter=int(counter)

provider = "avgust"

print(counter)

price_file = open('raw_product.csv', 'r')
product_file=open('sorted_product.csv', 'w')
data = price_file.readlines()
product_file.write('id,category,name,slug,provider,vendor_code,vendor,specifications,type_product,price,stock,available'+'\n')

# "Tintoretto ceylon ginepro";"синий";"легкая фактура";" ";72;101;"250 г/м2";"0.182 кг";"1.51 ";"картон";"со склада"

for i in data:
	i=str(i).split(';')
	id_product=str(counter)
	name=i[0]
	vendor_code=slugify(name+'-'+i[6])
	slug=vendor_code
	specifications ='"'+"Цвет: "+i[1][1:-1]+", "+"Фактура: "+i[2][1:-1]+'"'
	try:
		price=str(i[8][1:-2])
		price=(((float(price)*0.30)+float(price))*29.5)/9; price=format(price, '.2f'); price=str(price)
	except ValueError:
		price=str(i[8])
		price=(((float(price)*0.30)+float(price))*29.5)/9; price=format(price, '.2f'); price=str(price)
	available, stock = "1", "1"

	if len(i[1]) <= 390:
		product_file.writelines(id_product+','+category+','+name+','+slug+','+provider+','+vendor_code+','+vendor+','+specifications+','+type_product+','+price+','+stock+','+available+'\n')
		counter+=1

print(counter)

out_counter = open('counter_id.pkl', 'wb')
pickle.dump(counter, out_counter)
out_counter.close()


#9076

t = int(input())
li = []
for i in range(t):
    l=input().split(' ')
    for j in range(5):
        l[j] = int(l[j])
    l.sort()
    li.append(l)

for i in range(len(li)):
    sum = 0
    if li[i][3]-li[i][1]>=4:
        li[i] = 'KIN'
    else:
        for k in li[i]:
            sum+=k
        sum = sum-li[i][0]-li[i][4]
        li[i] = sum

for i in li:
    print(i)