def notas():
    while True:
        nome1 = input("Informe o nome do 1 participante: ")
        nota1 = float(input("Informe a nota do 1 participante: "))
        if not nota1 >= 0 or not nota1 <= 10:
            print("Valor invalido.")
            break

        nome2 = input("Informe o nome do 2 participante: ")
        nota2 = float(input("Informe a nota do 2 participante: "))
        if not nota2 >= 0 or not nota2 <= 10:
            print("Valor invalido.")
            break

        nome3 = input("Informe o nome do 3 participante: ")
        nota3 = float(input("Informe a nota do 3 participante: "))
        if not nota3 >= 0 or not nota3 <= 10:
            print("Valor invalido.")
            break

        nome4 = input("Informe o nome do 4 participante: ")
        nota4 = float(input("Informe a nota do 4 participante: "))
        if not nota4 >= 0 or not nota4 <= 10:
            print("Valor invalido.")
            break

        nome5 = input("Informe o nome do 5 participante: ")
        nota5 = float(input("Informe a nota do 5 participante: "))
        if not nota5 >= 0 or not nota5 <= 10:
            print("Valor invalido.")
            break

        notas = [nota1,nota2,nota3,nota4,nota5]
        notas.sort(reverse=True)
        notaVencedor = notas[0]

        participantes = {
            nome1: nota1,
            nome2: nota2,
            nome3: nota3,
            nome4: nota4,
            nome5: nota5
            }

        nomes = list(participantes.keys())
        notas = list(participantes.values())

        posicaoVencedor = notas.index(notaVencedor)
        vencedor = nomes[posicaoVencedor]

        print(f"\nO(a) vencedor(a) foi {vencedor} com nota {notaVencedor}!\n")
        if input("Digite 's' para sair ou enter para comecar de novo: ") == "s":
            break
notas()


import tensorflow as tf

"""功能：计算Hurwitz zeta函数。
输入：x为张量或稀疏张量，可以为`float32`, `float64`类型。"""

a = tf.constant(1, tf.float64)
x = tf.constant([[1, 2, 3, 4]], tf.float64)
z = tf.zeta(x, a)
sess = tf.Session()
print(sess.run(z))
sess.close()
# [[        inf  1.64493407  1.2020569   1.08232323]]


# -*- coding: utf-8 -*-
import tensorflow as tf

'''
这个例子是用来告诉大家如何初始化session，以及使用的，相当于python的file handle方式
同时tf之中的每一个操作都必须通过session 来 run

'''

matrix1 = tf.constant([[3,3]])
matrix2 = tf.constant([[2],[2]])

product = tf.matmul(matrix1,matrix2) #matrix multiply np.dot(m1,m2)

#method 1
# sess = tf.Session()
# result =sess.run(product)
# print(result)
# sess.close()

#method 2,with synax can help you close session convient
with tf.Session() as sess:
    result2 = sess.run(product)
    print(result2)


# %% Inputs
import os
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
import warnings
import seaborn as sns
warnings.filterwarnings('ignore')

# import classes
os.chdir('C:\\Users\\Ana\\Documents\\PhD\\Dev\\miniscope_analysis')
import miniscope_session_class
import locomotion_class

path_session_data = 'J:\\Miniscope processed files'
session_data = pd.read_excel('J:\\Miniscope processed files\\session_data_split_S2.xlsx')
save_path = 'J:\\test\\'

save_plot = 0
plot_data = 1
window = np.arange(-330, 330 + 1)  # Samples
interval = [-165, 0]  # Samples (-0.5s to 0.25s)
zs_data = True  # True if you want to standardize observed data on shuffled data
iter_n = 100  # Number of iterations of CS timestamps random shuffling

# for s in range(1, len(session_data)):
s=3
ses_info = session_data.iloc[s, :]
print(ses_info)
date = ses_info[3]
# path inputs
path = os.path.join(path_session_data, 'TM RAW FILES', ses_info[0], ses_info[1], date + '\\')
path_loco = os.path.join(path_session_data, 'TM TRACKING FILES',
                         ses_info[0] + ' ' + ses_info[2] + ' ' + date.split('_')[-1] + date.split('_')[-2] +
                         date.split('_')[-3][2:] + '\\')
session_type = path.split('\\')[-4].split(' ')[0]
session_id = session_type + '_' + ses_info[2]
mscope = miniscope_session_class.miniscope_session(path)
loco = locomotion_class.loco_class(path_loco)
import df_behav_class

nxb = df_behav_class.df_behav_analysis('C:\\Users\\Ana\\Documents\\PhD\\Dev\\miniscope_analysis')

# Session data and inputs
animal = mscope.get_animal_id()
session = loco.get_session_id()
[df_extract, df_events_extract, df_extract_rawtrace, df_extract_rawtrace_detrended, df_events_extract_rawtrace,
 coord_ext, reg_th, reg_bad_frames, trials,
 clusters_rois, colors_cluster, colors_session, idx_roi_cluster_ordered, ref_image,
 frames_dFF] = mscope.load_processed_files()
[trigger_nr, strobe_nr, frames_loco, trial_start, bcam_time] = loco.get_tdms_frame_start(animal, session,
                                                                                frames_dFF)
[trials_ses, trials_ses_name, cond_plot, trials_baseline, trials_split, trials_washout] = mscope.get_session_data(
    trials, session_type, animal, session)
centroid_ext = mscope.get_roi_centroids(coord_ext)

# Load behavioral data
filelist = loco.get_track_files(animal, session)
param_name = 'step_length'
p = 'FR'
p2 = 'FL'
st_strides_trials = []
sw_strides_trials = []
final_tracks_trials = []
param_trials = []
param_trials_fr_mean = np.zeros(len(trials))
stride_duration_trials = []
final_tracks_forwadloco_trials = []
for count_trial, f in enumerate(filelist):
    [final_tracks, tracks_tail, joints_wrist, joints_elbow, ear, bodycenter] = loco.read_h5(f, 0.9, int(
        frames_loco[count_trial]))
    [st_strides_mat, sw_pts_mat] = loco.get_sw_st_matrices(final_tracks, 1)
    paws_rel = loco.get_paws_rel(final_tracks, 'X')
    final_tracks_forwadloco = loco.final_tracks_forwardlocomotion(final_tracks, st_strides_mat)
    final_tracks_forwadloco_trials.append(final_tracks_forwadloco)
    final_tracks_trials.append(final_tracks)
    st_strides_trials.append(st_strides_mat)
    sw_strides_trials.append(sw_pts_mat)
    param_trials.append(
        loco.compute_gait_param(bodycenter, final_tracks, paws_rel, st_strides_mat, sw_pts_mat, param_name))
    param_trials_fr_mean[count_trial] = np.nanmean(param_trials[-1][0]) - np.nanmean(param_trials[-1][2])
final_tracks_trials_phase = loco.final_tracks_phase(final_tracks_trials, trials, st_strides_trials,
                                                    sw_strides_trials, 'st-st')
[sl_idx_all, sl_time_all_array, sl_sym_all_array] = loco.param_continuous_sym(param_trials, st_strides_trials,
                                                                              trials, p, p2, sym=1,
                                                                              remove_nan=1)  # SL symmetry for each stride

# Get kinematic variables (body position, speed, acceleration)
bodycenter, bodyspeed, bodyacc = nxb.body_kinematic(final_tracks_trials, trials, win_len=81, polyorder=3)

# Get phase and displacement difference
displ_diff_contra = nxb.paw_diff(final_tracks_trials, 0, 3)
displ_diff_ipsi = nxb.paw_diff(final_tracks_trials, 0, 1)

# Dictionary of all the indipendent variables on which computing the STA
# ind_vars = {'FR-HL displacement difference': displ_diff_contra, 'FR-HR displacement difference': displ_diff_ipsi,
#             'Body position': bodycenter, 'Body speed': bodyspeed, 'Body acceleration': bodyacc}
ind_vars = {'Body position': bodycenter, 'Body speed': bodyspeed, 'Body acceleration': bodyacc}
keys = list(ind_vars.keys())

# Loop through independent variables to compute and plot STAs of each one
for var in range(len(ind_vars)):
    var_name = keys[var]
    variable = ind_vars[var_name]

    # Compute spike-triggered average (STA) of kinematic variables
    df_events, cluster_transition_idx = nxb.sort_rois_clust(df_events_extract_rawtrace,
                                                            clusters_rois)  # Sort ROIs by cluster
    sta_allrois, signal_chunks_allrois = nxb.sta(df_events, variable, bcam_time, window, trials)
    # Sort ROIs
    rois_sorted = []
    for i in range(len(clusters_rois)):  # flatten 'clusters_rois'
        rois_sorted = np.hstack((rois_sorted, clusters_rois[i]))
    # Sub-divide experimental blocks
    if session_type == 'split':
        split_blocks = nxb.split_expblocks(trials_ses)
    else:
        split_blocks = trials_ses

    # Standardize observed STA on STA computed with shuffled data
    if zs_data:
        # Shuffle CS timestamps
        shuffled_spikes_ts = nxb.shuffle_spikes_ts(df_events_extract_rawtrace, iter_n)
        # Compute STA for shuffled data
        sta_shuffled_ts = np.array(nxb.sta_shuffled(shuffled_spikes_ts, variable, bcam_time, window, trials))
        # Standardize STA
        mean_chance = np.nanmean(sta_shuffled_ts, axis=2)
        sd_chance = np.nanstd(sta_shuffled_ts, axis=2)
        sta_zs = np.zeros((len(sta_allrois), len(trials), len(window)))
        for n in range(len(sta_allrois)):
            for tr in range(len(trials)):
                sta_zs[n, tr] = (sta_allrois[n][tr] - mean_chance[n][tr]) / sd_chance[n][tr]

    # Define font size for plot labels
    font_size = 15

    # Define colorcode for experimental blocks
    color_blocks = []
    for b in split_blocks:
        color_blocks.append(colors_session[b[0] + 1])

    # Re-sort data to have a list of the STA of all the ROIs for each trial
    sta_tr_allrois = [[sta_roi[tr_idx] for sta_roi in sta_zs] for tr_idx, _ in
                      enumerate(trials)]  # List of the STA of all the ROIs for each trial

    # Compute STA of all the ROIs for each block
    sta_blocks_allrois = [np.nanmean(np.array(sta_tr_allrois[start:end]), axis=0) for start, end in
                          split_blocks]  # List of the STA of all the ROIs for block

    # Define tick labels for plots
    x_tick_values = [round(window[0] / nxb.sr_cam, 1), round((1 / 2) * window[0] / nxb.sr_cam, 1), 0,
                     round((1 / 2) * window[-1] / nxb.sr_cam, 1), round(window[-1] / nxb.sr_cam, 1)]
    x_ticks = np.linspace(0, len(sta_tr_allrois[0][0]), len(x_tick_values)).astype(int)

    # Plot 1: Heatmap STA of the population by trial
    max_val = np.nanmax(np.concatenate(sta_tr_allrois, axis=0))
    min_val = np.nanmin(np.concatenate(sta_tr_allrois, axis=0))
    for tr_idx, tr in enumerate(trials):  # WARNING: for tr in range(len(trial_changes)-1):
        plt.figure()
        hm = sns.heatmap(sta_tr_allrois[tr_idx], cmap='viridis', vmin = min_val, vmax = max_val)  # heatmap STA whole population by trial
        plt.ylabel('ROIs', fontsize=font_size)
        plt.xlabel('Time (s)', fontsize=font_size)
        cbar = hm.collections[0].colorbar
        cbar.set_label(var_name + ' (z-score)', fontsize=font_size)
        plt.axvline(x=window[-1], color='white', linestyle='--')
        plt.yticks([])
        plt.tick_params(left=False)
        plt.xticks(x_ticks, [f"{tick}" for tick in x_tick_values])
        plt.title('STA ' + var_name + ' trial ' + str(tr), fontsize=font_size)
        plt.savefig(save_path+'STA_'+var_name+'_trial'+str(tr))
        plt.close('all')

    # Plot 2: STA traces of one cluster across trials
    max_val = np.nanmax(np.concatenate(sta_tr_allrois, axis=0))
    min_val = np.nanmin(np.concatenate(sta_tr_allrois, axis=0))
    clust_sta_tr = np.zeros(
        (len(sta_tr_allrois), len(cluster_transition_idx), len(window)))  # STA of clusters by block
    for tr_idx, trial in enumerate(sta_tr_allrois):
        start = 0
        for clust_idx, clust_end in enumerate(cluster_transition_idx):
            if len(cluster_transition_idx) - 1 == clust_idx:
                end = len(sta_tr_allrois[0])
            else:
                end = clust_end
            clust_sta_tr[tr_idx, clust_idx] = np.mean(trial[start:end], axis=0)
            start = clust_end
    fig, axs = plt.subplots(nrows=1, ncols=len(cluster_transition_idx), figsize=(15, 5))
    if len(cluster_transition_idx) == 1:
        axs = [axs]  # Convert single axis to a list for indexing consistency
    for clust_idx, _ in enumerate(cluster_transition_idx):
        for tr in trials_ses.flatten():
            trial_idx = np.where(tr == trials)[0][0]
            current_ax = axs[clust_idx]  # Get the current axis
            current_ax.plot(window * 1 / nxb.sr_cam, clust_sta_tr[trial_idx, clust_idx], c=colors_session[tr],
                            linewidth=2)
        current_ax.axvline(x=0, color='black', linestyle='--')
        current_ax.spines['right'].set_visible(False)
        current_ax.spines['top'].set_visible(False)
        current_ax.set_ylim([min_val, max_val])
        current_ax.set_xlim(window[0] * 1 / nxb.sr_cam, window[-1] * 1 / nxb.sr_cam)
        current_ax.set_xlim(window[0] * 1 / nxb.sr_cam, window[-1] * 1 / nxb.sr_cam)
        current_ax.set_xlabel('Time around event (s)', fontsize=font_size)
        if clust_idx == 0:
            current_ax.set_ylabel(var_name + ' (z-score)', fontsize=font_size)
        if clust_idx > 0:
            current_ax.set(yticklabels=[])
            current_ax.tick_params(left=False)
            current_ax.spines['left'].set_visible(False)
        current_ax.set_title('Cluster ' + str(clust_idx + 1), fontsize=font_size, c=colors_cluster[clust_idx])
    plt.savefig(save_path+'STA_zs_'+var_name+'_clusters_trials')

    # Plot 3: Heatmap STA of the population by block
    max_val = np.nanmax(np.concatenate(sta_blocks_allrois, axis=0))
    min_val = np.nanmin(np.concatenate(sta_blocks_allrois, axis=0))
    fig, axs = plt.subplots(len(sta_blocks_allrois), 1, figsize=(12, 12))
    for b in range(len(sta_blocks_allrois)):
        hm = sns.heatmap(sta_blocks_allrois[b], cmap='viridis', ax=axs[b], vmin = min_val, vmax = max_val)  # heatmap STA whole population by block
        axs[b].axvline(x=window[-1], color='white', linestyle='--')
        axs[b].set_ylabel('ROIs', fontsize=font_size)
        axs[b].set(xticklabels=[])
        axs[b].set(yticklabels=[])
        if b < len(sta_blocks_allrois) - 1:
            axs[b].tick_params(left=False, bottom=False)
        if b == int((len(sta_blocks_allrois) - 1) / 2):
            cbar = hm.collections[0].colorbar
            cbar.set_label(var_name + ' (z-score)', fontsize=font_size)
        plt.xlabel('Time (s)', fontsize=font_size)
        plt.axvline(x=window[-1], color='white', linestyle='--')
        plt.yticks([])
        plt.tick_params(left=False)
        plt.xticks(x_ticks, [f"{tick}" for tick in x_tick_values], fontsize=12)
        fig.suptitle('STA ' + var_name, fontsize=font_size)
        for c in cluster_transition_idx:  # Mark clusters in the heatmap
            axs[b].hlines(c + 1, *axs[b].get_xlim(), color='white', linestyle='dashed', linewidth=0.5)
    plt.savefig(save_path+'STA_zs_'+var_name+'_blocks')

    # Plot 4: STA traces of one cluster across blocks
    clust_sta = np.zeros(
        (len(sta_blocks_allrois), len(cluster_transition_idx), len(window)))  # STA of clusters by block
    for block_idx, block in enumerate(sta_blocks_allrois):
        start = 0
        for clust_idx, clust_end in enumerate(cluster_transition_idx):
            if len(cluster_transition_idx) - 1 == clust_idx:
                end = len(sta_blocks_allrois[0])
            else:
                end = clust_end
            clust_sta[block_idx, clust_idx] = np.mean(block[start:end], axis=0)
            start = clust_end
    fig, axs = plt.subplots(nrows=1, ncols=len(cluster_transition_idx), figsize=(15, 5))
    if len(cluster_transition_idx) == 1:
        axs = [axs]  # Convert single axis to a list for indexing consistency
    for clust_idx, _ in enumerate(cluster_transition_idx):
        for block_idx, _ in enumerate(sta_blocks_allrois):
            current_ax = axs[clust_idx]  # Get the current axis
            current_ax.plot(window * 1 / nxb.sr_cam, clust_sta[block_idx, clust_idx], c=color_blocks[block_idx],
                            linewidth=2)
        current_ax.axvline(x=0, color='black', linestyle='--')
        current_ax.spines['right'].set_visible(False)
        current_ax.spines['top'].set_visible(False)
        current_ax.set_ylim([min_val, max_val])
        current_ax.set_xlim(window[0] * 1 / nxb.sr_cam, window[-1] * 1 / nxb.sr_cam)
        current_ax.set_xlim(window[0] * 1 / nxb.sr_cam, window[-1] * 1 / nxb.sr_cam)
        current_ax.set_xlabel('Time around event (s)', fontsize=font_size)
        if clust_idx == 0:
            current_ax.set_ylabel(var_name + ' (z-score)', fontsize=font_size)
        if clust_idx > 0:
            current_ax.set(yticklabels=[])
            current_ax.tick_params(left=False)
            current_ax.spines['left'].set_visible(False)
        current_ax.set_title('Cluster ' + str(clust_idx + 1), fontsize=font_size, c=colors_cluster[clust_idx])
    plt.savefig(save_path+'STA_zs_'+var_name+'_clusters_blocks')
    plt.close('all')


import os
import numpy as np
import pandas as pd
import matplotlib
import matplotlib.pyplot as plt

plt.style.use('ggplot')
stats = ['agrigentomandrascava', 'alia', 'augusta', 'bivona', 'calascibetta',
    'caltagirone', 'caltanissetta', 'canicatti',
    'catania', 'cesarovignazza', 'contessaentellina', 'enna', 'francofonte',
    'lascari', 'leni', 'marsala', 'messina', 'mineo', 'modica',
    'monrealebifarera', 'monrealevignaapi', 'mussomeli', 'palazzoloacreide',
    'palermo', 'paterno', 'pedara', 'pettineo', 'polizzigenerosa', 'ragusa',
    'ramaccagiumarra', 'riesi', 'scicli', 'siracusa', 'trapanifontanasalsa']
s = {}
l = []
h = []
for i in range(2009,2022):
	if i == 2009:
		stats = ['messina','trapanifontanasalsa','pettineo','palermo','pedara'
		]
	elif i == 2010:
		stats = []
	elif i == 2011:
		stats = ['modica','siracusa','palazzoloacreide']
	elif i == 2012:
		stats = ['paterno','palazzoloacreide']
	elif i == 2013:
		stats = ['messina','leni','catania','ramaccagiumarra','pettineo','paterno']
	elif i == 2014:
		stats = []
	elif i == 2015:
		stats = ['agrigentomandrascava','canicatti', 'alia',
		'caltagirone','mussomeli','calascibetta','messina','leni','monrealebifarera',
		'mineo','ramaccagiumarra','ragusa','pettineo', 'pedara','paterno','marsala',
		'enna','riesi']
	elif i == 2016:
		stats = ['augusta']
	elif i == 2017:
		stats = []
	elif i == 2018:
		stats = ['canicatti','caltanissetta','calascibetta','bivona','alia',
		'mussomeli','monrealevignaapi','monrealebifarera','mineo',
		'leni','lascari','enna','contessaentellina','cesarovignazza',
		'trapanifontanasalsa','scicli','ramaccagiumarra','polizzigenerosa']
	elif i == 2019:
		stats = ['caltagirone','siracusa','scicli','ragusa','palazzoloacreide']
	elif i == 2020:
		stats = ['mineo','catania','palermo']
	elif i == 2021:
		stats = ['monrealevignaapi','mineo','lascari','contessaentellina','catania',
		'siracusa', 'paterno']
	s[i] = []
	l.append(int(i))
	if stats == []:
		h.append(0)
	else:
		for stat in stats:
			df = pd.read_excel('../excel_recap/mestations.xlsx', sheet_name=stat)
			df.rename(columns={'Unnamed: 0': 'years'}, inplace=True)
			s[i].append(df['heavy rain (%)'][int(i)-2009])
		h.append(np.mean(s[i]))
x_axis = np.arange(len(l))
ns = [int(5),int(0),int(3),int(2),int(6),int(0),int(18),int(1),int(0),int(18),int(5),int(3),int(7)]
width = 0.35
fig, ax = plt.subplots()
rects1 = ax.bar(x_axis, ns, width, tick_label=l, label = 'number of anomalies by year', color = 'orangered')
ax2 = ax.twinx()
rects2 = ax2.bar(x_axis + width, h, width, tick_label=l, label = 'heavy rain mean (%)', color ='steelblue')
ax.set_title('')
ax.tick_params(axis='x', which='both', labelsize=17, labelrotation=90)
ax.tick_params(axis='y', which='both', labelsize=17)
ax2.tick_params(axis='y', which='both', labelsize=17)
ax.set_ylim(0,20)
ax2.set_ylim(0,8)
ax.set_ylabel(r'counter')
ax2.set_ylabel(r'heavy rain (%)')
rects = [rects1, rects2]
labs = [l.get_label() for l in rects]
ax.legend(rects, labs, loc = 2, prop={'size': 17}, bbox_to_anchor=(0.0001, 1.33))
fig.tight_layout()
plt.savefig('results/final_b.pdf')


# -*- coding: utf-8 -*-
"""
edX - MIT - Introduction to Computer Science and Programming
Quiz - Problem 6
Python 2.7

Write a recursive Python function, given a non-negative integer N,
to count and return the number of occurrences of the digit 7 in N.

For example:
count7(717) -> 2
count7(1237123) -> 1
count7(8989) -> 0

Hint: Mod (%) by 10 gives you the rightmost digit (126 % 10 is 6),
while doing integer division by 10 removes the rightmost digit (126 / 10 is 12).

This function has to be recursive; you may not use loops!
This function takes in one integer and returns one integer.

"""

#%% Function

def count7(N):
    ''' Count the number of 7's in N

    Args:
        N: a non-negative integer

    Returns:
        int: count of 7

    '''

    if N == 0:
        return 0

    if N%10 == 7:
        return 1 + count7(N//10)

    else:
        return count7(N//10)

#%% Test

print(count7(717))
print(count7(1237123))
print(count7(8989))


import torch
import random

# This files shows how to build a neural network using pytorch to learn the
# XOR operation

# Function to learn
def xor(a, b):
    if a == 1 and b == 1:
        return 0
    elif a == 0 and b == 0:
        return 0
    else:
        return 1

# Torch model
model = torch.nn.Sequential(
    torch.nn.Linear(2, 10),
    torch.nn.ReLU(),
    torch.nn.Linear(10, 1)
)

# Parameters
loss_fn = torch.nn.MSELoss()
learning_rate = 1e-2
optimizer = torch.optim.Adam(model.parameters(), lr=learning_rate)

score = 0

steps = 1000
params = {
    'steps': 1000,
    'evaluated_steps': 250
}

for step in range(params['steps']):
    a = random.randint(0, 1)
    b = random.randint(0, 1)
    x = torch.Tensor([a, b])

    y_pred = model(x)
    y = xor(a, b)

    yp = torch.Tensor([y])
    loss = loss_fn(y_pred, yp)

    optimizer.zero_grad()
    loss.backward()
    optimizer.step()

    # Evaluation
    if step >= params['steps'] - params['evaluated_steps']:
        if y == 0 and y_pred.item() < 0.5:
            score = score + 1
        if y == 1 and y_pred.item() >= 0.5:
            score = score + 1

print("Score : " + str(score) + " / " + str(params['evaluated_steps']))


#!/usr/bin/env python3
"""AOC 2021: day 19

This does it mostly brute force, by running out lots of states and finding the best.

A better solution would figure out the recurrence relation and compute what is possible.
"""

import heapq

from tools import aoc
import expectations

class Blueprint(object):

  def __init__(self, id):
    self.id = id

  def __str__(self):
    return 'bp %2d: ore=%d, clay=%d os=%2d,%2d geode=%2d,%2d' % (
        self.id, self.ore_ore, self.clay_ore, self.obs_ore, self.obs_clay, self.geode_ore, self.geode_obs)

  @staticmethod
  def from_str(s):
    parts = s.split(':')
    id = int(parts[0][10:])
    ret = Blueprint(id)
    robots = parts[1].strip().split('.')
    # Blueprint 1: Each ore robot costs 4 ore.  Each clay robot costs 2 ore.  Each obsidian robot costs 3 ore and 14 clay.  Each geode robot costs 2 ore and 7 obsidian.
    ret.ore_ore = int(robots[0].strip().split(' ')[4])
    ret.clay_ore = int(robots[1].strip().split(' ')[4])
    ret.obs_ore = int(robots[2].strip().split(' ')[4])
    ret.obs_clay = int(robots[2].strip().split(' ')[7])
    ret.geode_ore = int(robots[3].strip().split(' ')[4])
    ret.geode_obs = int(robots[3].strip().split(' ')[7])
    return ret

class State(object):

  fuzzy_hash = True

  def __init__(self, clone=None):
    self.future_ore = 0
    self.future_clay = 0
    self.future_obs = 0
    if clone:
      self.minute = clone.minute
      self.n_ore = clone.n_ore
      self.n_clay = clone.n_clay
      self.n_obs = clone.n_obs
      self.n_geode = clone.n_geode
      self.bot_ore = clone.bot_ore
      self.bot_clay = clone.bot_clay
      self.bot_obs = clone.bot_obs
      self.bot_geode = clone.bot_geode
      return

    self.minute = 0
    self.n_ore = 0
    self.n_clay = 0
    self.n_obs = 0
    self.n_geode = 0
    self.bot_ore = 1
    self.bot_clay = 0
    self.bot_obs = 0
    self.bot_geode = 0

  def __hash__(self):
    if State.fuzzy_hash:
      ret = ((min(self.n_ore, 1500) * 23 + min(self.n_clay, 1500)) * 37 + self.n_obs) * 37 + self.n_geode
    else:
      ret = (((self.minute * 37 + self.n_ore) * 23 + self.n_clay) * 37 + self.n_obs) * 37 + self.n_geode
    ret = (((        ret * 37 + self.bot_ore) *23 + self.bot_clay) * 37 + self.bot_obs) * 37 + self.bot_geode
    return ret

  def __eq__(self, other):
    if State.fuzzy_hash:
      if(min(self.n_ore, 1500) != min(other.n_ore, 1500)
         or min(self.n_clay, 1500) != min(other.n_clay, 1500)):
        return False
    else:
      if (self.n_ore != other.n_ore) or (self.n_clay != other.n_clay):
        return False
    return (
        self.n_obs == other.n_obs
        and self.n_geode == other.n_geode
        and self.bot_ore == other.bot_ore
        and self.bot_clay == other.bot_clay
        and self.bot_obs == other.bot_obs
        and self.bot_geode == other.bot_geode
        )

  def __lt__(self, other):
    v = self.n_geode - other.n_geode
    if v < 0:
      return True
    if v != 0:
      return False
    v = self.bot_geode - other.bot_geode
    if v < 0:
      return True
    if v != 0:
      return False
    v = self.n_obs - other.n_obs
    if v < 0:
      return True
    if v != 0:
      return False
    v = self.bot_obs - other.bot_obs
    if v < 0:
      return True
    if v != 0:
      return False
    v = self.n_clay - other.n_clay
    if v < 0:
      return True
    if v != 0:
      return False
    v = self.bot_clay - other.bot_clay
    if v < 0:
      return True
    if v != 0:
      return False
    v = self.n_ore - other.n_ore
    if v < 0:
      return True
    if v != 0:
      return False
    v = self.bot_ore - other.bot_ore
    if v < 0:
      return True
    if v != 0:
      return False
    if self.minute < other.minute:
      return True
    return False

  def __str__(self):
    return ', '.join([
        'min: %d' % self.minute,
        'ore: %d' % self.n_ore,
        'clay: %d' % self.n_clay,
        'obsidian: %d' % self.n_obs,
        'geode: %d' % self.n_geode,
        'bot_ore: %d' % self.bot_ore,
        'bot_clay: %d' % self.bot_clay,
        'bot_obs: %d' % self.bot_obs,
        'bot_geode: %d' % self.bot_geode,
        'f_ore: %d' % self.future_ore,
        'f_clay: %d' % self.future_clay,
        ])

  def mine(self, trace=False):
    # Do the mining
    if trace:
      print('Mining:', self)
    self.n_ore += self.bot_ore
    self.n_clay += self.bot_clay
    self.n_obs += self.bot_obs
    self.n_geode += self.bot_geode
    if trace:
      print('   =>', self)

  def can_make_ore_bot(self, bp):
    return self.n_ore >= bp.ore_ore

  def can_make_clay_bot(self, bp):
    return self.n_ore >= bp.clay_ore

  def can_make_obs_bot(self, bp):
    return self.n_ore >= bp.obs_ore and self.n_clay >= bp.obs_clay

  def can_make_geode_bot(self, bp):
    return self.n_ore >= bp.geode_ore and self.n_obs >= bp.geode_obs

class day19(aoc.aoc):

  def __init__(self):
    super(day19, self).__init__(
        reader_params={
            'by_group': False,
            'skip_first_blank': True,
            'strip_lines': True,
            'verbose': False,
        })
    self.trace = True
    self.blueprints = []
    self.max_minute = 24
    self.use_scores = True

  def do_line(self, line):
    # called for each line of input
    blueprint = Blueprint.from_str(line)
    print(blueprint)
    self.blueprints.append(blueprint)

  def post_load(self):
    # called after all input is read
    for ore_rate in range(1, 6):
      n_ore = 1
      tot = 0
      to_build = 0
      for m in range(1, 25):
        # buy more
        while tot > 0 and tot % ore_rate == 0:
          tot -= ore_rate
          to_build += 1
        tot += n_ore
        # now fully made
        n_ore += to_build
      print('Max ore for', ore_rate, 'is', tot)

    for bp in self.blueprints:
      # need per geode
      need_clay = bp.geode_obs * bp.obs_clay
      need_ore = bp.geode_ore + need_clay * bp.clay_ore
      print('blueprint', bp.id, 'ore/geode:', need_ore)

  def part1(self):
    print('===== Start part 1')

    expect = expectations.EXPECT_SAMPLE_1 if self.doing_sample else expectations.EXPECT_1
    ret = 0
    start_here = 0
    if not self.doing_sample:
      start_here = 10
    for bp in self.blueprints[start_here:]:
      bp.max_g = 0
      print('>>>blueprint', bp.id, 'start')
      self.do_blueprint(bp)
      print('>>>blueprint', bp.id, 'max g', bp.max_g)
      if bp.max_g != expect[bp.id - 1][1]:
        print('blueprint', bp.id, 'got maxg:', bp.max_g, ' expected:', expect[bp.id - 1][1])
        break
      quality = bp.id * bp.max_g
      ret += quality
    return ret

  def do_blueprint(self, bp):
    future_states = set([State()])
    top_score = 0
    start_scoring = False
    for i in range(self.max_minute):
      f_new = []
      print('=#### minute', i+1, ', %d future states' % len(future_states))
      max_ore = max_clay = max_obs = max_geode = 0
      can_score = start_scoring
      for i, state in enumerate(future_states):
        fs = self.do_minute(bp, state)
        for f in fs:
          score = self.score_state(bp, f)
          # print(f)
          if f.n_obs > max_obs:
            max_obs = f.n_obs
            # print('Could have', max_obs, 'obsidian')
          if f.n_geode  > bp.max_g:
            bp.max_g = state.n_geode
            print('Could have', bp.max_g, 'geodes')

          # Do some heuristic pruning or we get too many states
          if f.n_geode <= bp.max_g - 3:  # cull the laggards
            continue
          if f.n_obs > 2 * bp.geode_obs:  # Making obs, but no geodes?
            continue
          if f.n_clay > 2 * bp.obs_clay and f.n_obs == 0:  # Making clay, but no obs?
            continue
          if f.n_ore > 2 * bp.clay_ore and f.bot_clay == 0 and f.bot_obs == 0:  # Making only ore
            continue
          if f.n_obs < max_obs - 10 and f.bot_geode == 0:
            continue
          if can_score and self.use_scores:
            heapq.heappush(f_new, (-score, f))
          else:
            f_new.append(f)
          if f.n_obs > 3:
            start_scoring = True
        # print('f_new len', len(f_new))
      if can_score and self.use_scores:
        tier = 1
        first_score = f_new[0][0]
        future_states = set()
        while f_new:
          top = heapq.heappop(f_new)
          assert top[0] >= first_score
          if top[0] > first_score:
            if tier > 3:  # Can we fiddle with this?
              break
            first_score = top[0]
            tier += 1
          future_states.add(top[1])
          if first_score < 0 and tier > 1 and len(future_states) > 50000:
            break
        print('top score', first_score, '# states', len(future_states))
      else:
        future_states = set(f_new)

  def do_minute(self, bp, state):
    # DFS bottom out
    if state.minute > self.max_minute:
      print("BOTTOM")
      if state.n_geode  > bp.max_g:
        bp.max_g = state.n_geode
        print('Could have', bp.max_g, 'geodes')
      return

    state.minute += 1
    # print('== minute', state.minute)

    if state.can_make_geode_bot(bp):
      state.n_ore -= bp.geode_ore
      state.n_obs -= bp.geode_obs
      state.mine()
      state.bot_geode += 1
      return [state]

    """
    # This results in only 54 from sample bp 1
    if state.can_make_obs_bot(bp) and state.n_obs < bp.geode_obs:
      state.n_ore -= bp.obs_ore
      state.n_clay -= bp.obs_clay
      state.mine()
      state.bot_obs += 1
      return [state]
    """

    # spend first

    future_states = [state]
    can_ore = min(state.n_ore // bp.ore_ore, 1)
    if state.n_ore > 1.5 * bp.clay_ore * bp.obs_clay:
      # we are building up too many
      can_ore = 0
    for make_ore in range(0, can_ore + 1):
      assert make_ore == 0 or state.can_make_ore_bot(bp)
      ore_s = State(clone=state)
      future_states.append(ore_s)
      ore_s.n_ore -= bp.ore_ore * make_ore
      ore_s.future_ore += make_ore
      if ore_s.future_ore > 0:
        continue

      can_clay = min(ore_s.n_ore // bp.clay_ore, 1)
      if state.n_clay > 3 * bp.obs_clay:
        # we are building up too many
        can_clay = 0
        # print('can make clay', can_clay)
      for make_clay in range(0, can_clay + 1):
        clay_s = State(clone=ore_s)
        future_states.append(clay_s)
        clay_s.n_ore -= bp.clay_ore * make_clay
        clay_s.future_clay += make_clay
        if clay_s.future_clay > 0:
          continue

        if clay_s.n_obs >= bp.geode_obs:
          # Stop making more of these. We must need ore
          continue

        can_make_obs = min(clay_s.n_ore // bp.obs_ore, clay_s.n_clay // bp.obs_clay)
        if can_make_obs > 2 and clay_s.bot_geode == 0:
          continue
        if clay_s.can_make_obs_bot(bp):
          obs_s = State(clone=clay_s)
          future_states.append(obs_s)
          obs_s.n_ore -= bp.obs_ore
          obs_s.n_clay -= bp.obs_clay
          obs_s.future_obs = 1
          continue

    ret = []
    for fs in future_states:
      fs.mine()
      fs.bot_ore += fs.future_ore
      fs.bot_clay += fs.future_clay
      fs.bot_obs += fs.future_obs
      fs.future_ore = 0
      fs.future_clay = 0
      fs.future_obs = 0
      ret.append(fs)
    # print('generated future states', len(future_states), '=>', len(ret), 'unique.')
    return set(ret)

  def score_state(self, bp, state):
    left = self.max_minute - state.minute
    """
    score = state.bot_geode * left
    # To make another: state.n_obs + state.bot_obs * N == bp.geode_obs
    obs_time_to_next_obs = (bp.geode_obs - state.n_obs) // min(state.bot_obs, 1)
    score = score + (left - obs_time_to_next_obs)
    """
    have_obs = state.n_obs
    bot_obs = state.bot_obs
    bot_geode = state.bot_geode
    score = 0
    # presume we can make an obs every minute
    for t in range(left):
      score += bot_geode
      if have_obs >= bp.geode_obs:
        have_obs -= bp.geode_obs
        bot_geode += 1
      else:
        have_obs += bot_obs
        bot_obs += 1
    return score

  def part2(self):
    print('===== Start part 2')
    self.max_minute = 32
    ret = 1
    for bp in self.blueprints[0:3]:
      bp.max_g = 0
      self.do_blueprint(bp)
      print('blueprint', bp.id, 'max g', bp.max_g)
      ret *= bp.max_g
    return ret

day19.sample_test("""
Blueprint 1: Each ore robot costs 4 ore.  Each clay robot costs 2 ore.  Each obsidian robot costs 3 ore and 14 clay.  Each geode robot costs 2 ore and 7 obsidian.
Blueprint 2: Each ore robot costs 2 ore.  Each clay robot costs 3 ore.  Each obsidian robot costs 3 ore and 8 clay.  Each geode robot costs 3 ore and 12 obsidian.
""", expect1=33, expect2=3472)

if __name__ == '__main__':
  day19.run_and_check('input.txt', expect1=2193, expect2=7200)


#!/usr/bin/env python
# coding: utf-8

# Author: Ioannis Kalfas (@kalfasyan) (kalfasyan at gmail dot com)

import argparse
import multiprocessing as mp
import os
import random
import shutil
from pathlib import Path
from time import perf_counter

import yaml
from tqdm import tqdm

from plakakia.settings import Settings
from plakakia.utils_tiling import clear_duplicates, process_tiles

random.seed(3)

# Parse command-line arguments
parser = argparse.ArgumentParser()
parser.add_argument('--config', help='Path to config.yaml file')
args = parser.parse_args()
print(100*'-')
config_path=args.config

def process_tiles_wrapper(args):
    """Wrapper function for the process_tile function."""
    t, input_image, input_annotation, settings = args
    return process_tiles(t, input_image, input_annotation, settings)

def main():
    # Delete the tiles and annotations folders if they exist
    [shutil.rmtree(x) if Path(x).exists() else None for x in [
                'tiles/', 'output/', 'annotations/', 'images/', 'logs/']]

    start_time = perf_counter()

    if config_path is None:
        print(f"No config file provided. Using default file.")
        # If no config_path is provided, use the default config.yaml file in the package
        package_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'plakakia')
        config_file = os.path.join(package_dir, 'config_example.yaml')
    else:
        config_file = config_path

    with open(config_file, 'r', encoding='utf-8') as f:
        config = yaml.load(f, Loader=yaml.FullLoader)

    # Create a settings object
    settings = Settings(**config)

    # Create a process pool with the desired number of workers
    with mp.Pool(processes=settings.num_workers) as pool:
        # Prepare the arguments for each task
        args = [(t, input_image, input_annotation, settings) \
            for t, (input_image, input_annotation) in \
                enumerate(zip(settings.input_images, settings.input_annotations))]

        # Submit the tasks to the pool
        results = pool.map(process_tiles_wrapper, args)

    end_time = perf_counter() - start_time

    print(f"Finished making tiles! Elapsed time: {end_time:.2f} seconds")

    if settings.clear_duplicates:
        clear_duplicates(settings)

if __name__ == '__main__':
    # Call the main function with the provided config path
    main()


import math

import cv2.cv2 as cv2
import numpy as np
import pyautogui

def nothing(x):
    pass

cv2.namedWindow("tresholds")

cv2.createTrackbar("H_L", "tresholds", 0, 255, nothing)     #lower bound for hue
cv2.createTrackbar("H_U", "tresholds", 0, 255, nothing)     #upper bound for hue
cv2.createTrackbar("S_L", "tresholds", 0, 255, nothing)     #lower bound for saturation
cv2.createTrackbar("S_U", "tresholds", 0, 255, nothing)     #upper bound for saturation
cv2.createTrackbar("V_L", "tresholds", 0, 255, nothing)     #lower bound for value
cv2.createTrackbar("V_U", "tresholds", 0, 255, nothing)     #upper bound for value

cv2.setTrackbarPos("H_L", "tresholds", 0)
cv2.setTrackbarPos("H_U", "tresholds", 255)
cv2.setTrackbarPos("S_L", "tresholds", 0)
cv2.setTrackbarPos("S_U", "tresholds", 255)
cv2.setTrackbarPos("V_L", "tresholds", 174)
cv2.setTrackbarPos("V_U", "tresholds", 255)

cap = cv2.VideoCapture(0)

state1 = -1         # states of current hand gestures. State1 stores the state of previous frame. State2 stores the current state.
state2 = -1         # If state1 == state2, we can be sure that the correct gesture is detected. open hand=0, fist=1, thumb=2, #thumb&point=3
last_action = -1    # stores last executed action. move_cursor=0, click=1, double_click=2, right_click=3
cursorX = 0
cursorY = 0         #current cursor points
flag = 0            #flag that implies whether cursor commands are activated by pressing 's'

cx = 0
cy = 0              #points of the center of hand

rec_width = 450;
rec_heigth = 400;       # Setting a perfect threshold for all of the screen is impossible most of the time.
h, w, = (480, 640)      # So, you have to replace your hand inside the rectangular detection area at the left top corner.
                        # These variables are all about that rectange.
point1 = (0, 0)
point2 = (rec_width, rec_heigth)

heigth_ratio = 1080 / rec_heigth        # Since hand is detected in a limited rectangular area, these ratios provides full control
width_ratio = 1920 / rec_width          # to all of the screen

radius = 100                # radius of an imaginary circle centered mass center of hand
ignore_arm_flag = 0         # a flag that implies whether ignore arm option is on/off

def rec_pos(event, x, y, flags, params):
    global point1, point2

    if event == cv2.EVENT_LBUTTONDBLCLK:

        p1 = x - int(rec_width / 2);
        p2 = y - int(rec_heigth / 2);
        p3 = x + int(rec_width / 2);
        p4 = y + int(rec_heigth / 2);

        if (p1 < 0):
            p1 = 0
            p3 = rec_width
        if (p2 < 0):
            p2 = 0
            p4 = rec_heigth
        if (p3 > w):
            p3 = w
            p1 = w - rec_width
        if (p4 > h):
            p4 = h
            p2 = h - rec_heigth

        point1 = (p1, p2)
        point2 = (p3, p4)

cv2.namedWindow("HSV_morph")
cv2.setMouseCallback("HSV_morph", rec_pos)

while True:
    _, img = cap.read()
    img = cv2.flip(img, 1)

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

    a, b = point1
    c, d = point2
    cropped = img[b:d, a:c]   #cropped part of detection area

    # ------------------------------------------------------------------------

    hl = cv2.getTrackbarPos("H_L", "tresholds")     #lower bound for hue
    hu = cv2.getTrackbarPos("H_U", "tresholds")     #upper bound for hue
    sl = cv2.getTrackbarPos("S_L", "tresholds")     #lower bound for saturation
    su = cv2.getTrackbarPos("S_U", "tresholds")     #upper bound for saturation
    vl = cv2.getTrackbarPos("V_L", "tresholds")     #lower bound for value
    vu = cv2.getTrackbarPos("V_U", "tresholds")     #upper bound for value

    lower = np.array([hl, sl, vl], dtype=np.uint8)
    upper = np.array([hu, su, vu], dtype=np.uint8)

    img_HSV = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
    HSV_mask = cv2.inRange(img_HSV, lower, upper)
    HSV_blurred = cv2.GaussianBlur(HSV_mask, (5, 5), 100)
    HSV_morph = cv2.morphologyEx(HSV_blurred, cv2.MORPH_OPEN, kernel)
    HSV_morph = cv2.dilate(HSV_morph, kernel)

    cv2.rectangle(HSV_morph, point1, point2, (255, 0, 0), 2)

    # ------------------------------------------------------------------------

    hsv_cropped = cv2.cvtColor(cropped, cv2.COLOR_BGR2HSV)

    mask = cv2.inRange(hsv_cropped, lower, upper)
    mask_blurred = cv2.GaussianBlur(mask, (5, 5), 100)
    mask_morph = cv2.morphologyEx(mask_blurred, cv2.MORPH_OPEN, kernel, iterations=2)
    mask = cv2.dilate(mask_morph, kernel, iterations=1)

    if ignore_arm_flag:
        mask[ignore_arm_point:rec_heigth, :] = 0
        HSV_morph[ignore_arm_point:480, :] = 0        #paint black ignored area

    contours, _ = cv2.findContours(mask, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)

    max_area = 0
    max_contour = 0
    for i in contours:
        area = cv2.contourArea(i)
        if area > max_area:
            max_area = area;
            max_contour = i;

    moments = cv2.moments(max_contour)
    if moments['m00'] != 0:
        cx = int(moments['m10'] / moments['m00'])           #Calculation for the center points of hand
        cy = int(moments['m01'] / moments['m00'])

    center = (cx, cy)

    cv2.circle(cropped, center, 10, [0, 0, 255], 2)

    if max_area != 0:

        epsilon = 0.25 * cv2.arcLength(max_contour, True)
        approx = cv2.approxPolyDP(max_contour, epsilon, True)

        cv2.drawContours(cropped, [max_contour], -1, (0, 255, 0), 2)
        hull = cv2.convexHull(max_contour, returnPoints=True);
        hull_area = cv2.contourArea(hull)

        cv2.drawContours(cropped, [hull], 0, (0, 0, 255), 2)
        hull = cv2.convexHull(max_contour, returnPoints=False);
        defects = cv2.convexityDefects(max_contour, hull)

        if defects is not None:
            count = 0
            for i in range(defects.shape[0]):
                s, e, f, d = defects[i, 0]

                start = tuple(max_contour[s][0])
                end = tuple(max_contour[e][0])
                far = tuple(max_contour[f][0])

                triangle_area = (abs((start[0] * end[1] + end[0] * far[1] + far[0] * start[1]) - (
                        end[0] * start[1] + far[0] * end[1] + start[0] * far[1]))) / 2     #calculation of triangular area consisting of start, end, far points

                if ((hull_area / triangle_area) < 30) & (far[1] <= cy) & (start[1]<=cy) & (end[1]<=cy):  # filteration of defect points
                    cv2.circle(cropped, far, 5, (255, 0, 0), -1)
                    count += 1

            font = cv2.FONT_HERSHEY_SIMPLEX

            if count >= 3:      # open hand detected

                state2 = 0

                last_action = 0

                if flag == 2:                               # if cursor mode is on
                    cursorX = int(cx * width_ratio)
                    cursorY = int(cy * heigth_ratio)
                    pyautogui.moveTo(cursorX, cursorY)

                elif flag == 1:                             # if terminal mode is on
                    cursorX = int(cx * width_ratio)
                    cursorY = int(cy * heigth_ratio)
                    print("move cursor to (", cursorX, ", ", cursorY, ")")

                if ignore_arm_flag:
                    radius = 100

            elif (count == 0):      # fist detected

                if (state1 == 1) & (last_action == 0):

                    last_action = 1
                    if flag == 2:
                        pyautogui.click(cursorX, cursorY)
                    elif flag == 1:
                        print("click on (", cursorX, ", ", cursorY, ")")

                state2 = 1

                if ignore_arm_flag:
                    radius = 70

            elif count == 1:  # thumb detected

                if (state1 == 2) & (last_action == 0):
                    last_action = 2
                    if flag == 2:
                        pyautogui.doubleClick(cursorX, cursorY)
                    elif flag == 1:
                        print("double click on (", cursorX, ", ", cursorY, ")")

                state2 = 2
                if ignore_arm_flag:
                    radius = 70

            elif count == 2:  # thumb&point finger detected

                if (state1 == 3) & (last_action == 0):
                    last_action = 3
                    if flag == 2:
                        pyautogui.rightClick(cursorX, cursorY)
                    elif flag == 1:
                        print("right click on (", cursorX, ", ", cursorY, ")")

                state2 = 3

                if ignore_arm_flag:
                    radius = 90

            if (state1 != -1) & (state1 == state2):
                if state1 == 0:
                    cv2.putText(img, "move", (30, 150), font, 2, (0, 0, 255), 3, cv2.LINE_AA)
                elif state1 == 1:
                    cv2.putText(img, "click", (30, 150), font, 2, (0, 0, 255), 3, cv2.LINE_AA)
                elif state1 == 2:
                    cv2.putText(img, "dbl click", (30, 150), font, 2, (0, 0, 255), 3, cv2.LINE_AA)
                else:
                    cv2.putText(img, "right click", (30, 150), font, 2, (0, 0, 255), 3, cv2.LINE_AA)

            ignore_arm_point = cy + radius

            state1 = state2

    cv2.imshow("cropped", cropped)
    cv2.imshow("img", img)
    cv2.imshow("HSV_morph", HSV_morph)

    key = cv2.waitKey(1)

    if key == 115:                  # press 's' to switch between modes.
        if flag == 2:               # default mode : printing in the terminal
            flag = 0                # terminal mode :
            print("flag = ", 0)     # cursor mode :
        elif flag == 0:
            flag = 1
            print("flag = ", 1)
        else:
            flag = 2
            print("flag = ", 2)

    elif key == 27:                 # press ESC to terminate the program
        break
    elif key == 116:                # press 't' to switch on/off the 'ignore arm feature'
        if ignore_arm_flag == 0:
            ignore_arm_flag = 1
            print("Trigger on!")
        else:
            ignore_arm_flag = 0
            radius = 100
            print("Trigger off!")

cap.release()
cv2.destroyAllWindows()


#
# CSC161 Fall 2014
#
# Daniel Saltz
#
# Chapter 2, Exercise 9
#
# Lab Section TR 2:00-3:15
#
# Class Section TR 6:15-7:30

def main():
    print("This program distances measured in kilometers to miles.")

    kilometers = eval(input("Please enter a distance measured in kilometers: "))
    miles = .62 * kilometers

    print(kilometers, "kilometers is equal to ", miles, "miles.")

main()


# -*- coding:utf-8 -*-

# Given two strings s and t , write a function to determine if t is an anagram of s.
#
# Example 1:
#
#
# Input: s = "anagram", t = "nagaram"
# Output: true
#
#
# Example 2:
#
#
# Input: s = "rat", t = "car"
# Output: false
#
#
# Note:
# You may assume the string contains only lowercase alphabets.
#
# Follow up:
# What if the inputs contain unicode characters? How would you adapt your solution to such case?
#

class Solution(object):
    def isAnagram(self, s, t):
        """
        :type s: str
        :type t: str
        :rtype: bool
        """
        #自己写的，用counter类统计两个字符串中字母出现的次数，如果相等就是anagram
        '''
        return collections.Counter(s) == collections.Counter(t)
        '''
        #用dict行不行？
        resultDict = {}
        for ch in s:
            if ch in resultDict:
                resultDict[ch] += 1
            else:
                resultDict[ch] = 1
        for ch in t:
            if ch in resultDict:
                resultDict[ch] -= 1
            else:
                return False
        for n in resultDict.values():
            if n != 0: return False
        return True


from pylab import *
import imutils
import cv2

image = cv2.imread('chip.png', cv2.CV_LOAD_IMAGE_GRAYSCALE)
thresh = 250
im_bw = cv2.threshold(image, thresh, 255, cv2.THRESH_BINARY)[1]
thresh = cv2.bitwise_not(im_bw)
cnts = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if imutils.is_cv2() else cnts[1]

for c in cnts:
    M = cv2.moments(c)
    cX = int(M["m10"] / M["m00"])
    cY = int(M["m01"] / M["m00"])
    cv2.drawContours(image, [c], -1, (0, 255, 0), 2)
    cv2.circle(image, (cX, cY), 7, (255, 255, 255), -1)
    cv2.putText(image, "center", (cX - 20, cY - 20), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 255, 255), 2)
    cv2.imshow("Image", image)

cv2.waitKey(0)


from django.db.models import Model
from typing import Dict, List, Type

from ..errors import ModelClassNotRegistered
from ..serializers import Exporter
from ..types import ID, ObjectData

class BaseContainer:
    _objects: Dict[ID, ObjectData]

    def __init__(self, exporters: List[Type[Exporter]] = [], ignore_unknown=False):
        self.__exporter_registry: Dict[str, Type[Exporter]] = {}
        for exporter in exporters:
            self.register_exporter(exporter)
        self._objects = {}
        self.ignore_unknown = ignore_unknown

    def register_exporter(self, exporter_cls):
        kind = ID.kind_for_model(exporter_cls.Meta.model)
        self.__exporter_registry[kind] = exporter_cls

    def dump_objects(self):
        for obj in self._objects.values():
            print(f'* {obj.id}')
            print('\n  Fields:')
            for k, v in obj.serialized_data.items():
                print(f'  - {k} = {repr(v)}')
            if obj.attachments:
                print('\n  Attachments:')
                for a in obj.attachments:
                    print(f'  - {a.id}: {repr(a.key)}')
            print()

    def _exporter_for_model(self, obj: Model, raise_exception=True):
        return self._exporter_for_kind(ID.kind_for_model(obj), raise_exception=raise_exception)

    def _exporter_for_kind(self, kind: str, raise_exception=True):
        if kind not in self.__exporter_registry:
            if not raise_exception:
                return None
            raise ModelClassNotRegistered(kind)
        return self.__exporter_registry[kind]


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Implementation of Graham scan algorithm which finds a convex hull given a set
of points.
Created on Wed Nov 13 15:03:33 2019

@author: karthikkr
"""
import matplotlib.pyplot as plt
import numpy as np
import math
import argparse

from plyfile import PlyData, PlyElement
from matplotlib import animation

class GrahamScan():

    def __init__(self, plyfile):
        """
        initialization
        """
        self.data = PlyData.read(plyfile)
        self.P = list(zip(self.data.elements[0].data["x"],\
                          self.data.elements[0].data["y"]))

    def delete(self, index, _list):
        """
        delete the element from the list
        """
        for i in index:
            del _list[i]

    def get_angle(self, a, b, c):
        """
        gets the angle between three points
        """
        ang = math.degrees(math.atan2(c[1]-b[1], \
                            c[0]-b[0]) - math.atan2(a[1]-b[1], a[0]-b[0]))
        return ang + 360 if ang < 0 else ang

    def upper_hull(self):
        """
        Computes the upper hull of
        """
        # sort points based on x coordinates
        self.P.sort(key=lambda tup: tup[0])
        l_upper = self.P[:2]

        for i in range(3, len(self.P)):
            l_upper.append(self.P[i])

            while((len(l_upper)> 2) and self.get_angle(l_upper[-3], \
                  l_upper[-2], l_upper[-1]) > 180):
                self.delete([-2], l_upper)
        return l_upper

    def lower_hull(self):
        """
        Computes the lower hull of
        """
        P = list(reversed(self.P))
        l_lower = P[:2]
        for i in range(3, len(P)):
            l_lower.append(P[i])

            while((len(l_lower)> 2) and self.get_angle(l_lower[-3], \
                  l_lower[-2], l_lower[-1]) > 180):
                self.delete([-2], l_lower)

        # delete first and last point in l_lower
        self.delete([0, -1], l_lower)
        return l_lower

    def graham_scan(self):
        """
        complete gramscanalgorithm
        """
        upper_hull = self.upper_hull()
        lower_hull = self.lower_hull()

        return upper_hull + lower_hull

if __name__ == "__main__":
    parser = argparse.ArgumentParser(description=\
                            'Graham Scan Algorithm for finding convex hull')
    parser.add_argument('FILE', metavar='FILE', \
                        help='path to the input .ply file.')
    parser.add_argument('-f', metavar='OUTFILE', default = 'output.ply', \
        help='path to the .ply file to which the output has to be written.')
    args = parser.parse_args()

    # gramscanalgorithm
    gs = GrahamScan(args.FILE)
    # get the convex hull
    ch = gs.graham_scan()

    x_points = [i[0] for i in ch]
    x_points.append(x_points[0])

    y_points = [i[1] for i in ch]
    y_points.append(y_points[0])

    # save the ply file
    vertex = np.array(ch, dtype=[('x', 'f4'), ('y', 'f4')])
    element = PlyElement.describe(vertex, 'vertex')
    PlyData([element],  text=True).write(args.f)

    # plot the graph
    plt.scatter(gs.data.elements[0].data["x"], gs.data.elements[0].data["y"])
    plt.plot(x_points, y_points, color = "black")
    plt.show()


def encrypt_file(file_path, key):
    # Input file
    with open(file_path, "rb") as input_file:
        # Read the content of the file
        file_content = input_file.read()

    # Create hash object with the key
    hasher = hashlib.sha256()
    hasher.update(key.encode("utf-8"))
    key_hash = hasher.digest()

    # Encrypt the content of the file using the key
    encrypted_content = bytearray()
    for i, byte in enumerate(file_content):
        key_byte = key_hash[i % len(key_hash)]
        encrypted_byte = byte ^ key_byte
        encrypted_content.append(encrypted_byte)

    # Write the content encrypted in an output file
    with open(file_path + ".encrypted", "wb") as output_file:
        output_file.write(encrypted_content)

if __name__ == "__main__":
    # Verify that a file and an encryption key was provided
    if len(sys.argv) < 3:
        print("Use > python encrypt.py key file")
        sys.exit(1)

    file_path = sys.argv[1]
    key = sys.argv[2]

    # Encrypt the file
    encrypt_file(file_path, key)

    print(f'{file_path} has been encrypted with the key "{key}"')


# высылка запроса и преоразование в суп
import csv
import json

import requests
from bs4 import BeautifulSoup

from config import products_list

products_list = products_list

def get_data(url, headers):
    r = requests.get(url, headers=headers)
    soup = BeautifulSoup(r.text, 'lxml')
    with open('index.html', 'w') as file:
        file.write(r.text)
        file.close()
    return soup

# получение данных из супа
def parse_scout(soup):
    # productslist = []
    global products_list
    result = soup.find_all('article', {
        'class': 'cldt-summary-full-item listing-impressions-tracking list-page-item ListItem_article__ppamD'})

    for item in result:
        product = {'name': item.find('h2').text + item.find('span', {'class': 'ListItem_version__jNjur'}).text,
                   'ID': item['id'],
                   'href': item.find('a', {'class': 'ListItem_title__znV2I Link_link__pjU1l'})['href']
                   }
        products_list.append(product)

    return products_list

# Высылка сообщение ботом
def send_message(chat_id, message):
    get_messanger = {'chat_id': chat_id,
                     'text': message
                     }
    chat = requests.get(
        f'https://api.telegram.org/bot1341365211:AAFUF_x74D8zxeFGRcCu6e2HuprexA-z9IM/sendMessage?chat_id={chat_id}&text=https://www.autoscout24.de{message}')
    return chat

def save(product_list, path):  # ФУНКЦИЯ ЗАПИСИ
    with open(path, 'w') as csvfile:
        writer = csv.writer(csvfile)
        writer.writerow(('Name', 'ID', 'href'))  # заголовоки таблицы
        for team in product_list:
            writer.writerow((team['name'], team['ID'], team['href']))
        csvfile.close()

# сохранение в json
def save_json(product_list, path):
    with open(path,'w') as file:
        json.dump(product_list,file,indent=4, ensure_ascii=False)
        file.close()

# из файла в словарь
def file_to_dict(path):
    with open(path, newline='') as csvfile:
        reader = csv.DictReader(csvfile)
        alt_list = []
        for row in reader:
            product = {'name': row['Name'],
                       'ID': row['ID'],
                       'href': row['href']

                       }
            alt_list.append(product)
        csvfile.close()
    return alt_list

# достает все айди из файла в список
def get_ids(path):
    with open(path, newline='') as csvfile:
        reader = csv.DictReader(csvfile)
        ids = []
        for row in reader:
            ids.append(row['ID'])
    csvfile.close()
    return ids

# while open('alt_product_list.json',  'r') as file:
#         alt_product_list = json.load(file)


"""
This file contains the functions for saving and loading the restos and gustos.
"""

# Standard Library Import
import os

# Data Paths
file_dir = os.path.dirname(__file__)
DATA_PATH = os.path.join(file_dir, "data")
RESTO_PATH = os.path.join(DATA_PATH, "resto.dat")
GUSTO_PATH = os.path.join(DATA_PATH, "gusto.dat")

# Creates a directory for data if it doesn't exist
if not os.path.exists(DATA_PATH):
    os.mkdir(DATA_PATH)

def load_restos(restos_dict: dict[str, list]) -> dict[str, list]:
    """Loads the restos from resto.dat.

    Args:
        restos_dict (dict[str, list]): the dictionary of restos

    Returns:
        dict[str, list]: the dictionary of restos
    """
    # Create resto.dat if it doesn't exist
    open(RESTO_PATH, "a", encoding="utf-8").close()

    # Read resto.dat
    fh = open(RESTO_PATH, "r", encoding="utf-8")
    for line in fh:
        name, distance, cuisine_type, meal_type, cost, rating = line.split("~")
        restos_dict[name] = [
            float(distance),
            cuisine_type.split(","),
            meal_type,
            float(cost),
            float(rating),
        ]
    fh.close()
    return restos_dict

def load_gustos(gustos_dict: dict[str, list]) -> dict[str, list]:
    """Loads the gustos from gusto.dat.

    Args:
        gustos_dict (dict[str, list]): the dictionary of gustos

    Returns:
        dict[str, list]: the dictionary of gustos
    """
    # Create gusto.dat if it doesn't exist
    open(GUSTO_PATH, "a", encoding="utf-8").close()

    # Read gusto.dat
    fh = open(GUSTO_PATH, "r", encoding="utf-8")
    for line in fh:
        (
            label,
            description,
            group_size,
            meal_type,
            budget,
            max_distance,
            cuisine_type,
            min_rating,
        ) = line.split("~")

        gustos_dict[label] = [
            description,
            int(group_size),
            meal_type,
            float(budget) if budget != "None" else None,
            float(max_distance) if max_distance != "None" else None,
            cuisine_type if cuisine_type != "None" else None,
            float(min_rating) if min_rating != "None\n" else None,
        ]
    fh.close()
    return gustos_dict

def load(restos_dict: dict[str, list], gustos_dict: dict[str, list]) -> tuple:
    """Loads the restos and gustos from their respective files.

    Args:
        restos_dict (dict[str, list]): the dictionary of restos
        gustos_dict (dict[str, list]): the dictionary of gustos

    Returns:
        tuple: the dictionary of restos and gustos
    """

    # This function simply calls load_restos and load_gustos
    restos_dict = load_restos(restos_dict)
    gustos_dict = load_gustos(gustos_dict)
    return (restos_dict, gustos_dict)

def save_restos(restos_dict: dict[str, list]) -> None:
    """Saves the restos to resto.dat.

    Args:
        restos_dict (dict[str, list]): the dictionary of restos
    """
    fh = open(RESTO_PATH, "w", encoding="utf-8")
    for name, value in restos_dict.items():
        fh.write(
            f"{name}~{value[0]}~{','.join(value[1])}~{value[2]}~{value[3]}~{value[4]}\n"
        )
    fh.close()

def save_gustos(gustos_dict: dict[str, list]) -> None:
    """Saves the gustos to gusto.dat.

    Args:
        gustos_dict (dict[str, list]): the dictionary of gustos
    """
    fh = open(GUSTO_PATH, "w", encoding="utf-8")
    for label, value in gustos_dict.items():
        fh.write(
            f"{label}~{value[0]}~{value[1]}~{value[2]}~{value[3]}~{value[4]}~{value[5]}~{value[6]}\n"
        )
    fh.close()

def save(restos_dict: dict[str, list], gustos_dict: dict[str, list]) -> None:
    """Saves the restos and gustos to their respective files.

    Args:
        restos_dict (dict[str, list]): the dictionary of restos
        gustos_dict (dict[str, list]): the dictionary of gustos
    """

    # This function simply calls save_restos and save_gustos
    save_restos(restos_dict)
    save_gustos(gustos_dict)


from urllib.parse import urlencode, quote_plus
import requests
import constants
import json

def getSearchCategoryLink(category,page = 1):
    category = category.lower()
    url_params_array = {
        'query':category,
        'page':page
    }
    url_params_str = urlencode(url_params_array, quote_via=quote_plus)
    return f"https://www.trustpilot.com/search?{url_params_str}"

def get_all_categories(hierarchy = 0):
    return json.loads(
        requests.get(
            constants.ENDPOINT,
            params={
                "fetch":"categories",
                "hierarchy":hierarchy
            }
        ).text
    )

def post_scraped_review(review):
    return requests.post(
        constants.ENDPOINT,
        data=json.dumps(review.__dict__)
    ).text

def retrieve_json_from_category_businesses(body):
    first_search = '<script id="__NEXT_DATA__" type="application/json">'
    first_cut_index = body.find(first_search) + len(first_search)
    first_part = body[first_cut_index:len(body)]
    second_search = '</script>'
    second_cut = first_part.find(second_search)
    return first_part[0:second_cut]

def retrieve_json_from_reviews_page(body):
    first_search = '<script type="application/ld+json" data-business-unit-json-ld>'
    first_cut_index = body.find(first_search) + len(first_search)
    first_part = body[first_cut_index:len(body)]
    second_search = '</script>'
    second_cut = first_part.find(second_search)
    return first_part[0:second_cut]


import tree
class TreeNode(object):
	def __init__(self,val):
		self.val = val
		self.left = None
		self.right = None
		self.height = 1
T = tree
def balance(x):
	balance = x.left.height - x.right.height

	while balance > 1 or balance < -1:
		if balance >1:
			rightRotate(T,x)
		else:
			leftRotate(T,x)
		balance(x.left)
		balance(x.right)

def AvlInsert(x,z):
	w = x
	while w != None:
		y = w
		if z.key>y.key:
			w = w.right
		else:
			w = w.left

	if z.key>y.key:
		y.right = z
		if y.left==None:
			y.height = 1
	while y!= x:
		y.height = 1+max(y.left.h+y.right.h)
		if y.left.height>y.right.height+1:
			rightRotate(T,y)
		if y.right.height>y.left.height+1:
			leftRotate(T,y)
			y = y.parent

def rightRotate(T,x):
	pass
def leftRotate(T,x):
	pass


from typing import List

class Solution:
    def updateBoard(self, board: List[List[str]], click: List[int]) -> List[List[str]]:
        directions = [(0, 1), (1, 1), (1, 0), (1, -1), (0, -1), (-1, -1), (-1, 0), (-1, 1)]
        cols, rows = len(board[0]), len(board)
        stack = [click]

        def bfs(r: int, c: int):
            mines = 0
            temp = []
            for x, y in directions:
                if 0 <= c + x < cols and 0 <= r + y < rows:
                    val = board[r + y][c + x]
                    if val == 'M':
                        mines += 1
                    elif val == 'E':
                        temp.append((r + y, c + x))
            if mines != 0:
                board[r][c] = str(mines)
            else:
                board[r][c] = 'B'
                stack.extend(temp)

        while stack:
            r, c = stack.pop()
            if board[r][c] != 'M':
                bfs(r, c)
            else:
                board[r][c] = 'X'
                break

        return board

def main():
    sol = Solution()
    print(sol.updateBoard(board = [["E","E","E","E","E"],["E","E","M","E","E"],["E","E","E","E","E"],["E","E","E","E","E"]], click = [3,0]))
    print(sol.updateBoard(board = [["B","1","E","1","B"],["B","1","M","1","B"],["B","1","1","1","B"],["B","B","B","B","B"]], click = [1,2]))

if __name__ == '__main__':
    main()


import random
try:
    # check user input is equal to target or not
    def guessNumber(target):
        '''check input number is equal to given or not'''
        check = True
        times = 1
        while check:
                player = int(input("Guess number:- "))
                if player < target:
                    print("Wrong\nYou guess smaller number")
                    times += 1
                elif player > target:
                    print("Wrong\nYou guess larger number")
                    times += 1
                else:
                    print(f"Congratulation\nYou guess the right number in {times} times")
                    check = False
        return times
    # generate random number
    def generateRandomNumber(a, b):
        '''return random number between a and b'''
        return random.randrange(a, b)
except:
        raise TypeError("Please enter only integer number")
if __name__ == "__main__":
    try:
        mn, mx = input("Enter minimum and maximum number:- ").split(' ')
        target = generateRandomNumber(int(mn), int(mx))
        print("Player 1 :-")
        p1 = guessNumber(target)
        print("Player 2 :-")
        target = generateRandomNumber(int(mn), int(mx))
        p2 = guessNumber(target)
        if p1 < p2:
            print("Player 1 win the game")
        elif p1 == p2:
            print("Match drawn")
        else:
            print("Player 2 win the game")

    except:
        raise TypeError("Please enter only integer number")


from bs4 import BeautifulSoup
from .process_tag import process_tag

def add_links(converted_text, html):
    """
    Add the links to the bottom of the text
    """
    soup = BeautifulSoup(html, 'html.parser')

    link_exceptions = [
        'footnote-reference',
        'fn-backref',
        'citation-reference'
    ]

    footnotes = {}
    citations = {}
    backrefs = {}

    links = soup.find_all('a')
    for link in links:
        href = link.get('href')
        text = process_tag(link)
        classes = dict(link.attrs).get('class', '')

        if 'footnote-reference' in classes:
            footnotes[href] = '#' + link.get('id')

        elif 'citation-reference' in classes:
            text = process_tag(link)
            citations[text] = '#' + link.get('id')

        elif 'fn-backref' in classes:
            sibling = link.findNext('td')
            text = process_tag(sibling)
            backrefs[href] = text

        excepted_link = False
        for class_type in classes:
            if class_type in link_exceptions:
                excepted_link = True

        if not excepted_link:
            if text.endswith('_'):
                text = text[0:-1]
            if len(text.split(' ')) > 1:
                text = text[1:-1]
            converted_text += '.. _' + text + ': ' + href + '\n'

    if len(footnotes.keys()) > 0:
        converted_text += '\n'

    for key in footnotes.keys():
        text = backrefs[footnotes[key]]
        converted_text += '.. [' + key + '] ' + text + '\n'

    if len(citations.keys()) > 0:
        converted_text += '\n'

    for key in citations.keys():
        text = backrefs[citations[key]]
        converted_text += '.. ' + key[0:-1] + ' ' + text + '\n'

    return converted_text.rstrip()


class Solution:
  def findWords(self, board: List[List[str]], words: List[str]) -> List[str]:
    # optimized DFS + trie-like dictionaries

    ret = []
    root = {}

    def dfs(r, c, n):
      # recursive DFS
      if board[r][c] == '*':
        return
      c_char = board[r][c]
      # mark letter as visited
      board[r][c] = '*'
      if c_char not in n:
        board[r][c] = c_char
        return
      n = n[c_char]
      # word found, add to ret and prune
      if '#' in n:
        ret.append(n['#'])
        del n['#']
      if r > 0:
        dfs(r-1, c, n)
      if c > 0:
        dfs(r, c-1, n)
      if r < len(board)-1:
        dfs(r+1, c, n)
      if c < len(board[0])-1:
        dfs(r, c+1, n)
      # unmark as visited
      board[r][c] = c_char

    # insert words into trie
    for word in words:
      cur = root
      for c in word:
        cur = cur.setdefault(c, {})
      cur['#'] = word

    for i in range(len(board)):
      for j in range(len(board[0])):
        dfs(i, j, root)

    return ret

Problems/0212. (H) Word Search II/Python3/solution.py


from flask_wtf import FlaskForm
from wtforms import DateField, SelectMultipleField, SubmitField, ValidationError
from wtforms.validators import DataRequired
from datetime import date

class FormEleccionMateriales(FlaskForm):
    fecha_entrega = DateField(
        "Fecha recepción de materialess",
        default=date.today,
        validators=[DataRequired(message="El campo para la fecha de recepción es obligatorio")],
    )

    enviar = SubmitField("Guardar")

    def validate_fecha_entrega(self, field):
        if field.data <= date.today():
            raise ValidationError(
                "La fecha de recepción de materiales debe ser posterior a la fecha actual"
            )


from scrapy.exceptions import DropItem
from sqlalchemy.orm import sessionmaker

from ..modals.stock_pe_ratio import db_connect, create_table, StockPERatio

class StockPERatioPipeline(object):
    def __init__(self):
        self.engine = db_connect()
        self.Session = sessionmaker(bind=self.engine)

    def process_item(self, item, spider):

        if StockPERatio.__tablename__ not in self.engine.table_names():
            create_table(self.engine)

        session = self.Session()

        if session.query(StockPERatio). \
                filter(StockPERatio.code == str(item['code'])). \
                filter(StockPERatio.yearQuarter == str(item['yearQuarter'])). \
                first():
            session.close()
            raise DropItem("Duplicate item found: %s" % item["code"])

        try:
            session.add(StockPERatio(**item))
            session.commit()
        except:
            session.rollback()
            raise
        finally:
            session.close()

        return item


import argparse
import datetime
import os
import re
import sys
from collections import namedtuple
import mako.template
import mako.lookup
from mako import exceptions
from ruamel import yaml

class BlockGenerator:
    """
    Generates a new file from a template utilizing a YAML configuration passed
    as argument.

    Each BlockGenerator generate one file out of one template.
    All substitution parameter used in the template must be given in the YAML
    configuration. Exceptions: year (generated on the fly) and destination
    (given as argument). The root object parsed from the YAML configuration is
    config. All configuration items are represented as object members of config
    (YAML dictionaries are resolved recursively).
    """

    def __init__(self, template_file):
        """
        Initializes a new generator based on template_file
        :param template_file: file used as root template during rendering,
                            template file is assumed to be located in folder
                            'modules' relative to this Python file.
        """
        self.template_file = template_file
        self.year = datetime.datetime.now().year
        self.parser = None
        self.config = None
        self.destination = None

    def setup_parser(self):
        """
        Setup argument parser.

        ArgumentParser is able to receive destination path and a file location
        of the YAML configuration.
        """
        self.parser = argparse.ArgumentParser(
            description="Generate RFNoC module out of yml description")
        self.parser.add_argument("-c", "--config", required=True,
                                 help="Path to yml configuration file")
        self.parser.add_argument("-d", "--destination", required=True,
                                 help="Destination path to write output files")

    def setup(self):
        """
        Prepare generator for template substitution.

        Results of setup are save in member variables and are accessible for
        further template processing.
        self.year         current year (for copyright headers)
        self.destination  root path where template generation results are placed
        self.config       everything that was passed as YAML format
                          configuration
        """
        args = self.parser.parse_args()
        self.year = datetime.datetime.now().year
        self.destination = args.destination
        os.makedirs(self.destination, exist_ok=True)
        with open(args.config) as stream:
            self.config = yaml.safe_load(stream)

    def run(self):
        """
        Do template substitution for destination template using YAML
        configuration passed by arguments.

        Template substitution is done in memory. The result is written to a file
        where the destination folder is given by the argument parser and the
        final filename is derived from the template file by substitute template
        by the module name from the YAML configuration.
        """
        # Create absolute paths for templates so run location doesn't matter
        template_dir = os.path.abspath(os.path.join(os.path.dirname(__file__),
                                                    "templates"))
        lookup = mako.lookup.TemplateLookup(directories=[template_dir])
        filename = os.path.join(template_dir, self.template_file)
        tpl = mako.template.Template(filename=filename, lookup=lookup,
                                     strict_undefined=True)
        # Render and return
        try:
            block = tpl.render(**{"config": self.config,
                                  "year": self.year,
                                  "destination": self.destination,})
        except:
            print(exceptions.text_error_template().render())
            sys.exit(1)

        filename = self.template_file
        # pylint: disable=no-member
        filename = re.sub(r"template(.*)\.mako",
                          r"%s\1" % self.config['module_name'],
                          filename)
        fullpath = os.path.join(self.destination, filename)

        with open(fullpath, "w") as stream:
            stream.write(block)

if __name__ == "__main__":
    Task = namedtuple("Task", "name")
    TASKS = [Task(name="noc_shell_template.v.mako"),
             Task(name="rfnoc_block_template.v.mako"),
             Task(name="rfnoc_block_template_tb.sv.mako"),
             Task(name="Makefile"),
             Task(name="Makefile.srcs")]
    for task in TASKS:
        generator = BlockGenerator(task.name)
        generator.setup_parser()
        generator.setup()
        generator.run()


from fastapi import APIRouter

from database import SessionLocal
from models import Answer

router = APIRouter(
    prefix="/api/answer"
)

@router.get("/list")
def answer_list():
    db = SessionLocal()
    _answer_list = db.query(Answer).all()
    db.close()
    return _answer_list


import logging
import pprint

from odoo import _, fields, models
from odoo.exceptions import ValidationError

_logger = logging.getLogger(__name__)

class PaymentToken(models.Model):
    _inherit = 'payment.token'

    stripe_payment_method = fields.Char(string="Stripe Payment Method ID", readonly=True)
    stripe_mandate = fields.Char(string="Stripe Mandate", readonly=True)

    def _stripe_sca_migrate_customer(self):
        """ Migrate a token from the old implementation of Stripe to the SCA-compliant one.

        In the old implementation, it was possible to create a Charge by giving only the customer id
        and let Stripe use the default source (= default payment method). Stripe now requires to
        specify the payment method for each new PaymentIntent. To do so, we fetch the payment method
        associated to a customer and save its id on the token.
        This migration happens once per token created with the old implementation.

        Note: self.ensure_one()

        :return: None
        """
        self.ensure_one()

        # Fetch the available payment method of type 'card' for the given customer
        response_content = self.provider_id._stripe_make_request(
            'payment_methods',
            payload={
                'customer': self.provider_ref,
                'type': 'card',
                'limit': 1,  # A new customer is created for each new token. Never > 1 card.
            },
            method='GET'
        )
        _logger.info("received payment_methods response:\n%s", pprint.pformat(response_content))

        # Store the payment method ID on the token
        payment_methods = response_content.get('data', [])
        payment_method_id = payment_methods and payment_methods[0].get('id')
        if not payment_method_id:
            raise ValidationError("Stripe: " + _("Unable to convert payment token to new API."))
        self.stripe_payment_method = payment_method_id
        _logger.info("converted token with id %s to new API", self.id)


from django.shortcuts import render, redirect
from django.apps import apps
from django.contrib.auth.decorators import login_required
from binascii import hexlify
from apps.features.models import Vault, SharedSecret, LockKey, RSAKeyPair
from utilities.cryptography import generate_shared_secret, encrypt_file

user_model = apps.get_model("users", "User")

@login_required()
def upload_file(request):
    all_users = user_model.objects.all()
    if request.method == "POST":
        no_of_secrets = int(request.POST.get('no_of_secrets'))
        unlock_secrets = int(request.POST.get('unlock_secrets'))
        secret_holders = request.POST.getlist('secret_holders')
        document_name = request.POST.get('document_name')
        document = request.FILES.get('document')

        if (no_of_secrets >= unlock_secrets) and (no_of_secrets == len(secret_holders)):

            # SAVE FILE
            new_document = Vault.objects.add_document(
                user=request.user,
                document_name=document_name,
                document_file=document,
                req_unlock=unlock_secrets,
                status="Encrypted With shared Secret"
            )
            new_document.save()

            # GET KEY AND SECRETS
            shares, key = generate_shared_secret(unlock_secrets, no_of_secrets)

            # ENCRYPT THE FILE
            enc_file = encrypt_file(new_document, key)
            print(enc_file)

            # SHARE THE SECRETS
            for i in range(len(shares)):
                new_secret = SharedSecret.objects.assign_secret(
                    name=document_name,
                    owner=user_model.objects.get(id=secret_holders[i]),
                    file=new_document,
                    index=shares[i][0],
                    secret=hexlify(shares[i][1]).decode('utf-8')
                )
                new_secret.save()

            # SAVE THE KEY
            new_key = LockKey()
            new_key.key = hexlify(key).decode('utf-8')
            new_key.file = new_document
            new_key.save()
        else:
            return render(request, 'upload-documents.html', {
                'all_users': all_users,
                'error_message':
                    "Num of Secrets must be => Num of Required Unlock secrets."
            })
        return redirect('vault')

    return render(request, 'upload-documents.html', {'all_users': all_users})

@login_required()
def vault(request):
    vault_items = Vault.objects.all()
    return render(request, 'vault.html', {'vault_items': vault_items})

@login_required()
def user_shared_secrets(request):
    secrets = request.user.shared_secrets.all()
    return render(request, 'shared_secrets.html', {'secrets': secrets})

@login_required()
def user_signed_documents(request):
    signatures = request.user.signatures.all()
    return render(request, 'my-signed-docs.html', {'signatures': signatures})


"""
Django settings for tango_with_django_project project.

For more information on this file, see
https://docs.djangoproject.com/en/1.7/topics/settings/

For the full list of settings and their values, see
https://docs.djangoproject.com/en/1.7/ref/settings/
"""

# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
import os
BASE_DIR = os.path.dirname(os.path.dirname(__file__))

#add template folders
TEMPLATE_PATH = os.path.join(BASE_DIR,'templates') #make absolute path from relative path
TEMPLATE_DIRS = (
                # Put strings here, like "/home/html/django_templates" or "C:/www/django/templates".
                # Always use forward slashes, even on Windows.
                # Don't forget to use absolute paths, not relative paths.
                TEMPLATE_PATH,
                )

#add static path
STATIC_PATH = os.path.join(BASE_DIR,'static')

STATIC_URL = '/static/' # You may find this is already defined by default (see bottom).

STATICFILES_DIRS = (
    STATIC_PATH,
)

#add media path
# The first variable MEDIA_URL defines the base URL from which all media files will be accessible
# on your development server. Setting the MEDIA_URL (for example) to /media/ will mean that user
# uploaded files will be available from the URL http://127.0.0.1:8000/media/.
# MEDIA_ROOT is used to tell Django where uploaded files should be stored on your local disk.
# In here, we set this variable to the result of joining our PROJECT_PATH variable with /media/.
# This gives an absolute path of <workspace>/tango_with_django_project/media/.
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media') # Absolute path to the media directory
#(Testing) try "http://127.0.0.1:8000/media/sample_upload.jpg" to see an image
#====================================================================
# WARNING: check The official Django documentation on static files, on
#          https://docs.djangoproject.com/en/1.7/ref/contrib/staticfiles/#static-file-development-view
#          before deployment!!!!!!!
#====================================================================
#LOGIN_URL = '/rango/login/' #ensures that the login_required() decorator will redirect any user not logged in to the URL /rango/login/
LOGIN_URL = '/accounts/login/'

# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/1.7/howto/deployment/checklist/

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'e9ul58@xbvs@yca#y!1u2^pmyfy#ozgo=h*b!s55mwundv+e3!'

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True

TEMPLATE_DEBUG = True

ALLOWED_HOSTS = [] # Need to set this when deployment

# Application definition

INSTALLED_APPS = (
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'rango',
    'registration',
)

MIDDLEWARE_CLASSES = (
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
)

ROOT_URLCONF = 'tango_with_django_project.urls'

WSGI_APPLICATION = 'tango_with_django_project.wsgi.application'

# Database
# https://docs.djangoproject.com/en/1.7/ref/settings/#databases

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    }
}

# Internationalization
# https://docs.djangoproject.com/en/1.7/topics/i18n/

LANGUAGE_CODE = 'en-us'

TIME_ZONE = 'UTC'

USE_I18N = True

USE_L10N = True

USE_TZ = True

# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/1.7/howto/static-files/

#STATIC_URL = '/static/'

#for package 'django-registration-redux'
REGISTRATION_OPEN = True        # If True, users can register
ACCOUNT_ACTIVATION_DAYS = 7     # One-week activation window; you may, of course, use a different value.
REGISTRATION_AUTO_LOGIN = True  # If True, the user will be automatically logged in.
LOGIN_REDIRECT_URL = '/rango/'  # The page you want users to arrive at after they successful log in
LOGIN_URL = '/accounts/login/'  # The page users are directed to if they are not logged in,
                                # and are trying to access pages requiring authentication


import re
from utils import aoc
from copy import deepcopy
from operator import add, mul
from math import prod

class Monkey:
    def __init__(self, data):
        regex = re.compile(r"\d+")
        matches = regex.findall(data[2])

        self.items = list(map(int, regex.findall(data[1])))
        self.operator = add if "+" in data[2] else mul
        self.operation_value = int(matches[0]) if matches else None
        self.divisible_by = int(regex.findall(data[3])[0])
        self.if_true = int(regex.findall(data[4])[0])
        self.if_false = int(regex.findall(data[5])[0])
        self.counter = 0

    def inspect(self):
        i = self.items.pop(0)
        if self.operation_value:
            return self.operator(i, self.operation_value)
        return self.operator(i, i)

def simulate(monkeys: list, rounds: int, p2=False):
    if p2:
        mod = prod(monkey.divisible_by for monkey in monkeys)

    for _ in range(rounds):
        for monkey in monkeys:
            monkey.counter += len(monkey.items)

            while monkey.items:
                if p2:
                    item = monkey.inspect() % mod
                else:
                    item = monkey.inspect() // 3

                if item % monkey.divisible_by == 0:
                    monkeys[monkey.if_true].items.append(item)
                else:
                    monkeys[monkey.if_false].items.append(item)

    a, b = sorted(-monkey.counter for monkey in monkeys)[:2]
    return a * b

if __name__ == "__main__":
    regex = re.compile(r"\d+")
    input = aoc.get_input("11", split="\n\n")
    monkeys = []
    for block in input:
        data = block.split("\n")
        monkeys.append(Monkey(data))

    monkeys_copy = deepcopy(monkeys)
    print(simulate(monkeys, 20))
    print(simulate(monkeys_copy, 10000, True))


import random
import cv2
import pandas
from keras.models import load_model
from tensorflow import keras
import glob
import re
import time
from keras.applications import vgg16 as vgg16
import numpy as np
import tensorflow as tf
from PIL import Image
from keras import models, layers, applications
from keras_preprocessing.image import ImageDataGenerator
from matplotlib import image
# Print time for start execution of code
from skimage.transform import resize
from sklearn.preprocessing import StandardScaler
from tensorflow.python.keras.utils.np_utils import to_categorical
from sklearn.model_selection import train_test_split

startTime = time.perf_counter()
print("Start execution time:", startTime)

X_TRAIN_IMG_ARRAY_LENGTH = 10270

X_TEST_IMG_ARRAY_LENGTH = 15009

# Initialize arrays
readLine = []
# create y_train to store y_train data
y_train = []
# store image pixel data for x_train and x_test
x_train = []
x_test = []

# Standardize function for image arrays
scaler = StandardScaler()

x_train = np.empty((X_TRAIN_IMG_ARRAY_LENGTH, 200, 200, 3), dtype=np.float32)
x_test = np.empty((X_TEST_IMG_ARRAY_LENGTH, 200, 200, 3), dtype=np.float32)
print("GPU number available:", len(tf.config.experimental.list_physical_devices("GPU")))

# These functions are implemented for Fit_Generator and data augmentation
# to store x_train and x_val into class directories
# def storeX_TrainWithLabels(x_trainArray, y_trainArray, x_validArray, y_validArray, trainPath, validPath):
#     print("Storing image and labels")
#     for length in range(len(x_trainArray)):
#         for y_range in range(23):
#             if int(y_trainArray[length]) == y_range:
#                 img = Image.fromarray(x_trainArray[length])
#                 createLabelFolders(str(trainPath) + str(y_range))
#                 if os.path.isfile(str(trainPath) + str(y_range) + "/" + str(length) + ".jpg"):
#                     print("File already exists, jump to next file")
#                 else:
#                     img.save(str(trainPath) + str(
#                         y_range) + "/" + str(length) + ".jpg")
#     for length in range(len(x_validArray)):
#         for y_range in range(23):
#             if int(y_validArray[length]) == y_range:
#                 img = Image.fromarray(x_validArray[length])
#                 createLabelFolders(str(validPath) + str(y_range))
#                 if os.path.isfile(str(validPath) + str(y_range) + "/" + str(length) + ".jpg"):
#                     print("File already exists, jump to next file")
#                 else:
#                     img.save(str(trainPath) + str(
#                         y_range) + "/" + str(length) + ".jpg")
#     print("Finished")
#
# def storeX_TrainWithLabelsForX_Test(x_testArray, testPath):
#     print("Storing image and labels")
#     for length in range(len(x_testArray)):
#         img = Image.fromarray(x_testArray[length])
#         createLabelFolders(str(testPath))
#         if os.path.isfile(str(testPath)+"/" + str(length) + ".jpg"):
#             print("File already exists, jump to next file")
#         else:
#             img.save(str(testPath)
#             +"/" + str(length) + ".jpg")
#
#     print("Finished")

# def createLabelFolders(path):
#     try:
#         os.mkdir(path)
#     except OSError:
#         print("Directory already created", path)
#     else:
#         print("Successfully created the directory %s ", path)

# Method to display image
# def displayImage(singleImage):
#     img = Image.fromarray(singleImage)
#     img.show()

# Upload file "train.txt" containing y_train data
# uploaded = files.upload()
def openY_Train(file):
    uploaded = open(file, "r")
    for everyLine in uploaded:
        readLine.append(everyLine)

def loadY_Train():
    # Put only the y_train data into array in order
    for line in readLine:
        # replace unnecessary strings with space
        temp = line.replace("\n", "")
        splitChar = " "
        # Partition out only the numbers and add to array
        temp1 = temp.partition(splitChar)[2]
        y_train.append(temp1)

# The following two functions are for sorting files in directory
# with int inside strings numerically
# Refernce from https://stackoverflow.com/questions/5967500/how-to-correctly-sort-a-string-with-a-number-inside
def atoi(text):
    return int(text) if text.isdigit() else text

def natural_keys(text):
    """
    alist.sort(key=natural_keys) sorts in human order
    http://nedbatchelder.com/blog/200712/human_sorting.html
    (See Toothy's implementation in the comments)
    """
    return [atoi(c) for c in re.split(r'(\d+)', text)]

# Load x_train images in local directory
x_train_images = glob.glob(
    "E:/360MoveData/Users/11047/Desktop/Aritificial Intelligence/Coursework/train/train" + '/*.jpg')
x_train_images.sort(key=natural_keys)

# Resize all images into unified size, since some photo have different size
# Resize a single image into shape 400*600*3, meaning 400px * 600px * 3 channels (RGB)
def resizeImagesAndSave(imgArray, arrayToSave, imageRangeFrom, imageRangeTo):
    # for singleImage in range(len(images)):
    print("Processing array to store images")

    scale_percent = 100  # percent of original size

    for singleImage in range(imageRangeFrom, imageRangeTo):
        print("Currently processing the", singleImage, "image")

        # All images should be cropped to this size
        cropImage = resize(image.imread(imgArray[singleImage]), (200, 200, 3), preserve_range=True)

        width = int(cropImage.shape[1] * scale_percent / 100)
        height = int(cropImage.shape[0] * scale_percent / 100)
        dim = (width, height)
        resized = cv2.resize(cropImage, dim, interpolation=cv2.INTER_AREA)
        # Saved to specific array parameter
        resized /= 255
        arrayToSave[singleImage] = resized
        # print("Image shape after crop:", np.array(cropImage).size)
    print("Process finished for array to store images")

# Function to convert 3 channel rgb image to greyscale 1 channel Referenced from:
# https://stackoverflow.com/questions/12201577/how-can-i-convert-an-rgb-image-into-grayscale-in-python by Mark Amery
# def rgb2gray(rgb):
#     print("Grey-Scaling images for array")
#     r, g, b = rgb[:, :, :, 0], rgb[:, :, :, 1], rgb[:, :, :, 2]
#     gray = 0.2989 * r + 0.5870 * g + 0.1140 * b
#     print("Grey-Scaling process finished for array")
#     return gray

# Run to open and load y_train in local terminal
openY_Train("train.txt")
# y_train is ranged from 0 to 22
loadY_Train()

# Resize x_train and x_test images into unified size and save into array, with range of images constrained
# x_train_image_range should be max 10270
# x_test_image_range should be max 15009
# Start from index 0
x_train_image_range_from = 0
#  range(i, j) produces i, i+1, i+2, ..., j-1.
# So if range(0,500), meaning index [0 - 499], selects image 0 - 500
x_train_image_range_to = X_TRAIN_IMG_ARRAY_LENGTH

print("Processing y_train to constraint range")
y_train = y_train[x_train_image_range_from:x_train_image_range_to]

print("Processing array x_train to store images")
resizeImagesAndSave(x_train_images, x_train, x_train_image_range_from, x_train_image_range_to)

# The following functions are for data augmentation and fit_generator
# storeX_TrainWithLabelsForX_Test(x_test,"E:/360MoveData/Users/11047/Desktop/Aritificial Intelligence/Coursework/test1/")
#
# train_datagen = ImageDataGenerator(
#     rotation_range=40,
#     width_shift_range=0.2,
#     height_shift_range=0.2,
#     rescale=1. / 255,
#     shear_range=0.2,
#     zoom_range=0.2,
#     horizontal_flip=True)
# validation_datagen = ImageDataGenerator(rescale=1. / 255)
#
# BATCH_SIZE = 16
# IMAGE_SIZE = (48, 32)
#
# train_generator = train_datagen.flow_from_directory(
#     'E:/360MoveData/Users/11047/Desktop/Aritificial Intelligence/Coursework/data_split/train',
#     target_size=IMAGE_SIZE,
#     batch_size=BATCH_SIZE,
#     class_mode='binary')
# validation_generator = validation_datagen.flow_from_directory(
#     'E:/360MoveData/Users/11047/Desktop/Aritificial Intelligence/Coursework/data_split/validation',
#     target_size=IMAGE_SIZE,
#     batch_size=BATCH_SIZE,
#     class_mode='binary')
# print("Done")

# Convert x_train and x_test into greyscale img with shape (numIMG,400,600)
# print("Converting x_train into grayscale")
# x_train = rgb2gray(np.array(x_train))
# print("Converting x_test into grayscale")
# x_test = rgb2gray(np.array(x_test))

# Turn y_train to be categorical
# y_train will be 1 value initially, either class 0,1,2 ... 22 with shape (10270,)
# categorize y_train into (10270,23), which shows the most possible class
print("y_train being processed to be categorical")
y_train = to_categorical(y_train, 23)
print("Categorical process finished")

print("Finished processing y_train to constraint range")

# Keras Model Part
print("Building model...")

VGG = vgg16.VGG16(input_shape=(200, 200, 3), include_top=False, weights="imagenet",classes=23)
VGG.trainable = False
model = keras.Sequential([
    VGG,
    keras.layers.Flatten(),
    keras.layers.Dense(units=512, activation="relu"),
    keras.layers.Dense(units=256, activation="relu"),
    keras.layers.Dense(units=23, activation="softmax")
])

print("Predicting model")

model.compile(optimizer="adam", loss=keras.losses.categorical_crossentropy, metrics=["accuracy"])
model.fit(x_train, y_train, validation_split=0.3, epochs=6, batch_size=32,  shuffle=True)

model.save("my_model_butterfly_VGG16_Version2")