data = open('data.txt').read()
rules, rest = data.split('\nyour ticket:\n')
my_ticket, other_tickets = rest.split('\n\nnearby tickets:\n')
parsed_rules = {}
for rule in rules.split('\n'):
    if not rule:
        continue
    key, values = rule.split(': ')
    pairs = []
    for pair in values.split(' or '):
        low, high = pair.split('-')
        pairs.append((int(low), int(high)))
        parsed_rules[key] = pairs

my_ticket = [
    [int(x) for x in ticket.split(',')]
    for ticket in my_ticket.split('\n') if ticket
][0]

other_tickets = [
    [int(x) for x in ticket.split(',')]
    for ticket in other_tickets.split('\n') if ticket
]

def invalids(rules, numbers):
    result = 0
    for number in numbers:
        valid = False
        for rule in rules:
            for (low, high) in rule:
                if low <= number <= high:
                    valid = True
        if not valid:
            result += number
    return result

def part1(rules, tickets):
    rules = list(rules.values())
    count = 0
    for ticket in tickets:
       count += invalids(rules, ticket)
    return count

def validate_number(rules, number):
    for low, high in rules:
        if (low <= number <= high):
            return True
    return False

def part2(rules, my_ticket, tickets):
    rule_list = list(rules.values())
    valid_tickets = []
    for ticket in tickets:
       if not invalids(rule_list, ticket):
           valid_tickets.append(ticket)

    possibilities = {
        key: set(range(len(my_ticket)))
        for key in rules.keys()
    }

    for key, ns in list(possibilities.items()):
        for n in list(ns):
            number_is_valid = True
            for t in valid_tickets:
                if not validate_number(rules[key], t[n]):
                    number_is_valid = False
                    break
            if not number_is_valid:
                possibilities[key].remove(n)

    actual = {}
    while len(possibilities) > 0:
        for k, v in list(possibilities.items()):
            if len(v) == 1:
                value =  v.pop()
                actual[k] = value
                del possibilities[k]
                for p_values in possibilities.values():
                    p_values.discard(value)

    result = 1
    for key, index in actual.items():
        if key.startswith('departure'):
            result *= my_ticket[index]
    return result

print(part1(parsed_rules, other_tickets))
print(part2(parsed_rules, my_ticket, other_tickets))


import pandas as pd
df = pd.read_csv('https://archive.ics.uci.edu/ml/machine-learning-databases/breast-cancer-wisconsin/wdbc.data', header=None)

# Assign Features and Label Output
from sklearn.preprocessing import LabelEncoder
X = df.loc[:, 2:].values
y = df.loc[:, 1].values
le = LabelEncoder()
y = le.fit_transform(y)

# Splitting Test and Train Data
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.20, random_state=1)

# Using Pipeline to Aggregate several steps
from sklearn.preprocessing import StandardScaler
from sklearn.decomposition import PCA
from sklearn.linear_model import LogisticRegression
from sklearn.pipeline import Pipeline
pipe_lr = Pipeline([('scl', StandardScaler()), ('pca', PCA(n_components=2)), ('clf', LogisticRegression(random_state=1))])
pipe_lr.fit(X_train, y_train)
print('Test Accuracy: %.3f' % pipe_lr.score(X_test, y_test))

# K-fold cross validation
import numpy as np
from sklearn.cross_validation import StratifiedKFold
kfold = StratifiedKFold(y=y_train, n_folds=10, random_state=1)
scores = []
for k, (train, test) in enumerate(kfold):
    pipe_lr.fit(X_train[train], y_train[train])
    score = pipe_lr.score(X_train[test], y_train[test])
    scores.append(score)
    print('Fold: %s, Class dist.: %s, Acc: %.3f' % (k+1, np.bincount(y_train[train]), score))

print('CV accuracy: %.3f +/- %.3f' % ( np.mean(scores), np.std(scores)))

# Using K-fold validation with pipeline
from sklearn.cross_validation import cross_val_score
scores = cross_val_score(estimator=pipe_lr, X=X_train, y=y_train, cv=10, n_jobs=1)
print('CV accuracy scores: %s' % scores)
print('CV accuracy: %.3f +/- %.3f' % (np.mean(scores), np.std(scores)))

# Plot Learning Curve
import matplotlib.pyplot as plt
from sklearn.learning_curve import learning_curve
pipe_lr = Pipeline(
    [
        ('scl', StandardScaler()),
        ('clf', LogisticRegression(penalty='l2', random_state=0))
    ]
)
train_sizes, train_scores, test_scores =\
        learning_curve(estimator=pipe_lr,
                       X=X_train,
                       y=y_train,
                       train_sizes=np.linspace(0.1, 1.0, 10),
                       cv=10,
                       n_jobs=1)
train_mean = np.mean(train_scores, axis=1)
train_std = np.std(train_scores, axis=1)
test_mean = np.mean(test_scores, axis=1)
test_std = np.std(test_scores, axis=1)
plt.plot(train_sizes, train_mean,
         color='blue', marker='o',
         markersize=5,
         label='training accuracy')
plt.fill_between(train_sizes,
                 train_mean + train_std,
                 train_mean - train_std,
                 alpha=0.15, color='blue')
plt.plot(train_sizes, test_mean,
         color='green', linestyle='--',
         marker='s', markersize=5,
         label='validation accuracy')
plt.fill_between(train_sizes,
                 test_mean + test_std,
                 test_mean - test_std,
                 alpha=0.15, color='green')
plt.grid()
plt.xlabel('Number of training samples')
plt.ylabel('Accuracy')
plt.legend(loc='lower right')
plt.ylim([0.8, 1.0])
plt.show()

# Plot Validation Curve
from sklearn.learning_curve import validation_curve
param_range = [0.001, 0.01, 0.1, 1.0, 10.0, 100.0]
train_scores, test_scores = validation_curve(
                estimator=pipe_lr,
                 X=X_train,
                 y=y_train,
                 param_name='clf__C',
                 param_range=param_range,
                 cv=10)
train_mean = np.mean(train_scores, axis=1)
train_std = np.std(train_scores, axis=1)
test_mean = np.mean(test_scores, axis=1)
test_std = np.std(test_scores, axis=1)
plt.plot(param_range, train_mean,
          color='blue', marker='o',
          markersize=5,
          label='training accuracy')
plt.fill_between(param_range, train_mean + train_std,
                  train_mean - train_std, alpha=0.15,
                  color='blue')
plt.plot(param_range, test_mean,
          color='green', linestyle='--',
          marker='s', markersize=5,
          label='validation accuracy')
plt.fill_between(param_range,
                  test_mean + test_std,
                  test_mean - test_std,
                  alpha=0.15, color='green')
plt.grid()
plt.xscale('log')
plt.legend(loc='lower right')
plt.xlabel('Parameter C')
plt.ylabel('Accuracy')
plt.ylim([0.8, 1.0])
plt.show()

# Using Grid Search to perform hyperparameter tuning
from sklearn.grid_search import GridSearchCV
from sklearn.svm import SVC
pipe_svc = Pipeline([('scl', StandardScaler()),
                      ('clf', SVC(random_state=1))])
param_range = [0.0001, 0.001, 0.01, 0.1, 1.0, 10.0, 100.0, 1000.0]
param_grid = [{'clf__C': param_range,
                'clf__kernel': ['linear']},
               {'clf__C': param_range,
                'clf__gamma': param_range,
                'clf__kernel': ['rbf']}]
gs = GridSearchCV(estimator=pipe_svc,
                   param_grid=param_grid,
                   scoring='accuracy',
                   cv=10,
                   n_jobs=-1)
gs = gs.fit(X_train, y_train)
print(gs.best_score_)
print(gs.best_params_)

clf = gs.best_estimator_
clf.fit(X_train, y_train)
print('Test accuracy: %.3f' % clf.score(X_test, y_test))

# Comparing different Classifier with grid search and nested k-fold cross validation
# SVM
gs = GridSearchCV(estimator=pipe_svc,
                   param_grid=param_grid,
                   scoring='accuracy',
                   cv=2,
                   n_jobs=-1) # to tune paramenter
scores = cross_val_score(gs, X_train, y_train, scoring='accuracy', cv=5) # Train with optimal params
print('CV accuracy: %.3f +/- %.3f' % (np.mean(scores), np.std(scores)))

# Decision Tree Classifier
from sklearn.tree import DecisionTreeClassifier
gs = GridSearchCV(
       estimator=DecisionTreeClassifier(random_state=0),
       param_grid=[
            {'max_depth': [1, 2, 3, 4, 5, 6, 7, None]}],
       scoring='accuracy',
       cv=5)
scores = cross_val_score(gs, X_train, y_train, scoring='accuracy', cv=2)
print('CV accuracy: %.3f +/- %.3f' % (np.mean(scores), np.std(scores)))

# Different Performance Metrics
# Confusion Matrix
from sklearn.metrics import confusion_matrix
pipe_svc.fit(X_train, y_train)
y_pred = pipe_svc.predict(X_test)
confmat = confusion_matrix(y_true=y_test, y_pred=y_pred)
print(confmat)

fig, ax = plt.subplots(figsize=(2.5, 2.5))
ax.matshow(confmat, cmap=plt.cm.Blues, alpha=0.3)
for i in range(confmat.shape[0]):
     for j in range(confmat.shape[1]):
         ax.text(x=j, y=i,
                 s=confmat[i, j],
                 va='center', ha='center')
plt.xlabel('predicted label')
plt.ylabel('true label')
plt.show()

# Precision, Recall, F1 Score
from sklearn.metrics import precision_score
from sklearn.metrics  import recall_score, f1_score
print('Precision: %.3f' % precision_score(y_true=y_test, y_pred=y_pred))
print('Recall: %.3f' % recall_score(y_true=y_test, y_pred=y_pred))
print('F1: %.3f' % f1_score(y_true=y_test, y_pred=y_pred))


import text2emotion as te
from sklearn.feature_extraction.text import TfidfVectorizer

# Define the song lyric

def analyze_lyric(lyric):
    # Tokenize the lyric
    tokens = lyric.split()
    # Vectorize the tokens using TF-IDF
    vectorizer = TfidfVectorizer()
    vectorizer.fit_transform(tokens)
    vectorized_lyric = vectorizer.transform([lyric]).toarray()
    # Use the text2emotion library to predict the emotions in the lyric
    emotions = te.get_emotion(lyric)
    # Print the predicted emotions and the vectorized lyric
    # give me the most common emotion
    return emotions


""" @author: Adam, @date: 8-7-2019

Brute force, just under 1 minute."""

import time

#%% Solution.

squares_dict = {}
for i in range(10):
    squares_dict[i] = i**2

def sum_digit_squares(n, squares_dict):
    """Return some of squares of digits of n."""
    s = 0
    for char in str(n):
        s += squares_dict[int(char)]
    return s

start_time = time.time()

# Memoize chains leading to 1 or 89.
chains1 = {1}
chains89 = {89}

limit = int(1e7)
count = 0
for n in range(1, limit):
    chain = set()
    while True:
        if n in chains1:
            chains1 = chains1 | chain
            break
        if n in chains89:
            count += 1
            chains89 = chains89 | chain
            break
        n = sum_digit_squares(n, squares_dict)
        chain.add(n)
print(count)

print(time.time() - start_time)

#%% Comments.
""" Potential improvements:
1)  Use number combinations to reduce the search space. e.g., 1234567 yields
    same result as 2134567 since their sum of digit squares is the same.
2)  Note that the maximum element in a chain after iteration is 7*(9^7).

    Extensions/Remarks:
"""


from __future__ import division, print_function

import apache_beam as beam

class SelectFromNestedDict(beam.DoFn):
    """A :class:`~apache_beam.DoFn` for selecting subsets of records formed of
    nested dictionaries.

    Args:
        keys (list): list of dictionary keys to be selected. Each key is a
            string formed of dot separated words, each is used for selecting
            from a dict in the nested dicts. The order of the word in the
            "dot.separated.string" correspond to the dict level to select from.
            For instance, if the input record is ``{'a': {'b': 3, 'c': {'d': 2} }}``
            and keys is ``['a.b', 'a.c.d']``, the transform output will
            ``{'a_b': 3, 'a_c_d': 2} or {'b': 3, 'd': 2}`` depending on
            ``deepest_key_as_name `` below.
        deepest_key_as_name (bool): if set to True, the deepest selected fields
            keys will be used as names for the output dict keys.

    Examples:
        Select from records formed of nested dicts. ::

            import apache_beam as beam
            from apache_beam.options.pipeline_options import PipelineOptions
            from beam_nuggets.transforms import SelectFromNestedDict

            inputs = [
                {
                    'name': {'first': 'Star', 'second': 'Light'},
                    'address': {'st': 'Jupiter', 'flat': 3},
                    'email': 's@l.no'
                },
                {
                    'name': {'first': 'Mark', 'second': 'Sight'},
                    'address': {'st': 'Loon', 'flat': 5},
                    'email': 'm@s.no'
                }
            ]
            with beam.Pipeline(options=PipelineOptions()) as p:
                nested = p | "Reading nested dicts" >> beam.Create(inputs)
                transformed = nested | "filtering" >> beam.ParDo(SelectFromNestedDict(
                    keys=['name.first', 'address.st', 'email'],
                    # deepest_key_as_name=True,
                ))
                transformed | 'Writing to stdout' >> beam.Map(print)

        The output will be something like:

            {'address_st': 'Jupiter', 'name_first': 'Star', 'email': 's@l.no'}
            {'address_st': 'Loon', 'name_first': 'Mark', 'email': 'm@s.no'}

    """

    def __init__(self, keys, deepest_key_as_name=False, *args, **kwargs):
        super(SelectFromNestedDict, self).__init__(*args, **kwargs)
        self._compiled_keys = self._compile_keys(keys, deepest_key_as_name)

    def process(self, element):
        """
        Args:
            element(dict):
        """

        yield {
            out_key: self._retrieve(nested_keys, element)
            for nested_keys, out_key in self._compiled_keys
        }

    @staticmethod
    def _retrieve(nested_keys, element):
        for key in nested_keys:
            element = element[key]
        return element

    @staticmethod
    def _compile_keys(keys, deepest_key_as_name):
        def _get_out_dict_key(nested_keys):
            if deepest_key_as_name:
                return nested_keys[-1]
            else:
                return '_'.join(nested_keys)

        return [
            (
                nested_keys,  # ['a', 'b'] used for retrieving nested values
                _get_out_dict_key(nested_keys),  # 'a_b' or 'b'
            )
            for nested_keys in [key.split('.') for key in keys]  # ['a.b']
        ]


# header is ("4solr field", "darwin core field")
dwc_mapping = [
    ("accessionnumber_s", "catalogNumber"),
    ("alllocalities_ss", "tbd"),
    ("associatedtaxa_ss", "associatedTaxa"),
    ("blob_ss", "associatedMedia"),
    ("briefdescription_txt", "dynamicProperties"),
    ("collcountry_s", "country"),
    ("collcounty_s", "county"),
    ("collectioncode", "collectionCode"),
    ("collectiondate_s", "verbatimEventDate"),
    ("collector_ss", "recordedBy"),
    ("collectornumber_s", "recordNumber"),
    ("collectorverbatim_s", "tbd"),
    ("collstate_s", "stateProvince"),
    ("comments_ss", "occurrenceRemarks"),
    ("coordinatesource_s", "georeferenceSources"),
    ("coordinateuncertainty_f", "coordinateUncertaintyInMeters"),
    #("coordinateuncertaintyunit_s", "coordinateUncertaintyInMeters"),
    ("createdat_dt", "tbd"),
    ("csid_s", "occurrenceID"),
    ("cultivated_s", "establishmentMeans"),
    ("datum_s", "geodeticDatum"),
    ("depth_s", "verbatimDepth"),
    #("depthunit_s", "verbatimDepthUnit"),
    ("determination_s", "scientificName"),
    ("determinationdetails_s", "identificationRemarks"),
    ("determinationqualifier_s", "identificationQualifier"),
    ("earlycollectiondate_dt", "eventDate"),
    ("elevation_s", "verbatimElevation"),
    #("elevationunit_s", "verbatimElevationUnit"),
    ("family_s", "family"),
    ("habitat_s", "habitat"),
    ("hastypeassertions_s", "tbd"),
    ("id", "tbd"),
    ("labelfooter_s", "tbd"),
    ("labelheader_s", "tbd"),
    ("latecollectiondate_dt", "eventDate"),
    ("latlong_p", "tbd"),
    ("loannumber_s", "tbd"),
    ("loanstatus_s", "tbd"),
    ("locality_s", "verbatimLocality"),
    ("localitynote_s", "localityRemarks"),
    ("localitysource_s", "tbd"),
    ("localitysourcedetail_s", "georeferenceRemarks"),
    ("localname_s", "vernacularName"),
    ("location_0_coordinate", "decimalLatitude"),
    ("location_1_coordinate", "decimalLongitude"),
    ("majorgroup_s", "tbd"),
    ("maxdepth_s", "tbd"),
    ("maxelevation_s", "tbd"),
    ("mindepth_s", "tbd"),
    ("minelevation_s", "tbd"),
    ("numberofobjects_s", "tbd"),
    ("objectcount_s", "tbd"),
    ("otherlocalities_ss", "tbd"),
    ("othernumber_ss", "otherCatalogNumbers"),
    ("phase_s", "reproductiveCondition"),
    ("posttopublic_s", "tbd"),
    ("previousdeterminations_ss", "previousIdentifications"),
    ("references_ss", "tbd"),
    ("sex_s", "sex"),
    ("sheet_s", "tbd"),
    ("taxonbasionym_s", "originalNameUsage"),
    ("termformatteddisplayname_s", "tbd"),
    ("trscoordinates_s", "tbd"),
    ("typeassertions_ss", "typeStatus"),
    ("ucbgaccessionnumber_s", "tbd"),
    ("updatedat_dt", "modified")
]

id_column = 0
csid_column = 1
accessionnumber_column = 2
determination_column = 3
termformatteddisplayname_column = 4
family_column = 5
taxonbasionym_column = 6
majorgroup_column = 7
collector_column = 8
collectornumber_column = 9
collectiondate_column = 10
earlycollectiondate_column = 11
latecollectiondate_column = 12
locality_column = 13
collcounty_column = 14
collstate_column = 15
collcountry_column = 16
elevation_column = 17
minelevation_column = 18
maxelevation_column = 19
elevationunit_column = 20
habitat_column = 21
location_0_coordinate_column = 22
location_1_coordinate_column = 23
latlong_column = 24
trscoordinates_column = 25
datum_column = 26
coordinatesource_column = 27
coordinateuncertainty_column = 28
coordinateuncertaintyunit_column = 29
localitynote_column = 30
localitysource_column = 31
localitysourcedetail_column = 32
updatedat_dt_column = 33
labelheader_column = 34
labelfooter_column = 35
previousdeterminations_column = 36
localname_column = 37
briefdescription_txt_column = 38
depth_column = 39
mindepth_column = 40
maxdepth_column = 41
depthunit_column = 42
associatedtaxa_column = 43
typeassertions_column = 44
cultivated_column = 45
sex_column = 46
phase_column = 47
othernumber_column = 48
ucbgaccessionnumber_column = 49
determinationdetails_column = 50
loanstatus_column = 51
loannumber_column = 52
collectorverbatim_column = 53
otherlocalities_column = 54
alllocalities_column = 55
hastypeassertions_column = 56
determinationqualifier_column = 57
comments_column = 58
numberofobjects_column = 59
objectcount_column = 60
sheet_column = 61
createdat_dt_column = 62
posttopublic_column = 63
references_column = 64
blob_column = 65


from enum import Enum
import boto3
import HTPredBenchCreator

class CELL(Enum):
    TSMC = 'tsmc_cells/'
    SYNOPSIS = 'synopsis_cells/'

def run(event, context):
    s3 = boto3.client('s3')
    file_name = "/tmp/afile"
    s3.download_file('htpred-bucket', event['s3key'], file_name)

    cell = CELL.TSMC.value if event['cell'] == 'tsmc' else CELL.SYNOPSIS.value

    outpf = '/tmp/file'

    if event['function'] == 'benchcreator':
        r = HTPredBenchCreator.Creator(file_name, cell, event['main_module'])
        s = open(outpf, 'w')
        s.write(r.convert())
        s.close()

    if event['function'] == 'featureextractor':
        r = HTPredBenchCreator.FeatureExtractor(file_name, cell, event['main_module'])
        r.getfeatures(outpf, ['preferences/mux_list.txt'])

    s3.upload_file(outpf, 'htpred-bucket', event['s3outputkey'])

    return {"STATUS":"SUCCESS"}


import os
import sys
import numpy as np
from collections import defaultdict
from enum import Enum, unique
head_path = os.path.dirname(os.path.dirname(
    os.path.dirname(os.path.abspath(__file__))))
# print(head_path)
sys.path.append(os.path.dirname(os.path.dirname(
    os.path.dirname(os.path.abspath(__file__)))))

import config
# PreVectorFormat = Enum('PreVectorFormat', 'last_coin bonus_coin win_free ')
# a = PreVectorFormat.last_coin.value
# print(a)
# @unique
# class VectorFormat(Enum):
#   Win_Bonus,
# 格式： last_coin bonus_coin total_time odds(seq_len)

def calc_len_times(seq_len, max_len):
    """
    计算转盘平均时长，区分pay和nopay
    """
    base_dir = os.path.join(config.log_base_dir, "result")
    # base_dir = r"E:\codes\GitHubs\slot\result"
    dir_list = os.listdir(base_dir)
    uid_count = [0, 0]
    total_time = [0, 0]
    for cr_uid in dir_list:
        user_dir = os.path.join(base_dir, cr_uid)
        if not os.path.isdir(user_dir):
            continue

        cr_time = _do_calc_len_times(user_dir, seq_len, max_len)
        if len(cr_time) < 2:
            continue
        for payed in range(2):
            if cr_time[payed] > 0:
                total_time[payed] += cr_time[payed]  # 没付费
                uid_count[payed] += 1  # 付费

    mean_time = [-1, -1]
    for payed in range(2):
        if total_time[payed] > 0:
            mean_time[payed] = total_time[payed] / uid_count[payed]
    return mean_time

def _do_calc_len_times(file_dir, seq_len, max_len):
    """
    一个玩家转盘的平均时长，分pay和no pay
    max_len : 原始文件的最大序列长度，目前是10
    """
    # 充值记录
    pay_file = os.path.join(file_dir, "pay_odds.txt")
    # if (not os.path.exists(pay_file)):
    #     return []
    mean_time = [0, 0]
    count = [0, 0]
    for payed in range(2):
        pre_fix = ""
        if payed:
            pre_fix = 'pay_'

        file_time = os.path.join(file_dir, pre_fix + "time_delta.txt")
        if (not os.path.exists(file_time)):
            mean_time[payed] = -1
            continue

        f_time = open(file_time, 'r')
        while True:
            line = f_time.readline().strip()
            line = line.split(" ")
            if len(line) < seq_len:
                break
            line = list(map(float, line[1::]))
            mean_time[payed] += np.mean(line)
            count[payed] += 1
        f_time.close()

    for payed in range(2):
        if mean_time[payed] > 0:
            mean_time[payed] = mean_time[payed] / count[payed]

    # return [data, lable]
    return mean_time

from scipy import stats

def process_data(data):
    desc_no_pay = stats.describe(data)

    stat_info = np.zeros(6, dtype=float)

    stat_info[0] = desc_no_pay.mean
    stat_info[1] = np.sqrt(desc_no_pay.variance)  # 量纲平方
    # stat_info[2] = desc_no_pay.skewness * desc_no_pay.mean  # 无量纲
    # stat_info[3] = desc_no_pay.kurtosis * desc_no_pay.mean # 无量纲
    stat_info[2] = desc_no_pay.skewness  # 无量纲
    stat_info[3] = desc_no_pay.kurtosis  # 无量纲
    stat_info[4] = desc_no_pay.minmax[0]
    stat_info[5] = desc_no_pay.minmax[1]

    # stat_info.append(desc_no_pay.mean )
    # stat_info.append(desc_no_pay.variance ) # 量纲平方
    # stat_info.append(desc_no_pay.skewness )  # 无量纲
    # stat_info.append(desc_no_pay.kurtosis ) # 无量纲
    # stat_info.append(desc_no_pay.minmax[0] )
    # stat_info.append(desc_no_pay.minmax[1] )

    return stat_info

def get_one_user_odds(file_dir, odds_count_dict, total_count, max_count):
    for payed in range(2):
        pre_fix = ""
        if payed == 0:
            pre_fix = 'pay_'
        file_odds = os.path.join(file_dir, pre_fix + "odds.txt")
        file_line = os.path.join(file_dir, pre_fix + "line.txt")
        file_machine_id = os.path.join(file_dir, pre_fix + "machine_id.txt")
        if (not os.path.exists(file_odds)) or (not os.path.exists(file_machine_id)) or (not os.path.exists(file_line)):
            continue
        f_odds = open(file_odds, 'r')
        f_line = open(file_line, 'r')
        f_machine_id = open(file_machine_id, 'r')
        while True:
            odds_line = f_odds.readline().strip()
            line_line = f_line.readline().strip()
            machine_id_line = f_machine_id.readline().strip()
            if not odds_line:
                break
            # cr_data = np.zeros(3 + seq_len)
            odds_line = odds_line.split(" ")
            line_line = line_line.split(" ")
            machine_id_line = machine_id_line.split(" ")
            # if len(line) < 2:
            #     break
            if odds_line[-1] == "-1":  # 被抛掉的数据
                continue
            # print(line)
            for i in range(len(odds_line)):
                cr_odd= round(float(odds_line[i]),1)
                cr_line = float(line_line[i])
                cr_machine_id = float(machine_id_line[i])

                odds_count_dict[payed][cr_machine_id][cr_line][cr_odd] += 1
                # odds_count_dict[payed][cr_machine_id][cr_odd] += 1
                total_count+= 1
                if(total_count > max_count):
                    return 1
    return 0

def get_odds_vector(max_count=100000):
    base_dir = os.path.join(config.log_result_dir, "slot")
    # base_dir = r"E:\codes\GitHubs\slot\result"
    total_count = 0
    # odds_count_dict = [defaultdict(int), defaultdict(int)]  # 充值的，没充值的，分别是odds->count
    odds_count_dict = [defaultdict(lambda: defaultdict(lambda: defaultdict(float))), defaultdict(lambda: defaultdict(lambda: defaultdict(float)))]
    dir_list = os.listdir(base_dir)
    for cr_uid in dir_list:
        if not cr_uid.isdigit():
            continue
        user_dir = os.path.join(base_dir, cr_uid)
        if not os.path.isdir(user_dir):
            continue
        is_end = get_one_user_odds(user_dir, odds_count_dict, total_count, max_count)
        if is_end:
            print("break");
            return odds_count_dict
    return odds_count_dict

def read_user_data_custom(file_dir, seq_len, max_len):
    """
    自定义向量读取，每次要改改这里
    """
    pay_file = os.path.join(file_dir, "pay_odds.txt")
    if (not os.path.exists(pay_file)):
        return []
    data = [[], []]  # 0没充值，1充值

    pay_count = 0
    no_pay_count = 0
    for file_type in range(2):
        pre_fix = ""
        payed = 0
        if file_type == 0:
            pre_fix = 'pay_'
            payed = 1
        # if file_type == 1:
        #     pay_coins = [x[0] for x in data[1]]
        #     coin_quartile = np.percentile(pay_coins, 75)
        #     for i,x in enumerate(data[1]):
        #         if(x[0] > coin_quartile):
        #             data[1].pop(i)
        #             pay_count -= 1
        file_odds = os.path.join(file_dir, pre_fix + "odds.txt")
        f_odds = open(file_odds, 'r')

        # file_coin = os.path.join(file_dir, pre_fix + "coin.txt")
        # f_coin = open(file_coin, 'r')

        # file_bonus = os.path.join(file_dir, pre_fix + "win_bonus.txt")
        # f_bonus = open(file_bonus, 'r')

        # file_time = os.path.join(file_dir, pre_fix + "time_delta.txt")
        # f_time = open(file_time, 'r')

        while True:
            line = f_odds.readline()
            if not line:
                break
            line = line.strip()
            # cr_data = np.zeros(3 + seq_len)
            line = line.split(" ")
            if len(line) < seq_len or line[-1] == "-1": # 被抛掉的数据
                continue

            odds = [float(x) for x in line[-seq_len:]]
            # odds_stat = process_data(odds)

            # line = f_coin.readline()
            # if not line:
                # break
            # line = line.relace("\n",'')
            # line = line.strip().split(" ")
            # if len(line) < seq_len or line[-1] == "-1": # 被抛掉的数据
            #     continue
            # coin = float(line[-1])
            # if file_type == 1 and coin > coin_quartile:
            #     continue
            # origin_coin = float(line[0])
            # earn = float(line[-1]) - float(line[0])
            # ratio = earn / origin_coin if origin_coin else earn

            # cr_data = np.hstack((coin, earn, ratio, odds_stat))
            cr_data = np.array(odds)

            # cr_data = [0] * (3 + seq_len)
            # line = line.split(" ")
            # cr_data[0] = float(line[-1])

            # line = f_bonus.readline().strip()
            # line = list(map(float, line.split(" ")[max_len - seq_len::]))
            # cr_data[1] = float(np.sum(line[::-1]))b

            # line = f_time.readline().strip()
            # line = list(map(float, line.split(" ")[max_len - seq_len::]))
            # cr_data[2] = float(np.sum(line))
            # data[].append(cr_data)
            # lable.append(file_type)
            # data[payed].append(cr_data)
            data[payed].append(cr_data)

            if file_type == 0:
                pay_count += 1
            else:
                if pay_count < 10:
                    return []
                no_pay_count += 1
                if no_pay_count > (pay_count * 10):
                    break
        f_odds.close()
        # f_bonus.close()
        # f_coin.close()
        # f_time.close()
    # return [data, lable]
    if pay_count < 10:
        return []
    return data

# 读玩家数据

def read_user_data(file_dir, seq_len, max_len):
    """
    max_len : 原始文件的最大序列长度，目前是10
    """
    # 只读有充值记录的
    pay_file = os.path.join(file_dir, "pay_odds.txt")
    if (not os.path.exists(pay_file)):
        return []
    data = [[], []]  # 0没充值，1充值
    lable = [[], []]

    pay_count = 0
    no_pay_count = 0
    for file_type in range(2):
        pre_fix = ""
        payed = 0
        if file_type == 0:
            pre_fix = 'pay_'
            payed = 1
        file_odds = os.path.join(file_dir, pre_fix + "odds.txt")
        f_odds = open(file_odds, 'r')

        # file_coin = os.path.join(file_dir, pre_fix + "coin.txt")
        # f_coin = open(file_coin, 'r')

        # file_bonus = os.path.join(file_dir, pre_fix + "win_bonus.txt")
        # f_bonus = open(file_bonus, 'r')

        # file_time = os.path.join(file_dir, pre_fix + "time_delta.txt")
        # f_time = open(file_time, 'r')

        while True:
            line = f_odds.readline().strip()
            # cr_data = np.zeros(3 + seq_len)
            line = line.split(" ")
            if len(line) < seq_len or line[-1] == "-1":  # 被抛掉的数据
                break
            cr_data = np.zeros(seq_len)
            for i in range(seq_len):
                # cr_data[3 + i] = float(line[max_len - seq_len + i])
                cr_data[i] = float(line[max_len - seq_len + i])

            # line = f_coin.readline()
            # if not line:
            #     break
            # # line = line.relace("\n",'')
            # line = line.strip()

            # cr_data = [0] * (3 + seq_len)
            # line = line.split(" ")
            # cr_data[0] = float(line[-1])

            # line = f_bonus.readline().strip()
            # line = list(map(float, line.split(" ")[max_len - seq_len::]))
            # cr_data[1] = float(np.sum(line[::-1]))

            # line = f_time.readline().strip()
            # line = list(map(float, line.split(" ")[max_len - seq_len::]))
            # cr_data[2] = float(np.sum(line))
            # data[].append(cr_data)
            # lable.append(file_type)
            # data[payed].append(cr_data)
            data[payed].append(process_data(cr_data))
            if file_type == 0:
                pay_count += 1
            else:
                if pay_count < 10:
                    return []
                no_pay_count += 1
                if no_pay_count > (pay_count * 10):
                    break
        f_odds.close()
        # f_bonus.close()
        # f_coin.close()
        # f_time.close()
    # return [data, lable]
    return data

def gen_uid_vector(seq_len, max_len):
    base_dir = os.path.join(config.log_result_dir, "slot")
    # base_dir = r"E:\codes\GitHubs\slot\result"

    uid_2_vectors = {}

    dir_list = os.listdir(base_dir)
    for cr_uid in dir_list:
        user_dir = os.path.join(base_dir, cr_uid)
        if not os.path.isdir(user_dir):
            continue
        ret = read_user_data_custom(user_dir, seq_len, max_len)
        if len(ret) > 0:
            uid_2_vectors[cr_uid] = ret
    return uid_2_vectors
# exit()

if __name__ == '__main__':
    import numpy as np
    from matplotlib import pyplot as plt
    from utils import file_util, other_util
    from sklearn.preprocessing import StandardScaler
    from matplotlib.ticker import MultipleLocator

    #---------------------------------------------------
    xmajorLocator   = MultipleLocator(0.5) #将x主刻度标签设置为20的倍
    ymajorLocator   = MultipleLocator(50) #将y轴主刻度标签设置为0.5的倍数

    scaler = StandardScaler()
    odds_count_dict = get_odds_vector(10000000000)
    no_pay = odds_count_dict[1]
    pay = odds_count_dict[0]

    no_pay_machine_id_2_odds = {}
    pay_machine_id_2_odds = {}
    for machine_id, machine_odds in no_pay.items():
        path = file_util.get_figure_path("slot", "odds_distribution_no_zero", str(machine_id))
        # machine_line_odds = machine_odds.values()
        for line, machine_line_odds in machine_odds.items():
            machine_line_odds_tmp = sorted(machine_line_odds.items(), key=lambda x : x[0])
            machine_line_odds_tmp = np.array(machine_line_odds_tmp)
            x = machine_line_odds_tmp[:,0]
            y = machine_line_odds_tmp[:,1]
            avg = np.sum(x * y) / np.sum(y)
            if len(x) > 1:
                x = x[1:]
                y = y[1:]
            #---------------------------------------------------
            xmajorLocator   = MultipleLocator(0.5) #将x主刻度标签设置为20的倍

            ymajorLocator   = MultipleLocator(np.max(y) / 8) #将y轴主刻度标签设置为0.5的倍数
            plt.minorticks_on()
            plt.xlabel("odds")
            plt.ylabel("count")
            plt.xlim(xmax=10,xmin=0)
            plt.gcf().set_size_inches(18.5, 10.5)
            plt.bar(x, y, width = 0.1)
            plt.bar(avg, np.max(y), width = 0.1)
            #设置主刻度标签的位置,
            plt.gca().xaxis.set_major_locator(xmajorLocator)
            plt.gca().yaxis.set_major_locator(ymajorLocator)
            # plt.gca().xaxis.set_minor_locator(xminorLocator)
            # plt.gca().yaxis.set_minor_locator(yminorLocator)
            # plt.show()
            plt.savefig(os.path.join(path, str(line)+ "_no_pay.png"))
            # plt.show()
            plt.cla()
        machine_odds_tmp = other_util.union_dict(*machine_odds.values())
        no_pay_machine_id_2_odds[machine_id] = machine_odds_tmp
        machine_odds_tmp = sorted(machine_odds_tmp.items(), key=lambda x : x[0])
        machine_odds_tmp = np.array(machine_odds_tmp)
        x = machine_odds_tmp[:,0]
        y = machine_odds_tmp[:,1]
        avg = np.sum(x * y) / np.sum(y)
        if len(x) > 1:
            x = x[1:]
            y = y[1:]

        xmajorLocator   = MultipleLocator(0.5) #将x主刻度标签设置为20的倍
        ymajorLocator   = MultipleLocator(np.max(y) / 8) #将y轴主刻度标签设置为0.5的倍数
        plt.minorticks_on()
        plt.xlabel("odds")
        plt.ylabel("count")
        plt.xlim(xmax=10,xmin=0)
        plt.gcf().set_size_inches(18.5, 10.5)
        plt.bar(x, y, width = 0.1)
        plt.bar(avg, np.max(y), width = 0.1)
        #设置主刻度标签的位置,
        plt.gca().xaxis.set_major_locator(xmajorLocator)
        plt.gca().yaxis.set_major_locator(ymajorLocator)
        # plt.gca().xaxis.set_minor_locator(xminorLocator)
        # plt.gca().yaxis.set_minor_locator(yminorLocator)
        plt.savefig(os.path.join(path, "all_no_pay"))
        # plt.show()
        plt.cla()

    for machine_id, machine_odds in pay.items():
        path = file_util.get_figure_path("slot", "odds_distribution_no_zero", str(machine_id))
        # machine_line_odds = machine_odds.values()
        for line, machine_line_odds in machine_odds.items():
            machine_line_odds_tmp = sorted(machine_line_odds.items(), key=lambda x : x[0])
            machine_line_odds_tmp = np.array(machine_line_odds_tmp)
            x = machine_line_odds_tmp[:,0]
            y = machine_line_odds_tmp[:,1]
            avg = np.sum(x * y) / np.sum(y)
            if len(x) > 1:
                x = x[1:]
                y = y[1:]
            xmajorLocator   = MultipleLocator(0.5) #将x主刻度标签设置为20的倍
            ymajorLocator   = MultipleLocator(np.max(y) / 8) #将y轴主刻度标签设置为0.5的倍数
            plt.minorticks_on()
            plt.xlabel("odds")
            plt.ylabel("count")
            plt.xlim(xmax=10,xmin=0)
            plt.gcf().set_size_inches(18.5, 10.5)
            plt.bar(x, y, width = 0.1)
            plt.bar(avg, np.max(y), width = 0.1)
            #设置主刻度标签的位置,
            plt.gca().xaxis.set_major_locator(xmajorLocator)
            plt.gca().yaxis.set_major_locator(ymajorLocator)
            # plt.gca().xaxis.set_minor_locator(xminorLocator)
            # plt.gca().yaxis.set_minor_locator(yminorLocator)
            plt.savefig(os.path.join(path, str(line) + "_pay.png"))
            # plt.show()
            plt.cla()
        machine_odds_tmp = other_util.union_dict(*machine_odds.values())
        pay_machine_id_2_odds[machine_id] = machine_odds_tmp
        machine_odds_tmp = sorted(machine_odds_tmp.items(), key=lambda x : x[0])
        machine_odds_tmp = np.array(machine_odds_tmp)
        x = machine_odds_tmp[:,0]
        y = machine_odds_tmp[:,1]
        avg = np.sum(x * y) / np.sum(y)
        if len(x) > 1:
            x = x[1:]
            y = y[1:]

        xmajorLocator   = MultipleLocator(0.5) #将x主刻度标签设置为20的倍
        ymajorLocator   = MultipleLocator(np.max(y) / 8) #将y轴主刻度标签设置为0.5的倍数
        plt.minorticks_on()
        plt.xlabel("odds")
        plt.ylabel("count")
        plt.xlim(xmax=10,xmin=0)
        plt.gcf().set_size_inches(18.5, 10.5)
        plt.bar(x, y, width = 0.1)
        plt.bar(avg, np.max(y), width = 0.1)
        #设置主刻度标签的位置,
        plt.gca().xaxis.set_major_locator(xmajorLocator)
        plt.gca().yaxis.set_major_locator(ymajorLocator)
        # plt.gca().xaxis.set_minor_locator(xminorLocator)
        # plt.gca().yaxis.set_minor_locator(yminorLocator)
        # plt.show()
        plt.savefig(os.path.join(path, "all_pay"))
        plt.cla()

    # all_data = sorted(all_data.items(), key=lambda x : x[0])
    # del odds_count_dict

    # # no_pay = scaler.fit_transform(no_pay)
    # # pay = scaler.fit_transform(pay)
    # # all_data = scaler.fit_transform(no_pay)

    # no_pay = np.array(no_pay)
    # no_pay_x = no_pay[:,0]
    # no_pay_y = no_pay[:,1]
    # no_pay_avg = np.sum(no_pay_x * no_pay_y) / np.sum(no_pay_y)
    # # no_pay_var = np.var(no_pay_x * no_pay_y)
    # print("no_pay: mean: %f" %(no_pay_avg))

    # pay = np.array(pay)
    # pay_x = pay[:,0]
    # pay_y = pay[:,1]
    # pay_avg = np.sum(pay_x * pay_y) / np.sum(pay_y)
    # # pay_var = np.var(pay_x * pay_y)
    # print("pay: mean: %f" %(pay_avg))

    # all_data = np.array(all_data)
    # all_data_x = all_data[:,0]
    # all_data_y = all_data[:,1]
    # all_avg = np.sum(all_data_x * all_data_y) / np.sum(all_data_y)
    # # all_var = np.var(all_data_x * all_data_y)
    # print("all: mean: %f" %(all_avg))

    # path = file_util.get_figure_path("slot")

    # # no_pay
    # plt.figure(1)
    # plt.minorticks_on()
    # plt.xlabel("odds")
    # plt.ylabel("count")
    # # plt.ylim(ymax=30,ymin=0)
    # plt.xlim(xmax=2,xmin=0)
    # # plt.scatter(no_pay_x[1:], no_pay_y[1:], marker='.')
    # plt.bar(no_pay_x, no_pay_y, width = 0.1)
    # plt.legend()
    # # plt.savefig(os.path.join(path, "odds_distribution_no_pay_with_zero"))
    # print("no pay zero: ", no_pay_y[0])

    # # pay
    # plt.figure(2)
    # plt.minorticks_on()
    # plt.xlabel("odds")
    # plt.ylabel("count")
    # # plt.ylim(ymax=30,ymin=0)
    # plt.xlim(xmax=2,xmin=0)
    # # plt.scatter(pay_x[1:], pay_y[1:], marker='.')
    # plt.bar(pay_x, pay_y, width = 0.1)
    # plt.legend()
    # # plt.savefig(os.path.join(path, "odds_distribution_pay_with_zero"))
    # print("pay zero: ", pay_y[0])

    # # all
    # plt.figure(3)
    # plt.minorticks_on()
    # plt.xlabel("odds")
    # plt.ylabel("count")
    # # plt.ylim(ymax=30,ymin=0)
    # plt.xlim(xmax=2,xmin=0)
    # # plt.scatter(pay_x[1:], pay_y[1:], marker='.')
    # plt.bar(all_data_x, all_data_y, width = 0.1)
    # plt.legend()
    # # plt.savefig(os.path.join(path, "odds_distribution_all_with_zero"))
    # print("all_zero: ",all_data_y[0])

    # plt.show()

    # from scipy import stats
    # # from scipy.stat import skew
    # file_names = ['coin', 'is_free', 'level', 'odds',
    #               'time_delta', 'win_bonus', 'win_free']
    # seq_len = 10
    # max_len = 50

    # # mean_time = calc_len_times(seq_len, max_len)
    # # exit()
    # uid_2_vectors = gen_uid_vector(seq_len, max_len)
    # # print(len(uid_2_vectors))
    # # print(uid_2_vectors)
    # stat_uid = {}
    # for uid, vectors in uid_2_vectors.items():
    #     no_pay = np.array(vectors[0])
    #     pay = np.array(vectors[1])

    #     types = ["均值", "方差", "偏度", "峰度", "最小", "最大"]

    #     no_pay_stat = []
    #     pay_stat = []
    #     for i in range(len(types)):
    #         no_pay_stat.append(np.mean(no_pay[:, i]))
    #         pay_stat.append(np.mean(pay[:, i]))

    #     from matplotlib import pyplot as plt
    #     plt.xlabel = "stat type"
    #     plt.ylabel = "stat value"
    #     types = ["均值", "方差", "偏度", "峰度", "最小", "最大"]
    #     plt.plot(no_pay_stat, label="no pay")
    #     plt.plot(pay_stat, label="pay")

    #     plt.legend()
    #     plt.show()

    #     print(pay)

    # from matplotlib import pyplot as plt
    # for uid, cr_data in stat_uid.items():
    #     no_pay = cr_data[0]
    #     pay = cr_data[1]

    #     plt.xlabel = "stat type"
    #     plt.ylabel = "stat value"
    #     types = ["均值", "方差", "偏度", "峰度", "最小", "最大"]
    #     plt.plot(no_pay, types, label="no pay")
    #     plt.plot(pay, types, label="pay")

    #     plt.legend()
    #     plt.show()

        # stat_pay.append(np.mean(pay))
        # stat_pay.append(np.var(pay))
        # stat_pay.append(skew(pay))

# def dirlist(path, allfile):
#     filelist = os.listdir(path)
#     for filename in filelist:
#         filepath = os.path.join(path, filename)
#         if os.path.isdir(filepath):
#             cr_uid = filename
#             dirlist(filepath, allfile)
#         else:
#             allfile.append(filepath)
#     return allfile


from django import forms
from django.conf import settings
from django.db.models import QuerySet
from snowpenguin.django.recaptcha3.fields import ReCaptchaField

from . import services
from .models import Product, Review

class ProductFilterForm(forms.Form):
    """Form for filtering products."""

    min_price = forms.DecimalField(
        min_value=0,
        decimal_places=2,
        label="",
        required=False,
        widget=forms.NumberInput(
            attrs={"class": "form-control mb-2", "placeholder": "Min price"}
        ),
    )
    max_price = forms.DecimalField(
        min_value=0,
        decimal_places=2,
        label="",
        required=False,
        widget=forms.NumberInput(
            attrs={"class": "form-control mb-2", "placeholder": "Max price"}
        ),
    )
    category = forms.ModelChoiceField(
        queryset=services.get_all_categories(),
        widget=forms.RadioSelect,
        required=False,
    )
    brands = forms.ModelMultipleChoiceField(
        queryset=services.get_all_brands(),
        widget=forms.CheckboxSelectMultiple,
        label="Brand",
        required=False,
    )
    years = forms.MultipleChoiceField(
        choices=[
            (year, year)
            for year in set(
                map(
                    lambda tup: int(tup[0]),
                    Product.objects.all().values_list("year"),
                )
            )
        ],
        widget=forms.CheckboxSelectMultiple,
        label="Year",
        required=False,
    )

    def get_filtered_(self, products: QuerySet[Product]) -> QuerySet[Product]:
        """Returns the filtered given products."""
        if self.cleaned_data.get("min_price"):
            products = products.filter(
                price__gte=self.cleaned_data.get("min_price")
            )
        if self.cleaned_data.get("max_price"):
            products = products.filter(
                price__lte=self.cleaned_data.get("max_price")
            )
        if self.cleaned_data.get("category"):
            products = products.filter(category=self.cleaned_data["category"])
        if self.cleaned_data.get("brands"):
            products = products.filter(brand__in=self.cleaned_data["brands"])
        if self.cleaned_data.get("years"):
            products = products.filter(year__in=self.cleaned_data["years"])
        return products

dict_with_field_classes = {"class": "form-control w-50 mb-2"}

class ReviewModelForm(forms.ModelForm):
    """Model form for adding review to product."""

    if not settings.TESTING:
        captcha = ReCaptchaField()

    class Meta:
        """Meta options for the ReviewForm."""

        model = Review
        fields = ("name", "body")
        if not settings.TESTING:
            fields = ("name", "body", "captcha")
        widgets = {
            "name": forms.TextInput(attrs=dict_with_field_classes),
            "body": forms.Textarea(attrs=dict_with_field_classes),
        }


import cv2
import numpy as np

img = cv2.imread('galon1.jpg', 1)
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
lower_range = np.array([50, 50, 190], dtype=np.uint8)
upper_range = np.array([106, 255, 255], dtype=np.uint8)

mask = cv2.inRange(hsv, lower_range, upper_range)

kernel = np.ones((10,10),np.uint8)

#Buat di tebelin
dilation = cv2.dilate(mask,kernel,iterations = 1)

#buat itung
# contours, hierarchy = cv2.findContours(dilation,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
contours, hierarchy = cv2.findContours(dilation,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)

#Kopi gambar asli ke variable resultImg
resultImg = (img).copy()

#Array kontur
contour = []
#Perulangan untuk kontur
for i in range(len(contours)):
    #Banyaknya kontur ke variable cnt
    cnt = contours[i]
    #Mencari radius untuk menggambar lingkaran
    (x,y),radius = cv2.minEnclosingCircle(cnt)
    #Pusat lingkaran
    center = (int(x),int(y))
    #Gambar lingkaran
    resultImg = cv2.circle(resultImg,center,int(radius),(0,0,255),3)

    len(contour)
    #add text
    text = "Jumlah Galon : " + str(len(contours)) + " pcs"
    cv2.putText(resultImg, text, (500, 50), cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 0, 0), 2)
    cv2.imshow('images',resultImg)
    #simpan gambar
    cv2.imwrite('galon1-countors.jpg', resultImg)

while (1):
    k = cv2.waitKey(0)
    if (k == 27):
        break

cv2.destroyAllWindows()


import numpy as np
import pandas as pd
from utils import get_survey_items_order
# *********************************
# helper functions
# *********************************
def get_drop_columns(df, columns=None, use_default=True):
    """
    defines columns to drop when converting from _clean to _event
    files each event file. Generates a list of columns to drop,
    constrains it to columns already in the dataframe.
    """
    default_cols = ['exp_stage',
                    'feedback_duration', 'possible_responses',
                    'stim_duration', 'text', 'time_elapsed',
                   'timing_post_trial', 'trial_num']
    drop_columns = []
    if columns is not None:
        drop_columns = columns
    if use_default == True:
        #if true, drop columns come from argument and from default (inclusive or)
        drop_columns = set(default_cols) | set(drop_columns)
     #drop columns only included if they appear in the dataframe
    drop_columns = set(df.columns) & set(drop_columns)
    return drop_columns

def get_movement_times(df):
    """
    time elapsed is evaluated at the end of a trial, so we have to subtract
    timing post trial and the entire block duration to get the time when
    the trial started. Then add the reaction time to get the time of movement
    """
    trial_time = df.time_elapsed - df.block_duration + \
                 df.rt
    return trial_time

def get_trial_times(df):
    """
    time elapsed is evaluated at the end of a trial, so we have to subtract
    timing post trial and the entire block duration to get the time when
    the trial started
    """
    trial_time = df.time_elapsed - df.block_duration
    return trial_time

def process_rt(events_df):
    """changes -1 rts (javascript no response) to nan, changes column from rt -> response_time """
    events_df.loc[events_df['rt'] == -1, 'rt'] = np.nan #replaces no response rts with nan
    events_df = events_df.rename(columns={'rt': 'response_time'})
    return events_df

def row_match(df,row_list):
    bool_list = pd.Series(True,index=df.index)
    for i in range(len(row_list)):
        bool_list = bool_list & (df.iloc[:,i] == row_list[i])
    return bool_list[bool_list].index

def create_events(df, exp_id, aim, duration=None, preRating_df = None):
    """
    defines what function to reference to create each task-specific event file
    takes in a dataframe from processed data, and exp_id and a duration
    """
    events_df = None
    lookup = {'attention_network_task': create_ANT_event,
              'columbia_card_task_fmri': create_CCT_event,
              'discount_fixed': create_discountFix_event,
              'dot_pattern_expectancy': create_DPX_event,
              'motor_selective_stop_signal': create_motorSelectiveStop_event,
              'stop_signal': create_stopSignal_event,
              'stroop': create_stroop_event,
              'survey_medley': create_survey_event,
              'twobytwo': create_twobytwo_event,
              'ward_and_allport': create_WATT_event}
    fun = lookup.get(exp_id)
    if fun is not None:
        if exp_id != 'columbia_card_task_fmri':
            events_df = fun(df, aim, duration=duration)
        elif exp_id == 'manipulation_task':
            events_df = fun(df, aim, preRating_df = preRating_df)
        else:
            events_df = fun(df, aim)
    return events_df

# *********************************
# Functions to create event files
# *********************************

def create_ANT_event(df, aim, duration=None):
    columns_to_drop = get_drop_columns(df, columns = ['trial_type', 'block_duration', 'trial_id'])
    events_df = df[df['time_elapsed']>0].copy()

    if duration is None:
        events_df.insert(0,'duration',events_df.stim_duration)
    else:
        events_df.insert(0,'duration',duration)

    # duration
    events_df.insert(0,'onset',get_trial_times(df))
    # process RT
    events_df = process_rt(events_df)

    # convert milliseconds to seconds
    events_df.loc[:,['response_time','onset','duration']]/=1000
    # drop unnecessary columns
    events_df = events_df.drop(columns_to_drop, axis=1)

    return events_df

def create_CCT_event(df, aim):
    columns_to_drop = get_drop_columns(df, columns = ['cards_left',
                                                    'round_points',
                                                    'which_round',
                                                    'trial_type',
                                                    'block_duration'])

    events_df = df[df['time_elapsed']>0].copy()
    events_df.insert(0, 'duration', events_df.rt)
    # time elapsed is at the end of the trial, so have to remove the block
    # duration
    events_df.insert(0,'onset',get_trial_times(df))
    # change onset of ITI columns to reflect the fact that the stimulus changes 750 ms after block starts
    # ITI_trials = events_df.query('trial_id == "ITI"').index

    # events_df.loc[ITI_trials, 'duration'] = events_df.loc[ITI_trials, 'stim_duration']-750
    # print(events_df.loc[ITI_trials])
    all_frames = []  # List to store chunks of DataFrame
    start_idx = 0

    for index, row in events_df.iterrows():
        if row['trial_id'] == 'ITI':
            all_frames.append(events_df.loc[start_idx:index-1])

            first_row = row.copy()
            second_row = row.copy()

            first_row['duration'] = row['stim_duration']
            first_row['trial_id'] = 'feedback'
            second_row['duration'] = row['block_duration'] - row['stim_duration']
            second_row['trial_id'] = 'ITI'
            second_row['onset'] = row['onset'] + row['stim_duration']

            all_frames.extend([pd.DataFrame([first_row]), pd.DataFrame([second_row])])

            start_idx = index + 1

    all_frames.append(events_df.loc[start_idx:])
    df_split = pd.concat(all_frames, ignore_index=True)

    events_df = df_split
    # process RT
    events_df = process_rt(events_df)
    # convert milliseconds to seconds
    events_df.loc[:,['response_time','onset','duration']]/=1000
    # # add feedback columns
    # events_df.loc[:,'feedback'] = events_df.clicked_on_loss_card \
    #                                 .apply(lambda x: int(not x))
    # drop unnecessary columns
    events_df = events_df.drop(columns_to_drop, axis=1)

    return events_df

def create_discountFix_event(df, aim, duration=None):
    columns_to_drop = get_drop_columns(df, columns = ['trial_id', 'block_duration'])
    events_df = df[df['time_elapsed']>0].copy()

    events_df.loc[:,'trial_type'] = events_df.choice
    if duration is None:
        events_df.insert(0,'duration',events_df.stim_duration)
    else:
        events_df.insert(0,'duration',duration)
    # time elapsed is at the end of the trial, so have to remove the block
    # duration
    events_df.insert(0,'onset',get_trial_times(df))
    # process RT
    events_df = process_rt(events_df)
    # convert milliseconds to seconds
    events_df.loc[:,['response_time','onset','duration']]/=1000

    # drop unnecessary columns
    events_df = events_df.drop(columns_to_drop, axis=1)

    return events_df

def create_DPX_event(df, aim, duration=None):
    columns_to_drop = get_drop_columns(df, columns=['block_duration'])
    events_df = df[df['time_elapsed']>0].copy()

    events_df.loc[:,'trial_type'] = events_df.condition
    if duration is None:
        events_df.insert(0,'duration',events_df.stim_duration)
    else:
        events_df.insert(0,'duration',duration)
    # time elapsed is at the end of the trial, so have to remove the block
    # duration. We also want the trial
    onsets = get_trial_times(df)
    events_df.insert(0,'onset',onsets)
    # process RT
    events_df = process_rt(events_df)
    # convert milliseconds to seconds
    events_df.loc[:,['response_time','onset',
                     'duration']]/=1000
    # drop unnecessary columns
    events_df = events_df.drop(columns_to_drop, axis=1)

    return events_df

def create_motorSelectiveStop_event(df, aim, duration=None):
    columns_to_drop = get_drop_columns(df, columns = ['condition',
                                                    'SS_duration',
                                                    'SS_stimulus',
                                                    'SS_trial_type',
                                                    'block_duration',
                                                    'correct',
                                                    'trial_id'])
    events_df = df[df['time_elapsed']>0].copy()

    # create condition column
    crit_key = events_df.query('condition=="stop"') \
                .correct_response.unique()[0]
    noncrit_key = events_df.query('condition=="ignore"') \
                    .correct_response.unique()[0]
    condition_df = events_df.loc[:,['correct_response',
                                    'SS_trial_type','stopped']]
    condition = pd.Series(index=events_df.index)
    condition[row_match(condition_df, [crit_key,'go',False])] = 'crit_go'
    condition[row_match(condition_df, [crit_key,'go',True])] = 'crit_go'
    condition[row_match(condition_df,
                        [crit_key,'stop',True])] = 'crit_stop_success'
    condition[row_match(condition_df,
                        [crit_key,'stop',False])] = 'crit_stop_failure'
    condition[row_match(condition_df,
                        [noncrit_key,'stop',False])] = 'noncrit_signal'
    condition[row_match(condition_df,
                        [noncrit_key,'go',False])] = 'noncrit_nosignal'
    condition[row_match(condition_df,
                        [noncrit_key,'stop',True])] = 'noncrit_signal'
    condition[row_match(condition_df,
                        [noncrit_key,'go',True])] = 'noncrit_nosignal'

    events_df.loc[:,'trial_type'] = condition

    if duration is None:
        events_df.insert(0,'duration',events_df.stim_duration)
    else:
        events_df.insert(0,'duration',duration)
    # time elapsed is at the end of the trial, so have to remove the block
    # duration
    events_df.insert(0,'onset',get_trial_times(df))
    # process RT
    events_df = process_rt(events_df)
    # convert milliseconds to seconds
    events_df.loc[:,['response_time','onset','duration', 'SS_delay']]/=1000
    # drop unnecessary columns
    events_df = events_df.drop(columns_to_drop, axis=1)

    return events_df

def create_stopSignal_event(df, aim, duration=None):

    events_df = df[df['time_elapsed']>0].copy()

    # create condition label
    SS_success_trials = events_df.query('SS_trial_type == "stop" \
                                        and stopped == True').index
    SS_fail_trials = events_df.query('SS_trial_type == "stop" \
                                        and stopped == False').index
    events_df.loc[:,'condition'] = 'go'
    events_df.loc[SS_success_trials,'condition'] = 'stop_success'
    events_df.loc[SS_fail_trials,'condition'] = 'stop_failure'
    events_df.loc[:,'trial_type'] = events_df.condition

    events_df.loc[events_df['trial_type'] == 'stop_success', ['correct']] = 1
    # duration
    if duration is None:
        events_df.insert(0,'duration',events_df.stim_duration)
    else:
        events_df.insert(0,'duration',duration)
    # time elapsed is at the end of the trial, so have to remove the block

    events_df.insert(0,'onset',get_trial_times(df))
    # process RT
    events_df = process_rt(events_df)
    # convert milliseconds to seconds
    events_df.loc[:,['response_time','onset','duration', 'block_duration', 'SS_delay']]/=1000
    # get and drop unnecessary columns
    columns_to_drop = get_drop_columns(events_df, columns = ['condition',
                                                    'SS_duration',
                                                    'SS_stimulus',
                                                    'SS_trial_type',
                                                    'block_duration',
                                                    'correct',
                                                    'trial_id'])
    events_df = events_df.drop(columns_to_drop, axis=1)

    return events_df

def create_stroop_event(df, aim, duration=None):
    columns_to_drop = get_drop_columns(df, columns = ['block_duration',
                                                    'trial_id'])
    events_df = df[df['time_elapsed']>0].copy()

    events_df.loc[:,'trial_type'] = events_df.condition
    if duration is None:
        events_df.insert(0,'duration',events_df.stim_duration)
    else:
        events_df.insert(0,'duration',duration)
    # time elapsed is at the end of the trial, so have to remove the block
    # duration
    events_df.insert(0,'onset',get_trial_times(df))
    # process RT
    events_df = process_rt(events_df)
    # convert milliseconds to seconds
    events_df.loc[:,['response_time','onset','duration','block_duration']]/=1000
    # drop unnecessary columns
    events_df = events_df.drop(columns_to_drop, axis=1)

    return events_df

def create_survey_event(df, aim, duration=None):
    columns_to_drop = get_drop_columns(df,
                                       use_default=False,
                                       columns = ['block_duration',
                                                'response',
                                                'options',
                                                'stim_duration',
                                                'text',
                                                'time_elapsed',
                                                'timing_post_trial',
                                                'trial_id',
                                                'item_responses'
                                                ])
    events_df = df[df['time_elapsed']>0].copy()
    # add signifiers for each question
    events_df['trial_type'] = df['item_text'].map(get_survey_items_order())
    # add duration and response regressor
    if duration is None:
        events_df.insert(0,'duration',events_df.stim_duration)
    else:#
        events_df.insert(0,'duration',duration)
    # time elapsed is at the end of the trial, so have to remove the block
    # duration
    events_df.insert(0,'onset',get_trial_times(df))
    # process RT
    events_df = process_rt(events_df)
    # convert milliseconds to seconds
    events_df.loc[:,['response_time','onset','duration']]/=1000
    # drop unnecessary columns
    events_df = events_df.drop(columns_to_drop, axis=1)

    return events_df

def create_twobytwo_event(df,aim, duration=None):
    columns_to_drop = get_drop_columns(df, columns=['block_duration',
                                                    'trial_id',
                                                    'trial_type'])
    events_df = df[df['time_elapsed']>0].copy()
    block_start_indexes = events_df.index[events_df['trial_id'] == 'test_start_block'].tolist()
    events_df['first_trial_of_block'] = 0
    for n in range(len(block_start_indexes)):
        ind = block_start_indexes[n]
        events_df.at[ind+1, 'first_trial_of_block'] = 1
    events_df = events_df[events_df['trial_id'] != 'test_start_block']
    # reorganize and rename columns in line with BIDs specifications
    if duration is None:
        events_df.insert(0,'duration',events_df.stim_duration)
    else:
        events_df.insert(0,'duration',duration)
    # time elapsed is at the end of the trial, so have to remove the block
    # duration
    events_df.insert(0,'onset',get_trial_times(df))
    # process RT
    events_df = process_rt(events_df)
    # convert milliseconds to seconds
    events_df.loc[:,['response_time','onset',
                     'duration','CTI', 'block_duration']]/=1000
    # drop unnecessary columns
    events_df = events_df.drop(columns_to_drop, axis=1)

    #change color to blue
    events_df = events_df.replace('#1F45FC', 'blue')

    return events_df

def create_WATT_event(df,aim, duration):
    columns_to_drop = get_drop_columns(df, columns = ['correct',
                                                      'min_moves',
                                                      'num_moves_made',
                                                      'problem_time',
                                                      'trial_type',
                                                      'block_duration'])
    columns_to_drop.remove('exp_stage')
    events_df = df.copy()
    # get planning, movement, and feedback index
    practice_planning = events_df.query('exp_stage == "practice" \
                                    and trial_id == "to_hand" \
                                    and num_moves_made==1').index
    practice_other = events_df.query('exp_stage == "practice" \
                                    and not(trial_id == "to_hand" \
                                    and num_moves_made==1) \
                                    and trial_id != "feedback"').index
    planning_moves = events_df.query('exp_stage == "test" \
                                    and trial_id == "to_hand" \
                                    and num_moves_made==1').index
    other_moves = events_df.query('exp_stage == "test" \
                                    and not (trial_id == "to_hand" \
                                    and num_moves_made==1) \
                                    and trial_id != "feedback"').index
    feedback = events_df.query('trial_id == "feedback"').index
    # add planning indicator
    events_df.insert(1,'planning',0)
    events_df.loc[planning_moves,'planning'] = 1
    events_df.loc[practice_planning,'planning'] = 1
    # ** Onsets **
    # time elapsed is at the end of the trial, so have to remove the block
    # duration
    events_df.insert(0,'onset',get_trial_times(df))
    events_df.insert(0, 'duration', 0)

    # add durations for planning
    planning_total = events_df[(events_df.trial_id=='to_hand') & (events_df.num_moves_made == 1)].index.values
    events_df.loc[planning_total, 'duration'] = events_df.loc[planning_total, 'rt']
    events_df.loc[practice_other, 'duration'] = events_df.loc[practice_other, 'rt']
    events_df.loc[other_moves, 'duration'] = events_df.loc[other_moves, 'rt']

    # add durations for feedback
    events_df.loc[feedback, 'duration'] = events_df.loc[feedback, 'stim_duration']

    subject = events_df['worker_id'].unique()[0]

    # Identify the feedback rows
    feedback_rows = events_df[events_df['trial_id'] == 'feedback'].copy()
    # Calculate the duration for the 'ITI' rows
    feedback_rows['ITI_duration'] = feedback_rows['block_duration'] - feedback_rows['duration']
    # Calculate the onset for the 'ITI' rows
    feedback_rows['ITI_onset'] = feedback_rows['onset'] + 1000
    # Create the 'ITI' rows by copying the preceding rows
    iti_rows = feedback_rows.copy()

    # Shift the values down one row to match the preceding trial
    iti_rows = iti_rows.shift(periods=-1, axis=0)

    # Modify the columns that should be different for 'ITI'
    iti_rows['duration'] = iti_rows['ITI_duration']
    iti_rows['onset'] = iti_rows['ITI_onset']
    iti_rows['trial_id'] = 'ITI'
    iti_rows['planning'] = 0  # or whatever value is appropriate for 'ITI'

    # Here, the rest of the columns will inherit values from the preceding row (trial)
    # If you want to manually override some columns, you can do so here. For example:
    # iti_rows['condition'] = 'ITI_condition'

    # Remove the extra ITI_duration and ITI_onset columns
    iti_rows = iti_rows.drop(['ITI_duration', 'ITI_onset'], axis=1)
    # Append the 'ITI' rows to the original dataframe
    events_df = pd.concat([events_df, iti_rows])

    # Sort the dataframe based on the onset column
    events_df = events_df.sort_values(by='onset').reset_index(drop=True)

    # process RT
    events_df = process_rt(events_df)
    # convert milliseconds to seconds
    events_df.loc[:,['onset','duration',
                     'response_time']]/=1000

    # drop unnecessary columns
    events_df = events_df.drop(columns_to_drop, axis=1)

    # fix typo
    events_df['condition'] = events_df['condition'].str.replace('intermeidate', 'intermediate')

    return events_df


lst=[]
while True:
    n=input()
    if n =="-1":
        break
    lst.append(n)
m=input()
t=-1
for i in range(len(lst)):
    if len(lst[i])>t:
        t=len(lst[i])
print(m*(t+2))
for i in range(len(lst)):
    a=len(lst[i])
    print(m,end='')
    print(lst[i],end='')
    print(' '*(t-a),end='')
    print(m)
print(m*(t+2))


from bs4 import BeautifulSoup
import re
from datetime import date
import urllib.parse as urlparse

class HTMLParser:
    def _getListURL(self, url, html) -> str:
        soup = BeautifulSoup(html, "html.parser", from_encoding="utf-8")
        divs = soup.find_all('div', class_='cont_nav')
        try:
            for div in divs:
                if re.search(r'学术动态', div.find('h3').get_text()) is None:
                    continue
                lecture_list_link = div.find(
                    'a', href=re.compile(r'newListLogic.shtml.+'))
                lecture_list_url = lecture_list_link['href']
                lecture_list_url = urlparse.urljoin(url, lecture_list_url)
                return lecture_list_url
        except:
            pass
        return None

    def _getAllListPages(self, url, html) -> {}:
        soup = BeautifulSoup(html, "html.parser", from_encoding="utf-8")
        try:
            text = soup.find('td', text=re.compile(r'共.+')).get_text()
            num = int(re.search(r'共1/(\d*)页', text).group(1))
            return {url + '&pageNumber=' + str(i) for i in range(1, num+1)}
        except:
            return None

    def _getLectureURLs(self, url, html) -> {}:
        soup = BeautifulSoup(html, "html.parser", from_encoding="utf-8")
        links = soup.find_all('a', href=re.compile(r'newsDetails_zw.shtml.+'))
        lecture_urls = set()
        for link in links:
            if re.search(r'讲座', link.get_text()) is not None:
                lecture_urls.add(urlparse.urljoin(url, link['href']))
        return lecture_urls

    def _getLectureDetails(self, url, html) -> {}:
        soup = BeautifulSoup(html, "html.parser", from_encoding="utf-8")
        text = re.sub(r'<[^<>]>', '', soup.get_text())
        text = re.sub(r'\xa0', '', text)
        try:
            page_title = soup.find_all('h3')[1].get_text()
        except:
            page_title = '未识别'
        try:
            title = re.search(r'(题目|主题)(：|:)(\r|\n)*([^\r\n]*)', text).group(4)
        except:
            title = '未识别'
        try:
            speaker = re.search(
                r'(报 ?告 ?人|演 ?讲 ?者|主 ?讲 ?人)(：|:)(\r|\n)*([^\r\n]*)', text).group(4)
        except:
            speaker = '未识别'
        try:
            temp = re.search(r'发布时间：\[(\d+)-(\d+)-(\d+)\]', text)
            announce_date = date(int(temp.group(1)), int(
                temp.group(2)), int(temp.group(3)))
        except:
            announce_date = date(1, 1, 1)
        try:
            time = re.search(
                r'(?<!发布)时间(：|:)(\r|\n)*([^\r\n]*)', text).group(3)
        except:
            time = '未识别'
        try:
            room = re.search(r'地点(：|:)(\r|\n)*([^\r\n]*)', text).group(3)
        except:
            room = '未识别'
        return {'url': url, 'page title': page_title, 'title': title, 'speaker': speaker,
                'time': time, 'room': room, 'announce date': announce_date}

    def parse(self, url, html) -> ():
        if url is None or html is None:
            return None
        elif re.search(r'newsDetails_zw.shtml', url) is not None:
            data = self._getLectureDetails(url, html)
            return (data, None)
        elif re.search(r'newListLogic.shtml.+&pageNumber', url) is not None:
            lecture_urls = self._getLectureURLs(url, html)
            return (None, lecture_urls)
        elif re.search(r'newListLogic.shtml', url) is not None:
            all_list_urls = self._getAllListPages(url, html)
            return (None, all_list_urls)
        elif re.search(r'index.shtml', url) is not None:
            list_url = self._getListURL(url, html)
            return (None, {list_url})
        else:
            return None


# Standard Libs
import pytest
from unittest.mock import patch, MagicMock

# External Libs
from src.services.bank_transfer.service import BankTransferService
from tests.src.stubs.router_bank_accounts_stubs.stubs import x_thebes_bank_tuple
from decouple import Config

# stub
jwt_decompiled_stub = {
    "exp": 1678209788,
    "created_at": 1646673788.442139,
    "scope": {"view_type": "default", "user_level": "client"},
    "user": {
        "unique_id": "40db7fee-6d60-4d73-824f-1bf87edc4491",
        "nick_name": "RAST3",
        "portfolios": {
            "br": {"bovespa_account": "000000014-6", "bmf_account": "14"},
            "us": {"_": None},
        },
    },
}
jwt_data = {"CLIENT_JWT_NAME": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9"}
bank_number = "001"
response_stub = {"agency": "0001", "bank": bank_number, "account": "000000014-6"}

from src.infrastructures.env_config import config

@pytest.mark.asyncio
@patch(
    "src.services.jwt.service.jwt_validator_and_decompile",
    return_value=jwt_decompiled_stub,
)
@patch(
    "src.services.jwt.service.verify_jwt_token_by_string",
    return_value=jwt_decompiled_stub,
)
@patch("decouple.Config.__call__", return_value=bank_number)
async def test_when_sending_the_right_jwt_then_return_the_bank_account_datas_from_jwt(
    mock_config_env_return,
    mock_jwt_validator_and_decompile,
    mock_verify_jwt_token_by_string,
):
    response = await BankTransferService.get_bank_transfer_account(
        request=MagicMock(headers=MagicMock(raw=x_thebes_bank_tuple))
    )
    assert response == response_stub


import math

class entity:
	def __init__(self, xPos, yPos, xVel, yVel, eID):
		self.id = str(eID)
		self.xPos = xPos
		self.yPos = yPos
		self.xVel = xVel
		self.yVel = yVel
		self.size = 1
		self.color = {'r': 1, 'g': 1, 'b': 1}

	def updatePos(self, terminalVel, friction):
		Vel = math.sqrt(math.pow(self.xVel, 2) + math.pow(self.yVel, 2))
		if Vel > terminalVel:
			self.xVel = self.xVel * (terminalVel/Vel)
			self.yVel = self.yVel * (terminalVel/Vel)

		self.xPos = self.xPos + self.xVel
		self.yPos = self.yPos + self.yVel

		self.xVel = self.xVel * friction
		self.yVel = self.yVel * friction
		return Vel

	def updateVel(self, dx, dy):
		self.xVel = self.xVel + dx
		self.yVel = self.yVel + dy

	def testBounds(self, xBoundMin, xBoundMax, yBoundMin, yBoundMax):
		if self.xPos > (xBoundMax - self.size/2) and self.xVel > 0:
			self.xVel = -self.xVel
		elif self.xPos < (xBoundMin + self.size/2) and self.xVel < 0:
			self.xVel = -self.xVel

		if self.yPos > (yBoundMax - self.size/2) and self.yVel > 0:
			self.yVel = -self.yVel
		elif self.yPos < (yBoundMin + self.size/2) and self.yVel < 0:
			self.yVel = -self.yVel

	def package(self):
		pkg = {'id': self.id}
		pkg['x'] = self.xPos
		pkg['y'] = self.yPos
		pkg['size'] = self.size
		pkg['color'] = self.color
		return pkg


import io

from unidecode import unidecode

DEBUG = False

# ======= Configuration =======
# Path to the table with the names of those present in the call
input_path = "../resources/attendance.csv" if DEBUG else "../resources/ed2905.csv"
# Path to the table with the names of those present in the call
output_path = "../resources/names.csv" if DEBUG else "../resources/names_table.csv"
# Minimum number of occurrences to register the presence
minimum_occurrence = 2 if DEBUG else 10

# Function: Generate a set with names from an attendence table
# Parameter: path = path of the table containing the data
# Parameter: minimum_occurrence = value of minimum number of occurrences to register the presence
def proccess(input_path, minimum_occurrence):
    text = io.open(input_path, "r+", encoding="utf8")
    cont = 0
    namedict = dict()
    for line in text:
        # Ignore the first two line of the table format
        if cont >= 2:
            line = line.rstrip()
            names = line.split(";")
            for name in names:
                if len(name) != 0:
                    namedict[name] = namedict.setdefault(name, 0) + 1
        cont += 1
    nameset = set()
    for name in namedict.keys():
        if namedict[name] >= minimum_occurrence:
            nameset.add(unidecode(name.title()))
    return nameset

# Function: Generate a set with names from an attendence table
# Parameter: output_path = path of csv with the names will be saved
# Parameter: namelist = set with the names to be write
def export(output_path, nameset):
    output_file = open(output_path, "w+", encoding="utf8")
    output_file.write("Nomes\n")
    namelist = list()
    for name in nameset:
        namelist.append(name)
    namelist.sort()
    for name in namelist:
        output_file.write(name)
        output_file.write("\n")

if __name__ == "__main__":
    names = proccess(input_path, minimum_occurrence)
    export(output_path, names)


"""CIFAR dataset input module, with the majority taken from
https://github.com/tensorflow/models/tree/master/resnet.
"""

from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

import tensorflow as tf

def build_data(data_path, size, dataset):
    """Creates the queue and preprocessing operations for the dataset.

    Args:
        data_path: Filename for cifar10 data.
        size: The number of images in the dataset.
        dataset: The dataset we are using.

    Returns:
        queue: A Tensorflow queue for extracting the images and labels.
    """
    image_size = 32
    if dataset == "cifar10":
        label_bytes = 1
        label_offset = 0
    elif dataset == "cifar100":
        label_bytes = 1
        label_offset = 1
    depth = 3
    image_bytes = image_size * image_size * depth
    record_bytes = label_bytes + label_offset + image_bytes

    def load_transform(value):
        # Convert these examples to dense labels and processed images.
        record = tf.reshape(tf.decode_raw(value, tf.uint8), [record_bytes])
        label = tf.cast(tf.slice(record, [label_offset], [label_bytes]),
                        tf.int32)
        # Convert from string to [depth * height * width] to
        # [depth, height, width].
        depth_major = tf.reshape(
            tf.slice(record, [label_bytes], [image_bytes]),
            [depth, image_size, image_size])
        # Convert from [depth, height, width] to [height, width, depth].
        image = tf.cast(tf.transpose(depth_major, [1, 2, 0]), tf.float32)
        return (image, label)
    # Read examples from files in the filename queue.
    data_files = tf.gfile.Glob(data_path)
    data = tf.contrib.data.FixedLengthRecordDataset(data_files,
                                                    record_bytes=record_bytes)
    data = data.map(load_transform)
    data = data.batch(size)
    iterator = data.make_one_shot_iterator()
    return iterator.get_next()

def build_input(data, batch_size, dataset, train):
    """Build CIFAR image and labels.

    Args:
        data_path: Filename for cifar10 data.
        batch_size: Input batch size.
        train: True if we are training and false if we are testing.

    Returns:
        images: Batches of images of size
            [batch_size, image_size, image_size, 3].
        labels: Batches of labels of size [batch_size, num_classes].

    Raises:
      ValueError: When the specified dataset is not supported.
    """
    image_size = 32
    depth = 3
    num_classes = 10 if dataset == "cifar10" else 100
    images, labels = data
    num_samples = images.shape[0] - images.shape[0] % batch_size
    dataset = tf.contrib.data.Dataset.from_tensor_slices(
        (images[:num_samples], labels[:num_samples]))

    def map_train(image, label):
        image = tf.image.resize_image_with_crop_or_pad(image, image_size + 4,
                                                       image_size + 4)
        image = tf.random_crop(image, [image_size, image_size, 3])
        image = tf.image.random_flip_left_right(image)
        image = tf.image.per_image_standardization(image)
        return (image, label)

    def map_test(image, label):
        image = tf.image.resize_image_with_crop_or_pad(image, image_size,
                                                       image_size)
        image = tf.image.per_image_standardization(image)
        return (image, label)

    dataset = dataset.map(map_train if train else map_test)
    dataset = dataset.batch(batch_size)
    dataset = dataset.repeat()
    if train:
        dataset = dataset.shuffle(buffer_size=16 * batch_size)
    images, labels = dataset.make_one_shot_iterator().get_next()
    images = tf.reshape(images, [batch_size, image_size, image_size, depth])
    labels = tf.reshape(labels, [batch_size, 1])
    indices = tf.reshape(tf.range(0, batch_size, 1), [batch_size, 1])
    labels = tf.sparse_to_dense(
        tf.concat([indices, labels], 1),
        [batch_size, num_classes], 1.0, 0.0)

    assert len(images.get_shape()) == 4
    assert images.get_shape()[0] == batch_size
    assert images.get_shape()[-1] == 3
    assert len(labels.get_shape()) == 2
    assert labels.get_shape()[0] == batch_size
    assert labels.get_shape()[1] == num_classes
    if not train:
        tf.summary.image("images", images)
    return images, labels


import os
import time
from google.oauth2.credentials import Credentials
from google_auth_oauthlib.flow import InstalledAppFlow
from googleapiclient.discovery import build
from googleapiclient.errors import HttpError

CLIENT_SECRETS_FILE = os.path.join(os.path.dirname(__file__), 'service_account.json')
SCOPES = ['https://www.googleapis.com/auth/youtube.force-ssl']
CHANNEL_ID = 'UC-lHJZR3Gqxm24_Vd_AJ5Yw'

def main():
    if os.path.exists('credentials.json'):
        credentials = Credentials.from_authorized_user_file('credentials.json', scopes = SCOPES)
    else:
        flow = InstalledAppFlow.from_client_secrets_file(CLIENT_SECRETS_FILE, scopes = SCOPES)
        credentials = flow.run_local_server(port=0)
        with open('credentials.json', 'w') as token:
            token.write(credentials.to_json())

    youtube = build('youtube', 'v3', credentials=credentials)
    nextPageToken = None

    while True:
        try:
            response = youtube.commentThreads().list(
                part = "id,snippet",
                allThreadsRelatedToChannelId = CHANNEL_ID,
                maxResults = 100,
                textFormat ='plainText',
                pageToken = nextPageToken
            ).execute()
            time.sleep(3)
        except HttpError as error:
            print(f'An error occurred: {error}')
            nextPageToken = None
            time.sleep(3)

        for item in response['items']:
            try:
                comment_id = item['snippet']['topLevelComment']['id']
                print ("comment ID: " + comment_id)
                youtube.comments().delete(id = comment_id).execute()
                time.sleep(3)
            except HttpError as error:
                print(f'An error occurred: {error}')
                time.sleep(3)

        nextPageToken = response.get('nextPageToken')
        if not nextPageToken:
            break

if __name__ == '__main__':
    main()


import requests
from requests import Session
from requests.adapters import HTTPAdapter
from urllib3 import Retry
from loguru import logger
from requests import HTTPError, Response

def get_session(add: dict, headers: dict) -> Session:
    session = requests.Session()
    session.mount(
        "https://",
        HTTPAdapter(
            max_retries=Retry(
                total=3,
                status_forcelist=[429, 500, 502, 503, 504],
                allowed_methods=["GET", "HEAD"],
                backoff_factor=1,
            )
        ),
    )
    if headers is None:
        headers = {
            "Accept": "text/html",
            "Accept-Encoding": "gzip, deflate, br",
            "Accept-Language": "en-GB,en-US;q=0.9,en;q=0.8",
            "upgrade-insecure-requests": "1",
            "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) "
            "AppleWebKit/537.36 (KHTML, like Gecko) "
            "Chrome/90.0.4430.93 Safari/537.36",
        }
    if add is not None:
        headers.update(add)
    session.headers = headers
    return session

def get(
    url, description=None, stream=False, add: dict = None, headers: dict = None
) -> Response:
    session = get_session(add=add, headers=headers)
    logger.info(
        f"Fetching"
        f"{f' {description} from' if description is not None else ''} "
        f"{url}"
    )
    try:
        response = session.get(url, stream=stream)
        response.raise_for_status()
        return response
    except HTTPError as e:
        logger.error(f"HTTP error: {e}")
        return Response()
    except Exception as e:
        logger.error(f"Other error: {e}")
        return Response()

def exists(url, add: dict = None, headers: dict = None) -> bool:
    session = get_session(add=add, headers=headers)
    logger.debug(f"Checking if {url} exists")
    try:
        response = session.head(url)
        response.raise_for_status()
        if response.is_redirect:
            return False
        return response.status_code == 200
    except HTTPError as e:
        logger.error(f"HTTP error: {e}")
        return False
    except Exception as e:
        logger.error(f"Other error: {e}")
        return False


# Напишите программу, удаляющую из текста все слова, содержащие ""абв"".

# решена на семинаре, удаляются слова с задаными символами из текста
# сохранённого в txt файле

# path = "text.txt"

# data_txt = ""

# with open("text.txt", "r", encoding="utf_8") as file:
#     data_txt = file.read()
# print(data_txt)

# data_txt = data_txt.split()
# print(data_txt)

# find_txt = input("Введите текст для проверки: ")

# result_txt = []

# for word in data_txt:
#     if find_txt not in word:
#         result_txt.append(word)
# print(result_txt)

text = 'Напишите абв напиабв програбвмму программу, удаляющую из \
    этого абв текста все вабвс слова, содерабващие содержащие "абв"'

def del_some_words(text):
    text = list(filter(lambda x: "абв" not in x, text.split()))
    return " ".join(text)

text = del_some_words(text)
print(text)


def main():
    from sys import stdin
    input = stdin.readline

    # 入力を受け取る
    S = input().rstrip()

    # 処理
    # 各白石の移動した距離の総和が操作回数
    # 各白石と相対順序が入れ替わった石の数は,
    # それよりもはじめ左にあった黒石の数

    # tmp_cnt は番号 i 時点での黒石の数の総和
    tmp_cnt = 0
    # cnt は操作回数の総和
    # 白石が出てきた時点で, それより左にある黒石の数(tmp_cnt)を加算
    cnt = 0
    for s in S:
        if s == "B":
            tmp_cnt += 1
        elif s == "W":
            cnt += tmp_cnt

    # 答えを出力
    print(cnt)

if __name__ == '__main__':
    main()


import numba
import numpy as np

class VoxelGenerator(object):
    """Voxel generator in numpy implementation.
    Args:
        voxel_size (list[float]): Size of a single voxel
        point_cloud_range (list[float]): Range of points
    """
    def __init__(self,
                 voxel_size,
                 point_cloud_range):

        point_cloud_range = np.array(point_cloud_range, dtype=np.float32)
        voxel_size = np.array(voxel_size, dtype=np.float32)
        grid_size = (point_cloud_range[3:] - point_cloud_range[:3]) / voxel_size
        grid_size = np.round(grid_size).astype(np.int64)

        self._voxel_size = voxel_size
        self._point_cloud_range = point_cloud_range
        self._grid_size = grid_size

    def generate(self, points):
        """Generate voxels given points."""
        return points_to_voxel(points, self._voxel_size, self._point_cloud_range, True)

    @property
    def voxel_size(self):
        """list[float]: Size of a single voxel."""
        return self._voxel_size

    @property
    def point_cloud_range(self):
        """list[float]: Range of point cloud."""
        return self._point_cloud_range

    @property
    def grid_size(self):
        """np.ndarray: The size of grids."""
        return self._grid_size

    def __repr__(self):
        """str: Return a string that describes the module."""
        repr_str = self.__class__.__name__
        indent = ' ' * (len(repr_str) + 1)
        repr_str += f'(voxel_size={self._voxel_size},\n'
        repr_str += indent + 'point_cloud_range='
        repr_str += f'{self._point_cloud_range.tolist()},\n'
        repr_str += indent + f'grid_size={self._grid_size.tolist()}'
        repr_str += ')'
        return repr_str

def points_to_voxel(points,
                    voxel_size,
                    coors_range,
                    reverse_index=True):
    """convert kitti points(N, >=3) to voxels.
    Args:
        points (np.ndarray): [N, ndim]. points[:, :3] contain xyz points and
            points[:, 3:] contain other information such as reflectivity.
        voxel_size (list, tuple, np.ndarray): [3] xyz, indicate voxel size
        coors_range (list[float | tuple[float] | ndarray]): Voxel range.
            format: xyzxyz, minmax
        reverse_index (bool): Whether return reversed coordinates.
            if points has xyz format and reverse_index is True, output
            coordinates will be zyx format, but points in features always
            xyz format.
    Returns:
        tuple[np.ndarray]:
            coordinates: [M, 3] int32 tensor.
            point_voxel_ids: [N] int32 tensor.
    """
    if not isinstance(voxel_size, np.ndarray):
        voxel_size = np.array(voxel_size, dtype=points.dtype)
    if not isinstance(coors_range, np.ndarray):
        coors_range = np.array(coors_range, dtype=points.dtype)
    voxelmap_shape = (coors_range[3:] - coors_range[:3]) / voxel_size
    voxelmap_shape = tuple(np.round(voxelmap_shape).astype(np.int32).tolist())
    if reverse_index:
        voxelmap_shape = voxelmap_shape[::-1]
    coor_to_voxelidx = -np.ones(shape=voxelmap_shape, dtype=np.int32)
    coors = np.zeros(shape=(np.prod(voxelmap_shape), 3), dtype=np.int32)
    point_voxel_ids = -np.ones(shape=(points.shape[0]), dtype=np.int32)
    if reverse_index:
        voxel_num = _points_to_voxel_reverse_kernel(points, voxel_size, coors_range, coor_to_voxelidx,
                                                    coors, point_voxel_ids)

    else:
        voxel_num = _points_to_voxel_kernel(points, voxel_size, coors_range, coor_to_voxelidx,
                                            coors, point_voxel_ids)

    coors = coors[:voxel_num]
    return coors, point_voxel_ids

@numba.jit(nopython=True)
def _points_to_voxel_reverse_kernel(points,
                                    voxel_size,
                                    coors_range,
                                    coor_to_voxelidx,
                                    coors,
                                    point_voxel_ids):
    """convert kitti points(N, >=3) to voxels.
    Args:
        points (np.ndarray): [N, ndim]. points[:, :3] contain xyz points and
            points[:, 3:] contain other information such as reflectivity.
        voxel_size (list, tuple, np.ndarray): [3] xyz, indicate voxel size
        coors_range (list[float | tuple[float] | ndarray]): Range of voxels.
            format: xyzxyz, minmax
        coor_to_voxelidx (np.ndarray): A voxel grid of shape (D, H, W),
            which has the same shape as the complete voxel map. It indicates
            the index of each corresponding voxel.
        coors (np.ndarray): Created coordinates of each voxel.
        point_voxel_ids (np.ndarray):  Created voxel index of each point.
    Returns:
        tuple[np.ndarray]:
            coordinates: Shape [M, 3].
            point_voxel_ids: Shape [N].
    """
    # put all computations to one loop.
    # we shouldn't create large array in main jit code, otherwise
    # reduce performance
    N = points.shape[0]
    # ndim = points.shape[1] - 1
    ndim = 3
    ndim_minus_1 = ndim - 1
    grid_size = (coors_range[3:] - coors_range[:3]) / voxel_size
    # np.round(grid_size)
    # grid_size = np.round(grid_size).astype(np.int64)(np.int32)
    grid_size = np.round(grid_size, 0, grid_size).astype(np.int32)
    coor = np.zeros(shape=(3, ), dtype=np.int32)
    voxel_num = 0
    failed = False
    for i in range(N):
        failed = False
        for j in range(ndim):
            c = np.floor((points[i, j] - coors_range[j]) / voxel_size[j])
            if c < 0 or c >= grid_size[j]:
                failed = True
                break
            coor[ndim_minus_1 - j] = c
        if failed:
            continue
        voxelidx = coor_to_voxelidx[coor[0], coor[1], coor[2]]
        if voxelidx == -1:
            voxelidx = voxel_num
            voxel_num += 1
            coor_to_voxelidx[coor[0], coor[1], coor[2]] = voxelidx
            coors[voxelidx] = coor
        point_voxel_ids[i] = voxelidx
    return voxel_num

@numba.jit(nopython=True)
def _points_to_voxel_kernel(points,
                            voxel_size,
                            coors_range,
                            coor_to_voxelidx,
                            coors,
                            point_voxel_ids):
    """convert kitti points(N, >=3) to voxels.
    Args:
        points (np.ndarray): [N, ndim]. points[:, :3] contain xyz points and
            points[:, 3:] contain other information such as reflectivity.
        voxel_size (list, tuple, np.ndarray): [3] xyz, indicate voxel size.
        coors_range (list[float | tuple[float] | ndarray]): Range of voxels.
            format: xyzxyz, minmax
        coor_to_voxelidx (np.ndarray): A voxel grid of shape (D, H, W),
            which has the same shape as the complete voxel map. It indicates
            the index of each corresponding voxel.
        coors (np.ndarray): Created coordinates of each voxel.
        point_voxel_ids (np.ndarray):  Created voxel index of each point.
    Returns:
        tuple[np.ndarray]:
            coordinates: Shape [M, 3].
            point_voxel_ids: Shape [N].
    """
    N = points.shape[0]
    # ndim = points.shape[1] - 1
    ndim = 3
    grid_size = (coors_range[3:] - coors_range[:3]) / voxel_size
    # grid_size = np.round(grid_size).astype(np.int64)(np.int32)
    grid_size = np.round(grid_size, 0, grid_size).astype(np.int32)

    # lower_bound = coors_range[:3]
    # upper_bound = coors_range[3:]
    coor = np.zeros(shape=(3, ), dtype=np.int32)
    voxel_num = 0
    failed = False
    for i in range(N):
        failed = False
        for j in range(ndim):
            c = np.floor((points[i, j] - coors_range[j]) / voxel_size[j])
            if c < 0 or c >= grid_size[j]:
                failed = True
                break
            coor[j] = c
        if failed:
            continue
        voxelidx = coor_to_voxelidx[coor[0], coor[1], coor[2]]
        if voxelidx == -1:
            voxelidx = voxel_num
            voxel_num += 1
            coor_to_voxelidx[coor[0], coor[1], coor[2]] = voxelidx
            coors[voxelidx] = coor
        point_voxel_ids[i] = voxelidx
    return voxel_num