import Queue
import logging
import signal
import time

from ngamsDbSnapshotUtils import checkUpdateDbSnapShots, updateDbSnapShots
from ngamsJanitorCommon import StopJanitorThreadException, checkStopJanitorThread, suspend
from ngamsLib.ngamsCore import isoTime2Secs, loadPlugInEntryPoint

logger = logging.getLogger(__name__)

def JanitorCycle(plugins, srvObj, stopEvt):
    """
    A single run of all the janitor plug-ins
    """

    logger.debug("Janitor Thread running-Janitor Cycle.. ")

    for p in plugins:
        checkStopJanitorThread(stopEvt)
        try:
            logger.debug("Executing plugin %s", p.__name__)
            p(srvObj, stopEvt)
        except StopJanitorThreadException:
            raise
        except:
            logger.exception("Unexpected error in janitor plug-in %s", p.__name__)

def get_plugins(srvObj):
    """
    Returns the list of plug-ins that need to be run in this janitor process
    """

    hardcoded = [
        'janitor.backlog_buffer_checker',
        'janitor.old_requests_cleaner',
        'janitor.expired_data_cleaner',
        'janitor.notifications_sender',
        'janitor.rotated_logfiles_handler',
        'janitor.disk_space_checker',
        'janitor.wake_up_request_processor',
        'janitor.host_suspender'
    ]

    user_plugins = srvObj.getCfg().getJanitorPlugins()
    return [loadPlugInEntryPoint(n, entryPointMethodName='run') for n in hardcoded + user_plugins]

class ForwarderHandler(logging.Handler):

    def __init__(self, srv):
        super(ForwarderHandler, self).__init__()
        self.srv = srv

    def _format_record(self, record):
        # ensure that exc_info and args
        # have been stringified. Removes any chance of
        # unpickleable things inside and possibly reduces
        # message size sent over the pipe.
        if record.args:
            record.msg = record.msg % record.args
            record.args = None
        if record.exc_info:
            self.format(record)
            record.exc_info = None
        record.threadName = 'JANITOR-PROC'
        return record

    def emit(self, record):
        try:
            self.srv.janitor_send('log-record', self._format_record(record))
        except:
            self.handleError(record)

def janitorThread(srvObj, stopEvt, srv_to_jan_queue, jan_to_srv_queue):
    """
    Entry point for the janitor process. It checks which plug-ins should be run,
    how frequently, and runs them in an infinite loop.
    """

    # No need to shut down anything on this process
    def noop(*args):
        pass
    signal.signal(signal.SIGTERM, noop)
    signal.signal(signal.SIGINT, noop)

    # Reset the internal multiprocess queues so the janitor_communicate() method
    # of the server object is usable from within this process
    srvObj._serv_to_jan_queue = srv_to_jan_queue
    srvObj._jan_to_serv_queue = jan_to_srv_queue

    # Set up the logging so it outputs the records into the jan->srv queue
    for h in list(logging.root.handlers):
        logging.root.removeHandler(h)
    logging.root.addHandler(ForwarderHandler(srvObj))

    # Reset the db pointer in our server object to get fresh connections
    srvObj.reconnect_to_db()

    # => Update NGAS DB + DB Snapshot Document for the DB connected.
    try:
        checkUpdateDbSnapShots(srvObj, stopEvt)
    except StopJanitorThreadException:
        return
    except:
        logger.exception("Problem updating DB Snapshot files")

    # Main loop
    suspendTime = isoTime2Secs(srvObj.getCfg().getJanitorSuspensionTime())
    plugins = get_plugins(srvObj)
    run_count = 0
    try:
        while True:

            JanitorCycle(plugins, srvObj, stopEvt)

            # Suspend the thread for the time indicated.
            # Update the Janitor Thread run count.
            run_count += 1
            srvObj.janitor_send('janitor-run-count', run_count)

            # Suspend the thread for the time indicated.
            logger.info("Janitor Thread executed - suspending for %d [s] ...", suspendTime)
            startTime = time.time()
            while (time.time() - startTime) < suspendTime:

                # Check if we should update the DB Snapshot.
                try:
                    event_info_list = srvObj.janitor_communicate('event-info-list', timeout=0.5)
                except Queue.Empty:
                    event_info_list = None

                if event_info_list is not None:
                    try:
                        diskInfo = None
                        for diskInfo in event_info_list:
                            updateDbSnapShots(srvObj, stopEvt, diskInfo)
                    except:
                        if (diskInfo):
                            msg = "Error encountered handling DB Snapshot " +\
                                  "for disk: %s/%s"
                            args = (diskInfo[0], diskInfo[1])
                        else:
                            msg, args = "Error encountered handling DB Snapshot", ()
                        logger.exception(msg, *args)
                        suspend(stopEvt, 5)

                suspend(stopEvt, 1.0)

    except StopJanitorThreadException:
        return

# EOF


from math import *
a = int(input())
b = int(input())
c = int(input())
d = int(input())
def rutgon(a ,b):
    n = gcd(a ,b)
    return (a//n), (b//n)

def BienDoi(a, b, c, d):
    temp = 0
    while not (a == c and b == d) or (a/b > c/d):
        a, b = rutgon(a + 1, b + 1)
        temp += 1
        if a/b > c/d:
            return 0
    return temp

print(BienDoi(a, b, c, d))


''' '''
from adminEmployee import AdminEmployee
from commonEmployee import CommonEmployee
from client import Client
from items import Items

class System:
    def __init__(self):
        self.admin = AdminEmployee(first_name="Seu Tião", last_name="Meireles", id=0)
        # self.commonEmp = CommonEmployee(first_name="", last_name="", id=0)
        self.userLogged = None
        self.itemsContainer = []
        self.clientContainer = []
        self.employeeContainer = []
        self.running = False

    def authentication(self, login, password):
        pass

    def generateClientAndEmployees(self):
        #Insert employees
        self.employeeContainer.append(CommonEmployee(
            first_name = "Lucas",last_name =  "Natali", id = 990
        ))
        self.employeeContainer.append(CommonEmployee(
            first_name = "Geraldo", last_name = "Azevedo", id = 992
        ))
        self.employeeContainer.append(CommonEmployee(
            first_name = "Ademir",last_name =  "edivaldo", id = 993
        ))

        self.employeeContainer.append(CommonEmployee(
            first_name = "marlon", last_name = "ponei", id = 994
        ))

        '''Create Clients by Admin'''
        #Insert client 1
        self.clientContainer.append(Client(
            "Erika", "Oliveira",
            "888.225.763-72",
            "erika@email.com",
            "kkk8988"
        ))
        #Insert client 2
        self.clientContainer.append(Client(
            "Oswaldo", "Wiks",
            "992.888.111-82",
            "oswaldin@email.com",
            "xia"
        ))
        #Insert client 3
        self.clientContainer.append(Client(
            "Janaina", "Kristakens",
            "878.008.112-66",
            "janaina@email.com",
            "jana2222"
         ))

        self.clientContainer.append(Client(
            "Nicolas", "Oliveira",
            "888.288.223-72",
            "nicolas@email.com",
            "k--k"
        ))  #Insert client 4
        self.clientContainer.append(Client(
            "Mirella", "Wiks",
            "992.002.111-22",
            "mirella@email.com",
            "banana"
        )) #Insert client 5

        self.clientContainer.append(Client(
            "Eustaquio", "Kristakens",
            "118.008.212-66",
            "eustaquio@email.com",
            "sonho"
         ))  #Insert client 6

    def generateItems(self):
        self.itemsContainer.append(Items(
            name="item1",
            id_item=1,
            value=20,
            description="item top",
            status="available"
        ))
        self.itemsContainer.append(Items(
            name="item2",
            id_item=2,
            value=50,
            description="item fera",
            status="available"
        ))
        self.itemsContainer.append(Items(
            name="item3",
            id_item=3,
            value=990,
            description="item caro",
            status="available"
        ))
        self.itemsContainer.append(Items(
            name="item4",
            id_item=4,
            value=110.5,
            description="item show",
            status="available"
        ))

    def run(self):
        self.running = True
        while(self.running):
            option = input('----- LOGIN ----- \n'
                        + '(1) - Admin\n'
                        + '(2) - Funcionário\n'
                        + '(3) - Sair\n')

            if(option == "1"):
                self.userLogged = self.admin;
                self.userLogged.showMenu()
            elif(option == "2"):
                self.admin.listEmployees()
                func = input('Qual funcionário você é?')
                self.userLogged = self.employeeContainer[int(func)-1]
                self.userLogged.showMenu()
            else:
                quit()


import numpy as np
import matplotlib.pyplot as plt
import matplotlib
import matplotlib.gridspec as gridspec
from scipy import signal

matplotlib.rcParams['pdf.fonttype'] = 42
matplotlib.rcParams['svg.fonttype'] = 'none'

#%% script params

num_axons = 3
num_dendrites = 9

axon_colors = ['magenta', 'teal', 'purple']

num_spikes_per_axon = 3
experiment_time_ms  = 300

tau_rise_range  = [1,9]
tau_decay_range = [5,30]

v_reset     = -80
v_threshold = -55
current_to_voltage_mult_factor = 4
refreactory_time_constant = 25

save_figures = False
all_file_endings_to_use = ['.png', '.pdf', '.svg']

figure_folder = '/filter_and_fire_neuron/saved_figures/'

#%% helper functions

def create_single_PSP_profile(tau_rise, tau_decay, temporal_filter_length=50):

    if tau_rise >= tau_decay:
        tau_decay = tau_rise + 5

    exp_r = signal.exponential(M=temporal_filter_length, center=0, tau=tau_rise , sym=False)
    exp_d = signal.exponential(M=temporal_filter_length, center=0, tau=tau_decay, sym=False)

    post_syn_potential = exp_d - exp_r
    post_syn_potential /= post_syn_potential.max()

    return post_syn_potential

def construct_normlized_synaptic_filter(tau_rise_vec, tau_decay_vec):

    num_synapses = tau_rise_vec.shape[0]
    temporal_filter_length = int(7 * tau_decay_vec.max()) + 1

    syn_filter = np.zeros((num_synapses, temporal_filter_length))

    for k, (tau_r, tau_d) in enumerate(zip(tau_rise_vec, tau_decay_vec)):
        syn_filter[k,:] = create_single_PSP_profile(tau_r, tau_d, temporal_filter_length=temporal_filter_length)

    return syn_filter

def simulate_filter_and_fire_cell_training(presynaptic_input_spikes, synaptic_weights, tau_rise_vec, tau_decay_vec,
                                           refreactory_time_constant=20, v_reset=-75, v_threshold=-55, current_to_voltage_mult_factor=2):

    temporal_filter_length = int(5 * refreactory_time_constant) + 1
    refreactory_filter = signal.exponential(M=temporal_filter_length,center=0,tau=refreactory_time_constant,sym=False)[np.newaxis,:]

    # padd input and get all synaptic filters
    normlized_syn_filter = np.flipud(construct_normlized_synaptic_filter(tau_rise_vec, tau_decay_vec))
    padded_input = np.hstack((np.zeros(normlized_syn_filter.shape), presynaptic_input_spikes))

    # calc local currents
    local_normlized_currents = np.zeros(presynaptic_input_spikes.shape, dtype=np.float16)
    for k in range(normlized_syn_filter.shape[0]):
        local_normlized_currents[k] = signal.convolve(padded_input[k], normlized_syn_filter[k], mode='valid')[1:]

    # multiply by weights to get the somatic current
    soma_current = signal.convolve(local_normlized_currents, synaptic_weights, mode='valid')

    # simulate the cell
    soma_voltage = v_reset + current_to_voltage_mult_factor * soma_current.ravel()
    output_spike_times_in_ms = []
    # after a spike inject current that is exactly required to bring the cell back to v_reset (this current slowly decays)
    for t in range(len(soma_voltage)):
        # after a spike inject current that is exactly required to bring the cell back to v_reset (this current slowly decays)
        if (soma_voltage[t] > v_threshold) and ((t + 1) < len(soma_voltage)):
            t_start = t + 1
            t_end = min(len(soma_voltage), t_start + temporal_filter_length)
            soma_voltage[t_start:t_end] -= (soma_voltage[t + 1] - v_reset) * refreactory_filter.ravel()[:(t_end - t_start)]
            output_spike_times_in_ms.append(t)

    return local_normlized_currents, soma_voltage, output_spike_times_in_ms

def add_offset_for_plotting(traces_matrix, offset_size=1.1):

    traces_matrix_with_offset = offset_size * np.kron(np.arange(traces_matrix.shape[0])[:,np.newaxis], np.ones((1,traces_matrix.shape[1])))
    traces_matrix_with_offset = traces_matrix_with_offset + traces_matrix

    return traces_matrix_with_offset

#%% simulate the cell

connections_per_axon = int(num_dendrites / num_axons)
num_synapses = num_dendrites

tau_rise_vec  = np.linspace(tau_rise_range[0] , tau_rise_range[1] , num_synapses)[:,np.newaxis]
tau_decay_vec = np.linspace(tau_decay_range[0], tau_decay_range[1], num_synapses)[:,np.newaxis]

# synapse learnable parameters
synaptic_weights_vec = 1.0 + 0.1 * np.random.uniform(size=(num_synapses, 1))

synaptic_filters = construct_normlized_synaptic_filter(tau_rise_vec, tau_decay_vec)

#%% run once

# generate sample input
stimulus_duration_ms = experiment_time_ms

axon_input_spike_train = np.zeros((num_axons, stimulus_duration_ms))
for k in range(num_axons):
    curr_axon_spike_times = 20 + np.random.randint(stimulus_duration_ms -80, size=num_spikes_per_axon)
    axon_input_spike_train[k,curr_axon_spike_times] = 1.0

presynaptic_input_spikes = np.kron(np.ones((connections_per_axon,1), dtype=bool), axon_input_spike_train).astype(bool)

# simulate F&F cell with normlized currents
local_normlized_currents, soma_voltage, output_spike_times_in_ms = simulate_filter_and_fire_cell_training(presynaptic_input_spikes,
                                                                                synaptic_weights_vec, tau_rise_vec, tau_decay_vec,
                                                                                refreactory_time_constant=refreactory_time_constant,
                                                                                v_reset=v_reset, v_threshold=v_threshold,
                                                                                current_to_voltage_mult_factor=current_to_voltage_mult_factor)

local_normlized_currents = np.flipud(local_normlized_currents)

soma_voltage_with_spikes = soma_voltage
soma_voltage_with_spikes[output_spike_times_in_ms] = -25

max_local_added_voltage = add_offset_for_plotting(local_normlized_currents).T.max()

print('running once')

#%% run again until we have at least 1 spike

while len(output_spike_times_in_ms) != 1 or max_local_added_voltage > 10.15:
    axon_input_spike_train = np.zeros((num_axons, stimulus_duration_ms))
    for k in range(num_axons):
        curr_axon_spike_times = 30 + np.random.randint(stimulus_duration_ms -60, size=num_spikes_per_axon)
        axon_input_spike_train[k,curr_axon_spike_times] = 1.0

    presynaptic_input_spikes = np.kron(np.ones((connections_per_axon,1), dtype=bool), axon_input_spike_train).astype(bool)

    # simulate F&F cell with normlized currents
    local_normlized_currents, soma_voltage, output_spike_times_in_ms = simulate_filter_and_fire_cell_training(presynaptic_input_spikes,
                                                                                synaptic_weights_vec, tau_rise_vec, tau_decay_vec,
                                                                                refreactory_time_constant=refreactory_time_constant,
                                                                                v_reset=v_reset, v_threshold=v_threshold,
                                                                                current_to_voltage_mult_factor=current_to_voltage_mult_factor)

    local_normlized_currents = np.flipud(local_normlized_currents)

    soma_voltage_with_spikes = soma_voltage
    soma_voltage_with_spikes[output_spike_times_in_ms] = -15

    max_local_added_voltage = add_offset_for_plotting(local_normlized_currents).T.max()

print('there is at least 1 spike')

#%% run untill we have a changed enough spike location

min_spike_time_diff = 35
max_local_added_voltage = 0

while True:

    output_spike_times_in_ms =[]

    # generate input axons with a single spike
    while len(output_spike_times_in_ms) != 1 or max_local_added_voltage > 10.15:
        axon_input_spike_train = np.zeros((num_axons, stimulus_duration_ms))
        for k in range(num_axons):
            curr_axon_spike_times = 30 + np.random.randint(stimulus_duration_ms -60, size=num_spikes_per_axon)
            axon_input_spike_train[k,curr_axon_spike_times] = 1.0

        presynaptic_input_spikes = np.kron(np.ones((connections_per_axon,1), dtype=bool), axon_input_spike_train).astype(bool)

        # simulate F&F cell with normlized currents
        local_normlized_currents, soma_voltage, output_spike_times_in_ms = simulate_filter_and_fire_cell_training(presynaptic_input_spikes,
                                                                                synaptic_weights_vec, tau_rise_vec, tau_decay_vec,
                                                                                refreactory_time_constant=refreactory_time_constant,
                                                                                v_reset=v_reset, v_threshold=v_threshold,
                                                                                current_to_voltage_mult_factor=current_to_voltage_mult_factor)

        local_normlized_currents = np.flipud(local_normlized_currents)

        soma_voltage_with_spikes = soma_voltage
        soma_voltage_with_spikes[output_spike_times_in_ms] = -15

        max_local_added_voltage = add_offset_for_plotting(local_normlized_currents).T.max()

        if len(output_spike_times_in_ms) == 1 and (output_spike_times_in_ms[0] > 200 or output_spike_times_in_ms[0] < 120):
            output_spike_times_in_ms = []

    print('there is at least 1 spike, spike times: ', output_spike_times_in_ms)

    # generate a weights change that will move this spikes by a minimum amount
    mult_vector = np.random.permutation([0.25,0.5,0.5,0.75,1.25,1.5,1.75,1.75,2.0])[:,np.newaxis]
    synaptic_weights_vec_2 = mult_vector * synaptic_weights_vec

    # make sure only the a the middle axon weights are changed (for non cluttered visualization)
    synaptic_weights_vec_2[0::3] = synaptic_weights_vec[0::3]
    synaptic_weights_vec_2[2::3] = synaptic_weights_vec[2::3]
    mult_vector[0::3] = 1
    mult_vector[2::3] = 1

    # simulate F&F cell with normlized currents
    local_normlized_currents_2, soma_voltage_2, output_spike_times_in_ms_2 = simulate_filter_and_fire_cell_training(presynaptic_input_spikes,
                                                                                synaptic_weights_vec_2, tau_rise_vec, tau_decay_vec,
                                                                                refreactory_time_constant=refreactory_time_constant,
                                                                                v_reset=v_reset, v_threshold=v_threshold,
                                                                                current_to_voltage_mult_factor=current_to_voltage_mult_factor)

    local_normlized_currents_2 = np.flipud(local_normlized_currents_2)

    soma_voltage_with_spikes_2 = soma_voltage_2
    soma_voltage_with_spikes_2[output_spike_times_in_ms_2] = -15

    max_local_added_voltage_2 = add_offset_for_plotting(local_normlized_currents_2).T.max()

    local_normlized_currents_2 = mult_vector * local_normlized_currents_2

    if len(output_spike_times_in_ms_2) == 1 and ((output_spike_times_in_ms[0] - output_spike_times_in_ms_2[0]) <= -min_spike_time_diff):
        break

print('changed weights such that the spike changed location for more than %d ms' %(min_spike_time_diff))

#%% Display Input Axons, Synaptic Filters and Local Voltage Traces "Slopily"

plt.close('all')
fig = plt.figure(figsize=(20,8))
plt.subplots_adjust(left=0.03, right=0.97, top=0.95, bottom=0.05, wspace=0.25, hspace=0.35)

plt.subplot(1,3,1);
for k, axon_color in enumerate(axon_colors):
    plt.plot(add_offset_for_plotting(np.flipud(axon_input_spike_train)).T[:,k], color=axon_color); plt.title('Input Axons', fontsize=24);

plt.subplot(1,3,2);
for k, axon_color in enumerate(axon_colors):
    plt.plot(add_offset_for_plotting(synaptic_filters).T[:100,k::num_axons], color=axon_color); plt.title('Synaptic Filters', fontsize=24);

plt.subplot(1,3,3);
for k, axon_color in enumerate(axon_colors):
    plt.plot(add_offset_for_plotting(local_normlized_currents).T[:,k::num_axons], color=axon_color); plt.title('Synaptic Contact Voltage Contribution', fontsize=24);
    plt.plot(add_offset_for_plotting(local_normlized_currents_2).T[:,k::num_axons], color=axon_color, linestyle='dashed');

#%% plot one below each other

plt.close('all')
plt.figure(figsize=(10,25))
gs_figure = gridspec.GridSpec(nrows=11,ncols=1)
gs_figure.update(left=0.04, right=0.95, bottom=0.05, top=0.95, wspace=0.1, hspace=0.8)

ax_axons          = plt.subplot(gs_figure[:3,:])
ax_local_voltages = plt.subplot(gs_figure[3:9,:])
ax_soma_voltage   = plt.subplot(gs_figure[9:,:])

ax_axons.plot(add_offset_for_plotting(axon_input_spike_train).T); ax_axons.set_title('Input Axons', fontsize=24);
ax_local_voltages.plot(add_offset_for_plotting(local_normlized_currents).T); ax_local_voltages.set_title('Synaptic Contact Voltage Contribution', fontsize=24);
ax_local_voltages.plot(add_offset_for_plotting(local_normlized_currents_2).T, linestyle='dashed');
ax_soma_voltage.plot(soma_voltage_with_spikes); ax_soma_voltage.set_title('Somatic Voltage', fontsize=24);
ax_soma_voltage.plot(soma_voltage_with_spikes_2, linestyle='dashed');

#%% Display The Full Figure

plt.close('all')
fig = plt.figure(figsize=(25,18))
gs_figure = gridspec.GridSpec(nrows=11,ncols=30)
gs_figure.update(left=0.04, right=0.95, bottom=0.05, top=0.92, wspace=0.2, hspace=0.7)

ax_axons         = plt.subplot(gs_figure[2:6,:9])
ax_syn_filters   = plt.subplot(gs_figure[:8,13:17])
ax_local_voltges = plt.subplot(gs_figure[:8,21:])
ax_soma_voltage  = plt.subplot(gs_figure[8:,21:])

for k, axon_color in enumerate(axon_colors):
    ax_axons.plot(add_offset_for_plotting(np.flipud(axon_input_spike_train)).T[:,k], color=axon_color, lw=3);
ax_axons.set_yticks([])
ax_axons.set_xticks([])
ax_axons.set_title('Input Axons', fontsize=20);
ax_axons.spines['top'].set_visible(False)
ax_axons.spines['bottom'].set_visible(False)
ax_axons.spines['left'].set_visible(False)
ax_axons.spines['right'].set_visible(False)

for k, axon_color in enumerate(axon_colors):
    ax_syn_filters.plot(add_offset_for_plotting(synaptic_filters).T[:100,k::num_axons], color=axon_color, lw=3);
ax_syn_filters.set_yticks([])
ax_syn_filters.set_xticks([])
ax_syn_filters.set_title('Synaptic Filters', fontsize=20);
ax_syn_filters.spines['top'].set_visible(False)
ax_syn_filters.spines['bottom'].set_visible(False)
ax_syn_filters.spines['left'].set_visible(False)
ax_syn_filters.spines['right'].set_visible(False)

for k, axon_color in enumerate(axon_colors):
    ax_local_voltges.plot(add_offset_for_plotting(local_normlized_currents).T[:,k::num_axons], color=axon_color, lw=3);
    ax_local_voltges.plot(add_offset_for_plotting(local_normlized_currents_2).T[:,k::num_axons], color=axon_color, ls='dashed', lw=2.5);
ax_local_voltges.set_xticks([])
ax_local_voltges.set_yticks([])
ax_local_voltges.set_title('Synaptic Contact Voltage Contribution', fontsize=20);
ax_local_voltges.spines['top'].set_visible(False)
ax_local_voltges.spines['bottom'].set_visible(False)
ax_local_voltges.spines['left'].set_visible(False)
ax_local_voltges.spines['right'].set_visible(False)

ax_soma_voltage.plot(soma_voltage_with_spikes, color='0.1', lw=3, alpha=0.85);
ax_soma_voltage.plot(soma_voltage_with_spikes_2, color='dodgerblue', lw=3);
ax_soma_voltage.set_yticks([])
ax_soma_voltage.set_xticks([])
ax_soma_voltage.set_title('Somatic Voltage', fontsize=20);
ax_soma_voltage.spines['top'].set_visible(False)
ax_soma_voltage.spines['bottom'].set_visible(False)
ax_soma_voltage.spines['left'].set_visible(False)
ax_soma_voltage.spines['right'].set_visible(False)

# save figure
if save_figures:
    figure_name = 'F&F_A_Introduction_Figure_1_%d' %(np.random.randint(2000))
    for file_ending in all_file_endings_to_use:
        if file_ending == '.png':
            fig.savefig(figure_folder + figure_name + file_ending, bbox_inches='tight')
        else:
            fig.savefig(figure_folder + figure_name + file_ending, bbox_inches='tight')

#%%


import datetime
import gocept.amqparchive.testing
import gocept.amqprun.interfaces
import gocept.amqprun.testing
import gocept.testing.mock
import os
import shutil
import tempfile
import time
import zope.event

class IndexTest(gocept.amqparchive.testing.TestCase):

    def setUp(self):
        super(IndexTest, self).setUp()
        self.patches = gocept.testing.mock.Patches()

    def tearDown(self):
        self.patches.reset()
        super(IndexTest, self).tearDown()

    def create_message(self, body='<foo>testbody</foo>'):
        from gocept.amqprun.message import Message
        message = Message({}, body, routing_key='routing')
        message.header.message_id = 'myid'
        message.header.timestamp = time.mktime(
            datetime.datetime(2011, 7, 14, 14, 15).timetuple())
        return message

    def test_indexes_body_and_headers(self):
        message = self.create_message()
        zope.event.notify(gocept.amqprun.interfaces.MessageStored(
            message, '/foo/bar'))
        time.sleep(1)  # give elasticsearch time to settle
        result = self.elastic.search({'query': {'text': {'_all': 'foo'}}})
        hits = result['hits']
        self.assertEqual(1, hits['total'])
        item = hits['hits'][0]['_source']
        self.assertEqual('/foo/bar', item['path'])
        self.assertEqual('testbody', item['data']['foo'])
        self.assertEqual('myid', item['message_id'])

    def test_exceptions_are_logged_and_not_raised(self):
        message = self.create_message()
        index = self.patches.add_object(self.elastic, 'index')
        index.side_effect = RuntimeError('provoked')

        log_warning = self.patches.add_object(
            gocept.amqparchive.archive.log, 'warning')
        zope.event.notify(gocept.amqprun.interfaces.MessageStored(
            message, '/foo/bar'))
        self.assertTrue(log_warning.called)

    def test_invalid_xml_does_not_break_indexing(self):
        message = self.create_message('<qux')
        zope.event.notify(gocept.amqprun.interfaces.MessageStored(
            message, '/foo/bar'))
        time.sleep(1)  # give elasticsearch time to settle
        result = self.elastic.search({'query': {'text': {'_all': 'qux'}}})
        hits = result['hits']
        self.assertEqual(1, hits['total'])

class IndexIntegrationTest(gocept.amqprun.testing.MainTestCase,
                           gocept.amqparchive.testing.ElasticHelper):

    level = 3
    layer = gocept.amqparchive.testing.QUEUE_LAYER

    def setUp(self):
        super(IndexIntegrationTest, self).setUp()
        self.tmpdir = tempfile.mkdtemp()

    def tearDown(self):
        shutil.rmtree(self.tmpdir)
        super(IndexIntegrationTest, self).tearDown()

    def test_message_should_be_indexed(self):
        self.make_config(__name__, 'index', mapping=dict(
            routing_key='test.data',
            directory=self.tmpdir,
            queue_name=self.get_queue_name('test'),
            pattern='foo/bar/baz.xml',
            elastic_hostname=os.environ['ELASTIC_HOSTNAME']))
        self.start_server()

        body = '<foo>This is only a test.</foo>'
        self.send_message(body, routing_key='test.data')
        self.wait_for_processing()
        # we're concurrent to the handler and we seem to be too fast
        time.sleep(2)

        self.assertEqual(
            2, len(os.listdir(os.path.join(self.tmpdir, 'foo', 'bar'))))
        result = self.elastic.search({'query': {'text': {'_all': 'only'}}})
        self.assertEqual(1, result['hits']['total'])
        hit = result['hits']['hits'][0]
        self.assertEqual('foo/bar/baz.xml', hit['_source']['path'])


def part1(data, lim=2020):
    locations = {}
    # first pass through the data
    for i in range(len(data)-1):
        locations[data[i]] = i

    # Then start iterating
    curr = data[-1]
    for i in range(len(data)-1, lim):
        prev = curr
        if curr in locations.keys():
            curr = i - locations[curr]
        else:
            curr = 0
        locations[prev] = i
    return prev

if __name__ == "__main__":
    example = [0, 3, 6]
    idata = [0, 14, 1, 3, 7, 9]
    print("Part 1:", part1(idata))
    print("Part 2:", part1(idata, 30000000))


import re

with open("input/05", "r") as f:
    indata = f.read().split('\n')

terrain1 = [[0] * 1000 for x in range(1000)]
terrain2 = [[0] * 1000 for x in range(1000)]
for row in indata:
    if re.findall(r'\d+', row):
        x1, y1, x2, y2 = [int(x) for x in re.findall(r'\d+', row)]
        if x1 == x2: #vertical
            for y in range(min(y1,y2), max(y1,y2)+1):
                terrain1[y][x1] += 1
                terrain2[y][x1] += 1
        elif y1 == y2: #horizontal
            for x in range(min(x1,x2), max(x1,x2)+1):
                terrain1[y1][x] += 1
                terrain2[y1][x] += 1
        else: #diagonal
            x_coords = [x for x in range(min(x1, x2), max(x1,x2)+1)]
            if x1 > x2:
                x_coords = x_coords[::-1]
            y_coords = [y for y in range(min(y1, y2), max(y1,y2)+1)]
            if y1 > y2:
                y_coords = y_coords[::-1]
            for i in range(len(x_coords)):
                x = x_coords[i]
                y = y_coords[i]
                terrain2[y][x] += 1

def count_dangerous(terrain):
    dangerous_tiles = 0
    for row in terrain:
        for tile in row:
            if tile >= 2:
                dangerous_tiles += 1
    return dangerous_tiles

print(f"part1: {count_dangerous(terrain1)}")
print(f"part2: {count_dangerous(terrain2)}")


# 주어진 x, y 포인트들(Points)은 좌표 평면에서 서로 직선으로 연결되어 있습니다. 이것을 바탕으로 X 좌표에 상응하는 Y값을 반환하세요.
# ex: x가 8일때 y는 1
# 정근님 코드 보고 깨달은 바대로 함수안의 함수를 써서 데이터양과 계산량 줄이기, 이전 코드는 데이터를 미리 다 만들고 거기서 계산
# 이 방법은 x가 들어오는 것을 보고 x에 대응하는 값을 계산
x = 0
points = [[0, 5],[2, 3],[6,2],[10,0]]
def usv_attenuation_graph(x, points): # x와 Points 를 입력시 y 값을 return 하는 함수
    def slope (x1, x2, y1, y2): # y 증가량 / x 증가량 = 기울기
        return (y2 - y1) / (x2 - x1)
    for i in range(len(points)): # Points의 length의 값 만큼 반복
        if x >= points[i][0] and x < points[i+1][0]:
            y = (x - points[i][0]) * slope(points[i][0], points[i+1][0], points[i][1], points[i+1][1]) + points[i][1]
            # x가 8이라면 y = (8-6)*-0.5 + 2 = -1 + 2 = 1
            # x의 증가량에 y의 증가량의 비율(slope)을 구해서 x의 증가량에 대응하는 y의 증가량을 구해서 x가 증가하기 전 값에 대응하는 y가 증가하기 전 값에 더해주기
            return print(y)
usv_attenuation_graph(8 ,points)

# 아래는 원래 코드
def usv_attenuation_graph_original(x, points): # x와 Points 를 입력시 y 값을 return 하는 함수
    index = 0 # for 돌리기 위한 index
    slope = [] # 기울기를 담을 빈 리스트
    x_points = [] # 기울기 코드 돌리기 위한 x 리스트
    y_points = [] # y 리스트
    for i in range(len(points)): # Points의 length의 값 만큼 반복
        x_points.append(points[index][0])
        y_points.append(points[index][1])
        if index + 1 == len(points) : break
        # 다만 아래부터는 index + 1의 값이 list 너머의 값으로 나올 수 있기에 에러 방지차 len 넘기면 break
        slope.append((points[index + 1][1] - points[index][1]) / (points[index + 1][0] - points[index][0]))
        index = index + 1
    if x >= points[0][0] and x < points[1][0]: n = 0
    elif x >= points[1][0] and x < points[2][0]: n = 1
    elif x >= points[2][0] and x < points[3][0]: n = 2
    elif x == points[3][0] : n = 3
    # 조건문을 매끄럽게 할 수 있는 방법 알아보자
    y = (x - points[n][0]) * slope[n] + points[n][1]
    return print(y)
usv_attenuation_graph_original(8 ,points)


import pygame, sys, playgo
import config as c
import draw
from pygame.locals import *

def displayGame(gridsize, player1, player2, DISPLAY, FPSCLOCK):
	score_file = open("scores.txt", 'r+')
	words = score_file.read()
	DISPLAY.fill(c.TAN)

	if player1.resigned:
		winner = player2.name
	else:
		winner = player1.name

	gameOverLabel = draw.Label(c.STARTSCREENFONT, 45, False, " Game Over ", c.BLACK, 0.5, 0.3)
	winnerLabel = draw.Label(c.STARTSCREENFONT, 45, False,  winner + "wins!", c.BLACK, 0.5, .5, 0,)

	newGameLabel = draw.Label(c.STARTSCREENFONT, 30, False, " New Game ", c.BLACK, 0.5, .8, -150, 0)
	newGameLabel.drawRect(DISPLAY, c.WHITE, 100, 200, 0)
	newGameLabel.drawRect(DISPLAY, c.BLACK, 101, 201, 1)

	quitLabel = draw.Label(c.STARTSCREENFONT, 30, False, "     Quit     ", c.BLACK, 0.5, .8, 150, 0)
	quitLabel.drawRect(DISPLAY, c.WHITE, 100, 200, 0)
	quitLabel.drawRect(DISPLAY, c.BLACK, 101, 201, 1)

	DISPLAY.blit(gameOverLabel.labelText, gameOverLabel.labelRect)
	DISPLAY.blit(winnerLabel.labelText, winnerLabel.labelRect)
	DISPLAY.blit(newGameLabel.labelText, newGameLabel.labelRect)
	DISPLAY.blit(quitLabel.labelText, quitLabel.labelRect)

	newGame = False
	cont = True
	while cont:
		mousePress = False
		for event in pygame.event.get():
			if event.type == MOUSEBUTTONUP:
				if event.button == 1:
					mousex, mousey = event.pos
					mousePress = True
			elif event.type == MOUSEMOTION:
					mousex, mousey = event.pos
			elif event.type == KEYUP:
				if event.key == K_ESCAPE:
					pygame.quit()
					sys.exit()

		if mousePress:
			if newGameLabel.labelRect.collidepoint(mousex, mousey):
				newGame = True
				cont = False
			elif quitLabel.labelRect.collidepoint(mousex, mousey):
				newGame = False
				cont = False

		pygame.display.update()

	return newGame


import pathlib
import numpy as np
from scipy.interpolate import RegularGridInterpolator

class Ppm():

    def __init__(self):
        self.data = None
        self.ijks = None
        self.normals = None
        self.ijk_interpolator = None
        self.normal_interpolator = None
        self.data_header = None
        self.valid = False
        self.error = "no error message set"

    def createErrorPpm(err):
        ppm = Ppm()
        ppm.error = err
        return ppm

    no_data = (0.,0.,0.)

    # lijk (layer ijk) is in layer's global coordinates
    def layerIjksToScrollIjks(self, lijks):
        print("litsi")
        if self.data is None:
            print("litsi no data")
            return lijks
        '''
        li,lj,lk = lijk
        if li < 0 or lj < 0:
            return Ppm.no_data
        if li >= self.width:
            return Ppm.no_data
        if lj >= self.height:
            return Ppm.no_data
        '''
        # sijk = np.zeros((lijk.shape), dtype=lijk.dtype)
        # sijks = self.ijk_interpolator(lijks[:,0:2])
        ijs = lijks[:,(2,0)]
        ks = lijks[:,1,np.newaxis]
        sijks = self.ijk_interpolator(ijs)
        norms = self.normal_interpolator(ijs)
        print(lijks.shape, sijks.shape, norms.shape, ks.shape)
        sijks += norms*(ks-32)
        return sijks

    def loadData(self):
        if self.data is not None:
            rturn
        print("reading data from %s for %s"%(str(self.path), self.name))

        fstr = str(self.path)
        print("reading ppm data for", self.path)
        if not self.path.exists():
            err="ppm file %s does not exist"%fstr
            print(err)
            return Ppm.createErrorPpm(err)

        try:
            fd = self.path.open("rb")
        except Exception as e:
            err="Failed to open ppm file %s: %s"%(fstr, e)
            print(err)
            return Ppm.createErrorPpm(err)

        try:
            bdata = fd.read()
        except Exception as e:
            err="Failed to read ppm file %s: %s"%(fstr, e)
            print(err)
            return Ppm.createErrorPpm(err)

        index = bdata.find(b'<>\n')
        if index < 0:
            err="Ppm file %s does not have a header"%fstr
            print(err)
            return Ppm.createErrorPpm(err)

        bdata = bdata[index+3:]
        lbd = len(bdata)
        height = self.height
        width = self.width
        le = height*width*8*6
        if lbd != le:
            err="Ppm file %s expected %d bytes of data, got %d"%(fstr, le, lbd)
            print(err)
            return Ppm.createErrorPpm(err)

        raw = np.frombuffer(bdata, dtype=np.float64)
        self.data = np.reshape(raw, (height,width,6))
        self.ijks = self.data[:,:,:3]
        self.normals = self.data[:,:,3:]
        print(self.ijks.shape, self.normals.shape)
        # print(self.ijks[0,0,:],self.normals[0,0,:])
        # print(self.ijks[3000,3000,:],self.normals[3000,3000,:])
        ii = np.arange(height)
        jj = np.arange(width)
        self.ijk_interpolator = RegularGridInterpolator((ii, jj), self.ijks, fill_value=0., bounds_error=False)
        self.normal_interpolator = RegularGridInterpolator((ii, jj), self.normals, fill_value=0., bounds_error=False)

    # reads and loads the header of the ppm file
    def loadPpm(filename):
        fstr = str(filename)
        print("reading ppm header for", filename)
        if not filename.exists():
            err="ppm file %s does not exist"%fstr
            print(err)
            return Ppm.createErrorPpm(err)

        try:
            fd = filename.open("rb")
        except Exception as e:
            err="Failed to open ppm file %s: %s"%(fstr, e)
            print(err)
            return Ppm.createErrorPpm(err)

        try:
            bstr = fd.read(200)
        except Exception as e:
            err="Failed to read ppm file %s: %s"%(fstr, e)
            print(err)
            return Ppm.createErrorPpm(err)

        index = bstr.find(b'<>\n')
        if index < 0:
            err="Ppm file %s does not have a header"%fstr
            print(err)
            return Ppm.createErrorPpm(err)

        hstr = bstr[:index+3].decode('utf-8')
        lines = hstr.split('\n')
        hdict = {}
        for line in lines:
            words = line.split()
            if len(words) != 2:
                continue
            name = words[0]
            value = words[1]
            if name[-1] != ':':
                continue
            name = name[:-1]
            hdict[name] = value
        for name in ["width", "height"]:
            if name not in hdict:
                err="Ppm file %s missing \"%s\" in header"%(fstr, name)
                print(err)
                return Ppm.createErrorPpm(err)

        try:
            width = int(hdict["width"])
        except Exception as e:
            err="Ppm file %s could not parse width value \"%s\" in header"%(fstr, hdict["width"])
            print(err)
            return Ppm.createErrorPpm(err)

        try:
            height = int(hdict["height"])
        except Exception as e:
            err="Ppm file %s could not parse height value \"%s\" in header"%(fstr, hdict["height"])
            print(err)
            return Ppm.createErrorPpm(err)

        expected = {
                "dim": "6",
                "ordered": "true",
                "type": "double",
                "version": "1",
                }

        for name, value in expected.items():
            if name not in hdict:
                err = "Ppm file %s missing \"%s\" from header"%(fstr, name)
                print(err)
                return Ppm.createErrorPpm(err)
            if hdict[name] != expected[name]:
                err = "Ppm file %s expected value of \"%s\" for \"%s\" in header; got %s"%(fstr, expected[name], name, hdict[name])
                print(err)
                return Ppm.createErrorPpm(err)

        ppm = Ppm()
        ppm.valid = True
        ppm.height = height
        ppm.width = width
        ppm.path = filename
        ppm.name = filename.stem
        print("created ppm %s width %d height %d"%(ppm.name, ppm.width, ppm.height))
        return ppm


from bs4 import BeautifulSoup
import requests

def matching_words(string_1, string_2):
    count = 0
    string_1 = string_1.split()

    for word in string_1:
        if word in string_2:
            count += 1
    return count

def good_match(string, num_matching_words):
    string = string.split()
    str_len = len(string)
    if str_len > 0:
        percent =(float(num_matching_words)*100/float(str_len))
        if percent >= 50:
            return True
    return False

def get_data(url):
    try:
        result      = requests.get(url)
        soup        = BeautifulSoup(result.text, "html.parser")
        thumbnails  = []
        title       = ""

        if "amazon.com" in url:
            soup_title  = soup.find("span",id="productTitle")
            soup_img    = soup.find_all("img", id="landingImage")

            if not soup_img:
                return {"error":1,"data":{},"message":"Unable to extract images."}
            else:
                for img in soup_img:
                    if img["src"] not in thumbnails:
                        thumbnails.append(img["src"])

                if soup_title:
                    title = soup_title.string

            return {"error":None,"data":{"title":title, "thumbnails":thumbnails},"message":"Success"}

        elif "ebay.com" in url:
            soup_title = soup.find("h1", id="itemTitle")
            soup_img = soup.find_all("img", id="icImg")

            if not soup_img:
                return {"error":1,"data":{},"message":"Unable to extract images."}
            else:
                for img in soup_img:
                    if img["src"] not in thumbnails:
                        thumbnails.append(img["src"])

                if soup_title:
                    children = []
                    for child in soup_title.children:
                        children.append(child)
                    title = children[1]

            return {"error":None,"data":{"title":title, "thumbnails":thumbnails},"message":"Success"}

        else:
            title = soup.title.string
            for img in soup.find_all("img", alt=True):
                alt = img['alt']
                src = img['src']
                numMatchingWords = matching_words(title,alt)
                if good_match(alt, numMatchingWords):
                    if src not in thumbnails and src[-4:]==".jpg" and "sprite" not in src:
                        thumbnails.append(src)

            if not thumbnails:
                for img in soup.findAll("img", src=True):
                    if "sprite" not in img["src"] and src[-4:]==".jpg":
                        thumbnails.append(img["src"])

            if not thumbnails:
                return {"error":1,"data":{},"message":"Unable to extract images."}

            return {"error":None,"data":{"title":title, "thumbnails":thumbnails},"message":"Success"}

    except requests.exceptions.RequestException:
        return {"error":2,"data":{},"message":"URL entered is invalid."}

url1 = "http://www.ebay.com/itm/ROLEX-Day-Date-II-Presidential-w-Factory-Diamond-Bezel-Dial-218348-/172103028001?hash=item281223cd21:g:gRcAAOSwezVWwhkv"
url2 = "http://intl.target.com/p/mr-coffee-cafe-barista-bvmc-ecmp1000/-/A-14575718#prodSlot=_1_8"
url3 = "http://www.amazon.com/gp/product/B00THKEKEQ/ref=s9_ri_gw_g421_i1_r?ie=UTF8&fpl=fresh&pf_rd_m=ATVPDKIKX0DER&pf_rd_s=desktop-4&pf_rd_r=1WEK74K6Y8MXQC6BSHDN&pf_rd_t=36701&pf_rd_p=2437869562&pf_rd_i=desktop"
url4 = "http://www.amazon.com/gp/product/B012GC5DX8/ref=s9_qpp_gw_d38_g107_i1_r?ie=UTF8&fpl=fresh&pf_rd_m=ATVPDKIKX0DER&pf_rd_s=desktop-1&pf_rd_r=0HX3HCEVK96HB5FDXMV0&pf_rd_t=36701&pf_rd_p=2437869742&pf_rd_i=desktop"
url5 = "http://www.ebay.com/itm/Lamborghini-Aventador-LP-750-4-SV-/231914556159?forcerrptr=true&hash=item35ff2f4aff:g:4ckAAOSwiYFXESqj&item=231914556159"
url6 = "http://www.amazon.com/Hifonics-ZRX2416-1D-Block-Vehicle-Amplifier/dp/B00T3VMTPQ?ie=UTF8&refRID=PX2YE82MNZZBNBDCRWSS&ref_=pd_ybh_a_1"
url7 = "http://www.amazon.com/Power-Acoustik-GW312-1200WATT-2500WATT/dp/B00B7C077G?ie=UTF8&psc=1&redirect=true&ref_=ox_sc_sfl_title_5&smid=A35DL6C7BAXYRR"
url8 = "http://www.ebay.com/itm/Apple-12-MacBook-Intel-Core-M-1-1GHz-8GB-RAM-256GB-Flash-Early-2015-Gold/262417285736?hash=item3d194a0268&_trkparms=5374%3AFeatured%7C5373%3A0"

#print get_data(url1)
#print get_data(url2)
#print get_data(url3)
#print get_data(url4)
#print get_data(url5)
#print get_data(url6)
#print get_data(url7)
#print get_data(url8)


from ising import IMul, PICircuit
from spinspace import Spin, Spinspace
from ortools.linear_solver import pywraplp

def test_set_aux(circuit, aux):
    circuit.set_aux(aux)
    for s in circuit.inspace:
        print(
            f"input {s} has aux {circuit.faux(s).spin()} which matches {aux[0][s.asint()]}: {circuit.faux(s).asint() == aux[0][s.asint()]}"
        )
        if circuit.faux(s):
            circuit.faux(s).asint() == aux[0][s.asint()]

if __name__ == "__main__":
    circuit = IMul(2, 2)
    with open("data/all_feasible_MUL_2x2x1.dat") as file:
        tally = 0
        for line in file:
            aux = [json.loads(line)[0]]
            print(aux)
            test_aux_array(aux)


"""
[STEPIK]
Python: основы и применение https://stepik.org/512
03_04_01 Распространённые форматы текстовых файлов: CSV, JSON
"""

"""
Вам дана частичная выборка из датасета зафиксированных преступлений, совершенных в городе Чикаго с 2001 года
по настоящее время.

Одним из атрибутов преступления является его тип – Primary Type.

Вам необходимо узнать тип преступления, которое было зафиксировано максимальное число раз в 2015 году.

Файл с данными:
Crimes.csv
"""

import csv
import time

YEAR = 2015

crimes_in_2015 = list()
with open('03_04_01.csv') as csv_file:
    reader = csv.DictReader(csv_file)
    for row in reader:
        if time.strptime(row.get('Date'), '%m/%d/%Y %I:%M:%S %p').tm_year == YEAR:
            crimes_in_2015.append(row)

crimes_by_type = dict()
for crime in crimes_in_2015:
    crime_type = crime.get('Primary Type')
    if not crimes_by_type.get(crime_type):
        crimes_by_type[crime_type] = list()
    crimes_by_type[crime_type].append(crime)

counted_crime_types = dict()
for crime_type in crimes_by_type:
    counted_crime_types[crime_type] = len(crimes_by_type[crime_type])

print(f'Most common crime in Chicago in year {YEAR}:')
print(max(counted_crime_types, key=counted_crime_types.get))


'''
# 수들의 합
서로 다른 N개의 자연수의 합이 S라고 한다. S를 알 때, 자연수 N의 최댓값은 얼마일까?

[입력]
첫째 줄에 자연수 S(1 ≤ S ≤ 4,294,967,295)가 주어진다.

[출력]
첫째 줄에 자연수 N의 최댓값을 출력한다.

[예제 입력]
200

[예제 출력]
19
'''

S = int(input())
step = 1
while True:
    if S >= step:
        S -= step
    else:
        step -= 1
        break
    step += 1
print(step)


n = int(input())
m = [int(x) for x in input().split()]

e, o = [], []
for i in range(n):
    if m[i] % 2:
        o.append(i+1)
    else:
        e.append(i+1)
if len(e) == 1:
    print(e[0])
else:
    print(o[0])

# https://codeforces.com/problemset/problem/25/A


import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(0,5,11)
y = x ** 2

fig, axes = plt.subplots(nrows=2, ncols=1)
axes[0].plot(y,x)

plt.show()

fig = plt.figure(figsize=(3,2), dpi=100)
ax = fig.add_axes([0,0,1,1])
ax.plot(x,y)

plt.show()
# or

# fig, axes = plt.subplots(nrows=2, ncols=1, figsize=(8,2))
# axes[0].plot(x,y)
# axes[1].plot(y,x)

fig = plt.figure()
# fig.savefig('my_fig.png', dpi=100)
ax = fig.add_axes([0,0,1,1])
ax.set_title('My title')
ax.set_ylabel('Y label')
ax.set_xlabel('X label')
ax.plot(x,y)

# plt.tight_layout()

plt.show()


# https://inf-ege.sdamgia.ru/problem?id=41002  86097
""" Дана последовательность целых чисел.
Необходимо найти максимально возможную сумму
её непрерывной подпоследовательности, в которой
количество положительных нечётных элементов кратно k=30."""

with open("./27-A.txt") as f:
    nums = list(map(int, f.readlines()))
n = nums[0]
nums = nums[1:n+1]
max_sm = -999999999
for i in range(n-1):
    for j in range(i+1, n):
        cnt = len(list(filter(lambda x: (x%2==1 and x>0), nums[i:j])))
        if cnt%30==0:
            sm = sum(nums[i:j])
            max_sm = max(max_sm, sm)
print(max_sm)


def acc(info,select_list,layer):

    id_resutlt = []
    result_result = []
    all_result = []

    for j in range(layer):
        id = []
        result = []
        for i in range(len(info[j]['ground'])):
            if i in select_list:
                c1 = info[j]['classify'][i]['label']
                c2 = info[j]['ground'][i]['label']
                if(c1 == "1 star" or c1 == "2 stars" or c1 =="3 stars"):
                    if(c2==0):
                        result.append(1)
                        id.append(i)
                    else:
                        result.append(0)
                if(c1=="4 stars" or c1=="5 stars"):
                    if(c2==1):
                        result.append(1)
                        id.append(i)
                    else:
                        result.append(0)

        total = 0
        for i in result:
            total +=i

        acc = total / len(result)
        acc = round(acc,2)
        result_result.append([acc,j])

        id_resutlt.append(id)

    all_result = [result_result,id_resutlt]
    all_result = {"accuracy":result_result,"true_selection":id_resutlt}
    print(all_result)

    return  all_result

def CountAvgScore(info,select_list,layer,key):

    result = []
    for j in range(layer):
        score = 0
        for i in select_list:
            score +=info[j][key][i]
        avg = score/len(select_list)
        result.append([avg,j])

    print(result)

    return result

def pos_count(data):
    result = {}
    for word in data :
        result.setdefault(word,0)
        result[word] = result[word]+1
    return result

def pos_count_select(select,data,layer):
    all_result = []

    for j in range(layer):
        result = {}
        d3_result=[]
        for index,item in enumerate(data):
            if index in select[j]:
               for key in item.keys():
                   result.setdefault(key,0)
                   result[key] = result[key]+item[key]
        for key in result.keys():
            d3_result.append({"pos":key,"amount":result[key]})

        all_result.append(d3_result)
        print(all_result)
    return all_result


# -*- coding: utf-8 -*-
from django.contrib import admin
from models import Category, Photo

class PhotoInline(admin.TabularInline):
    list_display = ('image', )
    model = Photo
    extra = 10

class CategoryAdmin(admin.ModelAdmin):
    inlines = [ PhotoInline, ]
    list_display = ('title', 'year')

admin.site.register(Category, CategoryAdmin)


import urllib2
import re
from urlparse import urlparse
from HTMLParser import HTMLParser

# parse unsecure cam urls from insecam.org
# no other way to do this ?

# Fake user agent to avoid 403
HEADERS = {'User-Agent' : 'Magic Browser'}
BASE_URL = "https://www.insecam.org"

NEWEST_PAGE = "/en/bynew/"
MOST_P_PAGE = "/en/byrating/"

NUMBER_PER_PAGE = 6
PAGINATION_PARAM = "?page="

# define our own html insecam parser
class CamUrlParser(HTMLParser):

	cam_urls = []

	def handle_starttag(self, tag, attrs):
		attrs = dict(attrs)
		if self.is_cam_img(tag, attrs):
			self.cam_urls.append(self.parse_url(attrs["src"]))

	def is_cam_img(self, tag, attrs):
		if tag != 'img':
			return False
		if not "class" in attrs or "thumbnail-item__img" not in attrs["class"]:
			return False
		return True

	# specific url parsing
	def parse_url(self, url):
		if "/mjpg/video.mjpg" in url:
			url = re.sub("/mjpg/video.mjpg", "/jpg/image.jpg", url)
		return url

# get x newest cam from insecam
def get_newest_cam_urls(n):
	return get_cam_urls(n, NEWEST_PAGE)

# get x best cam from insecam
def get_best_cam_urls(n):
	return get_cam_urls(n, MOST_P_PAGE)

# get x cam urls from insecam
def get_cam_urls(n, which):

	html_parser = CamUrlParser()

	page = 1
	while len(html_parser.cam_urls) < n:

		http_request = urllib2.Request(url=BASE_URL + which + PAGINATION_PARAM + str(page), headers=HEADERS)
		html_content = urllib2.urlopen(http_request).read()

		html_parser.feed(html_content)
		page += 1

	return html_parser.cam_urls


# -*- coding: utf-8 -*-
# #############################################################################
#
# John Winston Viloria Amaris.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
# #############################################################################
from openerp import models, fields, api
from openerp.exceptions import ValidationError
from openerp.tools.translate import _

class MedicalPatientRecord(models.Model):
    '''
    Patient Medical Record.
    '''
    _name = 'medical.patient.record'
    _order = 'id desc'
    _rec_name = 'code'

    @api.one
    @api.constrains('code')
    def _check_unique_code(self):
        if len(self.search([('code', '=', self.code)])) > 1:
            raise ValidationError(_("Medical Record already exists and violates unique field constraint"))

    @api.model
    def create(self, vals):
        vals['is_created'] = True
        new_obj = super(MedicalPatientRecord, self).create(vals)
        patient = self.env['medical.patient'].browse(vals['patient_id'])
        patient.emr_id = new_obj.id
        return new_obj

    code = fields.Char(related='patient_id.ref',
        string='Record Number', store=True)
    patient_name = fields.Char(related='patient_id.name',
    	string ='Patient Name')
    evaluation_ids = fields.One2many(comodel_name='medical.patient.evaluation',
    	inverse_name='emr_id',
        string='Evaluations')
    patient_id = fields.Many2one('medical.patient',
        string='Patient', required=True)
    date = fields.Datetime(string='Create Date',
    	default=lambda self: fields.Datetime.now())
    is_created = fields.Boolean('Created', default=False)


N, K = map(int, input().split())
H = []
for _ in range(N):
    H.append(int(input()))
INF = float('inf')

H.sort()
ans = INF
for i in range(K-1, N):
    ans = min(ans, H[i] - H[i-K+1])

print(ans)


from num2words import num2words

from odoo import models, tools

CURRENCY_NAME = {"Dollars": "ดอลลาร์", "Euros": "ยูโร", "Cents": "เซนต์"}

class Currency(models.Model):
    _inherit = "res.currency"

    def _convert_currency_name_hook(self, label):
        """Hooks to add currency translate.
        Currently, there are 2 currency are USD and EUR"""
        return CURRENCY_NAME[label]

    def amount_to_text(self, amount):
        self.ensure_one()
        lang_code = self.env.context.get("lang") or False
        if lang_code != "th_TH":
            return super().amount_to_text(amount)

        def _num2words(number, lang):
            try:
                return num2words(number, lang=lang).title()
            except NotImplementedError:
                return num2words(number, lang="en").title()

        formatted = "%.{}f".format(self.decimal_places) % amount
        parts = formatted.partition(".")
        integer_value = int(parts[0])
        fractional_value = int(parts[2] or 0)
        lang = (
            self.env["res.lang"]
            .with_context(active_test=False)
            .search([("code", "=", lang_code)])
        )
        # Thai Text with Thai Currency
        if self.name == "THB":
            try:
                return num2words(amount, to="currency", lang=lang.iso_code)
            except NotImplementedError:
                return num2words(amount, to="currency", lang="en")
        # Thai Text with Foreign currency
        currency_unit_label = self._convert_currency_name_hook(self.currency_unit_label)
        amount_words = tools.ustr("{amt_value}{amt_word}").format(
            amt_value=_num2words(integer_value, lang=lang.iso_code),
            amt_word=currency_unit_label,
        )
        if not self.is_zero(amount - integer_value):
            currency_subunit_label = self._convert_currency_name_hook(
                self.currency_subunit_label
            )
            amount_words += tools.ustr("{amt_value}{amt_word}").format(
                amt_value=_num2words(fractional_value, lang=lang.iso_code),
                amt_word=currency_subunit_label,
            )
        return amount_words


from rest_framework import serializers
from users.models import User
from django.contrib.auth import get_user_model
from game.models import LeaderBoard, Round
from game.serializers import LeaderBoardSerializer

class CreateUserSerializer(serializers.ModelSerializer):

    class Meta:
        model = User
        extra_kwargs = {
            'password': {'write_only': True},
            'date_joined': {'read_only': True},
        }
        fields = (
            'id',
            'email',
            'username',
            'date_joined',
            'password',
            'is_superuser',
        )

    def create(self, validated_data):
        user = get_user_model()

        if validated_data.pop('is_superuser', False):
            return user.objects.create_superuser(**validated_data)
        else:
            user_instance = user.objects.create_user(**validated_data)
            first_round = Round.objects.filter(number=1).first()
            LeaderBoard.objects.create(
                user = user_instance,
                round = first_round
            )
            return user_instance

class LeaderBoardListing(serializers.RelatedField):

    obj = {}

    def to_representation(self, value):
        self.obj['round_id'] = value.id
        return self.obj

class UserSerializer(serializers.ModelSerializer):

    current_round = serializers.ReadOnlyField(source='leaderboard.round.number', read_only=True)
    date_joined = serializers.DateTimeField(format="%Y-%m-%d")

    class Meta:
        model = User
        extra_kwargs = {
            'email': {'read_only': True},
            'id': {'read_only': True},
            'date_joined': {'read_only': True},
        }
        fields = (
            'id',
            'first_name',
            'username',
            'avatar',
            'email',
            'auth_token',
            'date_joined',
            'current_round',
        )

class AccessTokenSerializer(serializers.Serializer):

    access_token = serializers.CharField(label="Access Token")


# 暴力解法+分类讨论，非KMP
class Solution:
    def repeatedStringMatch(self, a: str, b: str) -> int:
        aS, bS = set(a), set(b)
        if aS & bS != bS: return -1

        times = math.ceil(len(b) / len(a))
        if (b in a*times): return times
        elif (b in a*(times+1)): return times+1
        else: return -1


class distance:
    def __init__(self,km1:int):
        self.km = km1
    def __ge__(self, km2):
        val1 = self.km*12
        val2 = km2.km*12
        if val1>=val2:
            return True
        else:
            return False

if __name__ == "__main__":
    d1 = distance(2)
    d2 = distance(4)
    print(d1>=d2)

    #interesant

First Year/Semester 1/Fundamentals of Programming/theory and experiments/magic methods/ge.py


import requests
import bs4
import re
import json
import urllib.parse
import threading

baseUrl = "https://www.luogu.com.cn/problem/list?ProblemListParams&page="

def requestToLuogu(url):
    headers = {
        "authority":"www.luogu.com.cn",
        "method":"GET",
        "path":"/problem/P8000",
        "scheme":"https",
        "Accept":"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7",
        "Accept-Encoding":"gzip, deflate, br",
        "Accept-Language":"zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6",
        "Cookie":"__client_id=a9a7f6dc9a1733e681d82f395f7d12d740413ff7; _uid=1088102; C3VK=195332",
        "Referer":"https://www.luogu.com.cn/",
        #"Sec-Ch-Ua":"Chromium";v="116", "Not)A;Brand";v="24", "Microsoft Edge";v="116"
        #Sec-Ch-Ua-Mobile:?0
        #Sec-Ch-Ua-Platform:"Windows"
        #Sec-Fetch-Dest:document
        #Sec-Fetch-Mode:navigate
        #Sec-Fetch-Site:same-origin
        #Sec-Fetch-User:?1
        "Upgrade-Insecure-Requests":"1",
        "User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36 Edg/116.0.1938.76"
    }
    r = requests.get(url = url,headers = headers)
    #用Unicode格式解码
    #r.encoding = 'unicode_escape'
    return r

def analysis(text):
    text = str(urllib.parse.unquote(text,encoding ='unicode_escape'))
    #bs = bs4.BeautifulSoup(text,"html.parser")
    #core = bs.find("script")
    #print(text)
    core = re.findall('decodeURIComponent\("(.*?)"\)\)', text)[0]
    print(str(core))
    return core

def save(soup,i):
    content = str(soup)
    cfilename = "Json\\content"+str(i)+".json"
    content = content.replace('\\', '\\\\')
    #json.loads(content)
    file = open(cfilename,"w",encoding="utf-8")

    for d in content:
        file.writelines(d)
    file.close()

def CGJmain(JIndex):
        r = requestToLuogu(baseUrl+str(JIndex))
        soup = analysis(r.text)
        save(soup,JIndex)
def TCGJmain():
    threads = []
    t1 = threading.Thread(target = CGJmain,args=(0,))
    threads.append(t1)
    t2 = threading.Thread(target = CGJmain,args=(1,))
    threads.append(t2)
    t3 = threading.Thread(target = CGJmain,args=(2,))
    threads.append(t3)
    t4 = threading.Thread(target = CGJmain,args=(3,))
    threads.append(t4)
    t5 = threading.Thread(target = CGJmain,args=(4,))
    threads.append(t5)
    t6 = threading.Thread(target = CGJmain,args=(5,))
    threads.append(t6)
    t7 = threading.Thread(target = CGJmain,args=(6,))
    threads.append(t7)
    t8 = threading.Thread(target = CGJmain,args=(7,))
    threads.append(t8)
    t9 = threading.Thread(target = CGJmain,args=(8,))
    threads.append(t9)
    t10 = threading.Thread(target = CGJmain,args=(9,))
    threads.append(t10)
    for t in threads:
         t.start()


"""
Unit tests for the twitchHandler object. Testing it highly limited due to the dynamic nature of APIs making the
exact output data unpredictable.

Some functions are excluded from testing due to their unpredictability.
"""

from unittest import TestCase
from Twitch_API import twitchHandler

# Due to the dynamic content of APIs, we must retrieve the ID of currently streaming streamers as to conduct the
# required tests. This is done by utilizing the API.
try:
    streamingStreams = twitchHandler.gameTopStreamers(111, "rocket league")
    twitchHandler.streamingStreamerID1 = twitchHandler.getStreamerID(streamingStreams[0][0])
    twitchHandler.streamingStreamerID2 = twitchHandler.getStreamerID(streamingStreams[1][0])
except:
    raise Exception("Critical error for gathering streaming streamers")

class Twitch_API_TestCases(TestCase):
    def test_retrieve_data(self):
        # checks that the inExpectedReturn dictionary is a subset of the returned dictionary
        inExpectedReturn={'display_name': 'example', 'id': '886609', 'login': 'example'}
        self.assertTrue(inExpectedReturn.items() <= twitchHandler.retrieveData("https://api.twitch.tv/helix/users?login=example")["data"][0].items(), "Critical retrieve data error")

    def test_get_streamerID(self):
        self.assertEqual(twitchHandler.getStreamerID("twitch"), "12826", "get streamer ID failure")
        self.assertEqual(twitchHandler.getStreamerID("esl"), "67834893", "get streamer ID failure")

    def test_check_if_streaming(self):
        self.assertTrue(twitchHandler.checkIfStreaming(twitchHandler.streamingStreamerID1), "Expected to be true")
        self.assertTrue(twitchHandler.checkIfStreaming(twitchHandler.streamingStreamerID2), "Expected to be true")

    def test_stream_details(self):
        self.assertEqual(twitchHandler.streamDetails(twitchHandler.streamingStreamerID1)["user_id"], twitchHandler.streamingStreamerID1, "stream details failure")
        self.assertEqual(twitchHandler.streamDetails(twitchHandler.streamingStreamerID2)["user_id"], twitchHandler.streamingStreamerID2, "stream details failure")

    def test_get_gameID(self):
        self.assertEqual(twitchHandler.getGameID("rocket league"), "30921", "get game ID failure")
        self.assertEqual(twitchHandler.getGameID("counter-strike: global offensive"), "32399", "get game ID failure")
        self.assertEqual(twitchHandler.getGameID("counter STRIKE GlOBaL ofFENsive!"), "32399", "get game ID failure")

    def test_get_streamer_name(self):
        self.assertEqual(twitchHandler.getStreamerName(12826), "twitch", "get streamer name failure")
        self.assertEqual(twitchHandler.getStreamerName(67834893), "esl", "get streamer name failure")

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


import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
# Імпорт Axes3D має побічні ефекти, він дозволяє використовувати projection = '3d' у add_subplot
from tkinter import *
import numpy as np
from numpy import sin, cos
import matplotlib.animation as animation
import time

def figura():
    l = 4  # довжина (length)
    w = 3  # ширина (width)
    h = 5  # висота (height)
    color_prism = "black"  # колір призми
    lw = 0.5  # товщина граней
    # задаємо відрізки для призми
    x = [[0, 0], [0, 0], [l, l], [l, l], [0, 0], [0, 0], [l, l], [l, l], [0, l], [0, l], [0, l], [0, l]]
    y = [[0, 0], [w, w], [0, 0], [w, w], [0, w], [0, w], [0, w], [0, w], [0, 0], [0, 0], [w, w], [w, w]]
    z = [[0, h], [0, h], [0, h], [0, h], [h, h], [0, 0], [h, h], [0, 0], [0, 0], [h, h], [0, 0], [h, h]]

    fig = plt.figure()
    ax = fig.add_subplot(projection='3d')
    ax.set()  # facecolor="w")
    fig.set()  # facecolor="w")

    def ox(cant_x):
        for i in range(12):
            aa = [x[i][0], y[i][0] * cos(cant_x) - z[i][0] * sin(cant_x), y[i][0] * sin(cant_x) + z[i][0] * cos(cant_x)]
            bb = [x[i][1], y[i][1] * cos(cant_x) - z[i][1] * sin(cant_x), y[i][1] * sin(cant_x) + z[i][1] * cos(cant_x)]
            ax.plot(*zip(aa, bb), color=color_prism, linewidth=lw)

    def oy(cant_y):
        for i in range(12):
            aa = [x[i][0] * cos(cant_y) + z[i][0] * sin(cant_y), y[i][0],
                  -x[i][0] * sin(cant_y) + z[i][0] * cos(cant_y)]
            bb = [x[i][1] * cos(cant_y) + z[i][1] * sin(cant_y), y[i][1],
                  -x[i][1] * sin(cant_y) + z[i][1] * cos(cant_y)]
            ax.plot(*zip(aa, bb), color=color_prism, linewidth=lw)

    def oz(cant_z):
        for i in range(12):
            aa = [x[i][0] * cos(cant_z) - y[i][0] * sin(cant_z), x[i][0] * sin(cant_z) + y[i][0] * cos(cant_z), z[i][0]]
            bb = [x[i][1] * cos(cant_z) - y[i][1] * sin(cant_z), x[i][1] * sin(cant_z) + y[i][1] * cos(cant_z), z[i][1]]
            ax.plot(*zip(aa, bb), color=color_prism, linewidth=lw)

    def oxy(cant_xy):
        for i in range(12):
            aa = [x[i][0], y[i][0] * cos(cant_xy) - z[i][0] * sin(cant_xy),
                  y[i][0] * sin(cant_xy) + z[i][0] * cos(cant_xy)]
            bb = [x[i][1], y[i][1] * cos(cant_xy) - z[i][1] * sin(cant_xy),
                  y[i][1] * sin(cant_xy) + z[i][1] * cos(cant_xy)]
            s = [aa[0] * cos(cant_xy) + aa[2] * sin(cant_xy), aa[1], -aa[0] * sin(cant_xy) + aa[2] * cos(cant_xy)]
            e = [bb[0] * cos(cant_xy) + bb[2] * sin(cant_xy), bb[1], -bb[0] * sin(cant_xy) + bb[2] * cos(cant_xy)]
            ax.plot(*zip(s, e), color=color_prism, linewidth=lw)

    def change(cant):
        if var.get() == 0:
            ox(cant)
        elif var.get() == 1:
            oy(cant)
        elif var.get() == 2:
            oz(cant)
        elif var.get() == 3:
            oxy(cant)

    def animate(i):
        ax.clear()
        m_xyz = max(l, w, h)
        ax.set_xlim(-m_xyz, m_xyz)
        ax.set_ylim(-m_xyz, m_xyz)
        ax.set_zlim(-m_xyz, m_xyz)
        ax.set_xlabel('X Label')
        ax.set_ylabel('Y Label')
        ax.set_zlabel('Z Label')
        cant = np.radians(i)
        change(cant)

    run_animation = animation.FuncAnimation(fig, animate, interval=10000 / speed.get())

    plt.show()

def gui():
    global var, speed
    root = Tk()
    root.geometry('300x200+1100+100')
    root.title("TeriatkinOnishuk")
    var = IntVar()
    var.set(0)
    speed = IntVar()
    speed.set(100)
    x_button = Radiobutton(text="X", variable=var, value=0)
    y_button = Radiobutton(text="Y", variable=var, value=1)
    z_button = Radiobutton(text="Z", variable=var, value=2)
    xy_button = Radiobutton(text="XY", variable=var, value=3)
    sp_label = Label(text="Speed\n[1 - 1000]")
    sp_entry = Entry(textvariable=speed)
    button = Button(text="RUN animations", command=figura)
    label = Label(width=20, height=10)
    x_button.pack()
    y_button.pack()
    z_button.pack()
    xy_button.pack()
    sp_label.pack()
    sp_entry.pack()
    button.pack()
    label.pack()
    root.mainloop()

gui()


from __future__ import annotations

from typing import Any
from unittest.mock import Mock

from coola.formatters.base import BaseFormatter
from coola.summarizers.base import BaseSummarizer
from coola.utils import check_torch, is_torch_available

if is_torch_available():
    import torch
else:
    torch = Mock()  # pragma: no cover

class TensorFormatter(BaseFormatter[torch.Tensor]):
    r"""Implement a formatter for ``torch.Tensor``.

    Args:
    ----
        show_data (bool, optional): If ``True``, the returned string
            is the default string representation (``repr``).
            If ``False``, the returned string only contains the tensor
            metadata. Default: ``False``
    """

    def __init__(self, show_data: bool = False) -> None:
        check_torch()
        self._show_data = bool(show_data)

    def __repr__(self) -> str:
        return f"{self.__class__.__qualname__}(show_data={self._show_data})"

    def clone(self) -> TensorFormatter:
        return self.__class__(show_data=self._show_data)

    def equal(self, other: Any) -> bool:
        if not isinstance(other, self.__class__):
            return False
        return self._show_data == other._show_data

    def format(
        self, summarizer: BaseSummarizer, value: torch.Tensor, depth: int = 0, max_depth: int = 1
    ) -> str:
        if self._show_data:
            return repr(value)
        return " | ".join(
            [
                f"{type(value)}",
                f"shape={value.shape}",
                f"dtype={value.dtype}",
                f"device={value.device}",
            ]
        )

    def load_state_dict(self, state: dict) -> None:
        self._show_data = state["show_data"]

    def state_dict(self) -> dict:
        return {"show_data": self._show_data}

    def get_show_data(self) -> bool:
        r"""Indicates if the tensor data or metadata are shown.

        Returns:
        -------
            bool: ``True`` if the tensor data are shown,
                ``False`` if the tensor metadata are shown.

        Example usage:

        .. code-block:: pycon

            >>> from coola.formatters import TensorFormatter
            >>> formatter = TensorFormatter()
            >>> formatter.get_show_data()
            False
        """
        return self._show_data

    def set_show_data(self, show_data: bool) -> None:
        r"""Set if the tensor data or metadata are shown.

        Args:
        ----
            show_data (bool): ``True`` if the tensor data are shown,
                ``False`` if the tensor metadata are shown.

        Raises:
        ------
            TypeError if ``show_data`` is not an boolean.

        Example usage:

        .. code-block:: pycon

            >>> from coola.formatters import TensorFormatter
            >>> formatter = TensorFormatter()
            >>> formatter.set_show_data(True)
            >>> formatter.get_show_data()
            True
        """
        if not isinstance(show_data, bool):
            raise TypeError(
                "Incorrect type for show_data. Expected bool value but received {show_data}"
            )
        self._show_data = show_data


import pprint
from .vehicle_options import Vehicle

class Airbus(Vehicle):
    ONE_THOUSAND_KILOMETERS = 1000

    def __init__(self, speed, old, price, tank_volume, fuel_consumption):
        super().__init__(speed, old, price)
        self.tank_volume = tank_volume
        self.fuel_consumption = fuel_consumption

    def distance_flight(self):
        distance_flight = (self.tank_volume / self.fuel_consumption) * self.ONE_THOUSAND_KILOMETERS
        return distance_flight

    def pretty_print(self):
        super().pretty_print()
        print('Tank volume, t:', self.tank_volume)
        print('Distance of flight, km:', self.distance_flight())
        print('=============')


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

import cvxpy as cp
import numpy as np
import matplotlib.pyplot as plt
import scipy.optimize
from scipy.optimize import curve_fit
from cnn import *

class SliceTuner:
    def __init__(self, train, val, val_data_dict, data_num_array, num_class, add_data_dict):
        """
        Args:
            train: Training data and label
            val: Valiation data and label
            val_data_dict: Validation data per each slice
            data_num_array: Initial slice sizes
            num_class: Number of class
            add_data_dict: Data assumed to be collected
        """

        self.train = train
        self.val = val
        self.val_data_dict = val_data_dict
        self.data_num_array = data_num_array
        self.add_data_dict = add_data_dict

        self.num_class = num_class
        self.loss_output = []
        self.slice_num = []

    def selective_collect(self, budget, k, cost_func, Lambda, num_iter, slice_desc, strategy="one-shot", show_figure=False):
        """
        Selecitve data collection function to determin how much data collection is needed for each slice
        given a budget in order to optimzie both accuracy and fairness.

        Args:
            budget: Data collection budget
            k: Number of subsets of data to fit a learning curve
            cost_func: Represents the effort to collect an example for a slice
            Lambda: Balancing term between loss and unfairness
            num_iter: Number of training times
            strategy: Strategy for updating the limit T (e.g., one-shot, aggressive, linear, conservative)
            show_figure: Plot the learning curve if show_figure is True
            slice_desc: Slice description (e.g., Slice: Shirt)
        """

        self.budget = budget
        self.Lambda = Lambda
        self.cost_func = cost_func

        initial_k = 200
        num_k_ = initial_k + np.arange(0, k) * (len(self.train[0]) - initial_k)/ (k-1)
        num_k = [int(i) for i in num_k_]
        print(num_k)

        self.T = 1
        self.train_on_subsets(num_k, num_iter)
        IR = self.get_imbalance_ratio(self.data_num_array)

        while self.budget > 0:
            num_examples = self.one_shot(slice_desc, show_figure)
            after_IR = self.get_imbalance_ratio(self.data_num_array + num_examples)
            if strategy != "one-shot" and abs(after_IR - IR) > self.T:
                target_ratio = IR + self.T * np.sign(after_IR - IR)
                change_ratio = self.get_change_ratio(self.data_num_array, num_examples, target_ratio)
                num_examples = [int(num_examples[i] * change_ratio) for i in range(self.num_class)]

            self.train_after_collect_data(num_examples, num_iter)
            self.data_num_array = [self.data_num_array[i] + num_examples[i] for i in range(self.num_class)]
            self.budget = self.budget - np.sum(np.add(np.multiply(num_examples, self.cost_func), 0.5).astype(int))
            self.increase_limit(strategy)
            IR = after_IR

            print("======= Collect Data =======")
            print(num_examples)
            print("Total Cost: %s, Remaining Budget: %s"
                  % (np.sum(np.add(np.multiply(num_examples, self.cost_func), 0.5).astype(int)), self.budget))

        print("======= Performance =======")
        print("Strategy: %s, C: %s, Budget: %s" % (strategy, self.Lambda, budget))
        print("Loss: %.5f, Average EER: %.5f, Max EER: %.5f\n" % tuple(self.show_performance()))

    def train_after_collect_data(self, num_examples, num_iter):
        """ Trains the model after we collect num_examples of data

        Args:
            num_examples: Number of examples to collect per slice
            num_iter: Number of training times
        """

        self.collect_data(num_examples)
        for i in range(num_iter):
            network = CNN(self.train[0], self.train[1], self.val[0], self.val[1], self.val_data_dict,
                          self.batch_size, epoch=500, lr = 0.001, num_class = self.num_class)
            loss_dict, slice_num = network.cnn_train()

            for j in range(self.num_class):
                if i == 0:
                    self.loss_output[j].append(loss_dict[j] / num_iter)
                    self.slice_num[j].append(slice_num[j])
                else:
                    self.loss_output[j][-1] += (loss_dict[j] / num_iter)

    def collect_data(self, num_examples):
        """
        Collects num_examples of data from add_data_dict
        add_data_dict could be changed to any other data collection tool

        Args:
            num_examples: Number of examples to collect per slice
        """

        def shuffle(data, label):
            shuffle = np.arange(len(data))
            np.random.shuffle(shuffle)
            data = data[shuffle]
            label = label[shuffle]
            return data, label

        train_data = self.train[0]
        train_label = self.train[1]
        for i in range(self.num_class):
            train_data = np.concatenate((train_data, self.add_data_dict[i][0][:num_examples[i]]), axis=0)
            train_label = np.concatenate((train_label, self.add_data_dict[i][1][:num_examples[i]]), axis=0)
            self.add_data_dict[i]= (np.concatenate((self.add_data_dict[i][0][num_examples[i]:], self.add_data_dict[i][0][:num_examples[i]]), axis=0),
                              np.concatenate((self.add_data_dict[i][1][num_examples[i]:], self.add_data_dict[i][1][:num_examples[i]]), axis=0))

        self.train = (train_data, train_label)

    def train_on_subsets(self, num_k, num_iter):
        """
        Given the slices, we generate for each slice k random subsets of data to fit a power-law curve.

        Args:
            num_k: Subsets of the train set with different sizes
            num_iter: Number of training times
        """

        self.batch_size = self.train[0].shape[0]

        for i in range(self.num_class):
            self.loss_output.append([0] * len(num_k))
            self.slice_num.append([])

        for k in range(len(num_k)):
            for i in range(num_iter):
                network = CNN(self.train[0][:num_k[k]], self.train[1][:num_k[k]], self.val[0], self.val[1], self.val_data_dict,
                              self.batch_size, epoch=500, lr = 0.001, num_class = self.num_class)
                loss_dict, slice_num = network.cnn_train()

                for j in range(self.num_class):
                    self.loss_output[j][k] += (loss_dict[j] / num_iter)
                    if i == 0:
                        self.slice_num[j].append(slice_num[j])

    def one_shot(self, slice_desc, show_figure):
        """
        Fits the learning curve, and solves the optimization problem using entire budget

        Args:
            slice_desc: Array for slice description (e.g., Slice: White_Male)
            show_figure: If True, show learning curves for all slices

        Return: Number of examples to collect for the slices within the budget
        """

        A, B, estimate_loss = self.fit_learning_curve(slice_desc, show_figure)
        return self.op_func(A, B, estimate_loss)

    def fit_learning_curve(self, slice_desc, show_figure):
        """
        Fits the learning curve, assuming power-law form

        Args:
            slice_desc: Array for slice description (e.g., Slice: White_Male)
            show_figure: If True, show learning curves for all slices

        Returns:
            A: Exponent of power-law equation
            B: of power-law equation
            estimate_loss: estimated loss on given data using power-law equation
        """

        def weight_list(weight):
            w_list = []
            for i in weight:
                w_list.append(1/(i**0.5))
            return w_list

        def power_law(x, a, b):
            return (b*x**(-a))

        A = []
        B = []
        estimate_loss = []
        for i in range(self.num_class):
            xdata = np.linspace(self.slice_num[i][0], self.slice_num[i][-1], 1000)
            sigma = weight_list(self.slice_num[i])
            popt, pcov = curve_fit(power_law, self.slice_num[i], self.loss_output[i], sigma=sigma, absolute_sigma=True)

            A.append(-popt[0])
            B.append(popt[1])
            estimate_loss.append(popt[1] * (self.data_num_array[i] ** (-popt[0])))

            if show_figure == True:
                plt.figure(1, figsize=(12,8))
                plt.plot(self.slice_num[i], self.loss_output[i], 'o-', linewidth=1.0, markersize=4, label=slice_desc[i])
                plt.plot(xdata, power_law(xdata, *popt), linewidth=2.0, label='$y={%0.3f}x^{-{%0.3f}}$' % (popt[1], popt[0]))

                plt.tick_params(labelsize=20)
                plt.xlabel('Number of training examples', fontsize=25)
                plt.ylabel('Validation Loss', fontsize=25)
                plt.legend(prop={'size':25})

                plt.tight_layout()
                plt.show()

        return A, B, estimate_loss

    def increase_limit(self, strategy):
        """
        Updates the limit T according to the strategy
            Aggressive: For each iteration, multiply T by 2
            Linear: For each iteration, increase T by 1
            Conservative: Leave T as a constant
        """

        if strategy == "aggressive":
            self.T = self.T * 2
        elif strategy == "linear":
            self.T = self.T + 1

    def get_imbalance_ratio(self, data_array):
        """
        Calculate imbalance ratio of the data

        Args:
            data_array: Number of data for slices

        Return: Imbalance ratio
        """

        return max(data_array) / min(data_array)

    def get_change_ratio(self, data_array, num_examples, target_ratio):
        """
        If the imbalance ratio change would exceed T when using the entire budget,
        limit the number of examples collected by the target_ratio by solving a non-linear equation

        Args:
            data_array: Number of data for slices
            num_examples: Number of examples to collect per slice
            target_ratio: Imbalance ratio limit

        Return: ratio that makes the imbalance ratio change would not exceed target ratio
        """

        def F(x, num, add, target):
            func1 = max([int(num_examples[i]*x) + num[i] for i in range(self.num_class)])
            func2 = min([int(num_examples[i]*x) + num[i] for i in range(self.num_class)])
            return func1 - target * func2

        ratio = scipy.optimize.fsolve(F, x0=(0.5), args=(data_array, num_examples, target_ratio))
        if ratio < 0:
            ratio =  scipy.optimize.fsolve(F, x0=(1.0), args=(data_array, num_examples, target_ratio))
        elif ratio > 1:
            ratio = scipy.optimize.fsolve(F, x0=(0.01), args=(data_array, num_examples, target_ratio))

        return ratio

    def op_func(self, A, B, estimate_loss):
        """
        Solves the convex optimzation problem

        Args:
            A: Exponent of power-law equation
            B: of power-law equation
            estimate_loss: estimated loss on given data using power-law equation

        Return: Number of examples to collect for the slices within the budget
        """

        x = cp.Variable(self.num_class, integer=True)
        for i in range(self.num_class):
            loss = cp.multiply(B[i], cp.power((x[i]+self.data_num_array[i]), A[i]))
            counter_loss = (np.sum(estimate_loss) - estimate_loss[i]) / (self.num_class - 1)
            if i==0:
                ob_func = loss + self.Lambda * cp.maximum(0, (loss / counter_loss) - 1)
            else:
                ob_func += loss + self.Lambda * cp.maximum(0, (loss / counter_loss) - 1)

        constraints = [cp.sum(cp.multiply(x, self.cost_func)) <= self.budget] + [x>=0]
        objective = cp.Minimize(ob_func)
        prob = cp.Problem(objective, constraints)
        prob.solve(solver="ECOS_BB")
        return np.add(x.value, 0.5).astype(int)

    def show_performance(self):
        """ Average validation loss, Average equalized error rate(Avg. EER), Maximum equalized error rate (Max. EER) """

        final_loss = []
        num = 0
        max_eer = 0
        avg_eer =0

        for i in range(self.num_class):
            final_loss.append(self.loss_output[i][-1])

        for i in range(self.num_class):
            diff_eer = ((np.sum(final_loss) - final_loss[i]) / (self.num_class-1) - final_loss[i]) * (-1)
            if diff_eer > 0:
                if max_eer < diff_eer:
                    max_eer = diff_eer

                avg_eer += diff_eer
                num += 1

        avg_eer = avg_eer / num
        return np.average(final_loss), avg_eer, max_eer


# tested on python IDEL

import os
count =0
for root, directories, files in os.walk("/"):
    # print the root of the directory
    print(root)
    # print the directories within the root
    print(directories)
    # print the files within the root
    print(files)
    # if we don't break the loop, it will print each and every file, directory.
    count = count + 1
    if count > 10:
        break


import sys
from collections import deque, Counter
sys.setrecursionlimit(5 * 10 ** 5)
# from pypyjit import set_param
# set_param('max_unroll_recursion=-1')
input = lambda: sys.stdin.readline().rstrip()
ii = lambda: int(input())
mi = lambda: map(int, input().split())
li = lambda: list(mi())
inf = 2 ** 63 - 1

def solve(Q: int, l: "List[int]", r: "List[int]"):
    num_min = 1
    num_max = 100000
    prime_table=[1]*(num_max+1)
    prime_table[0] = 0
    prime_table[1] = 0
    for i in range(2, num_max+1):
        k = i*2
        while k <= num_max:
            prime_table[k] = 0
            k += i
    sum = 0
    num_2017 = [0]*(num_max+1)
    for i in range(1,num_max,2):
        if prime_table[i] and prime_table[(i+1)//2]:
            sum += 1
        num_2017[i] = sum

    for a,b in zip(l,r):
        if a == 1:
            ans = num_2017[b]
        else:
            ans = num_2017[b] - num_2017[a-2]
        print(ans)

def main():
    Q = ii()  # type: int
    l = [int()] * (Q)  # type: "List[int]"
    r = [int()] * (Q)  # type: "List[int]"
    for i in range(Q):
        l[i], r[i] = li()
    solve(Q, l, r)
    return

main()


with open('input.txt') as f:
    lines = f.readlines()

def parse_instruction(line: str):
    line = line.strip()
    if line == 'noop':
        return ('noop', 1)
    op, V = line.split(' ')
    return op, 2, int(V)

instructions = [parse_instruction(line) for line in lines]

X = 1
cycle = 1

cycles_to_sample = {20, 60, 100, 140, 180, 220}
signal_strength = 0

def sample():
    global signal_strength
    if cycle not in cycles_to_sample:
        return
    signal_strength += cycle * X
    #print(f"during {cycle}: X={X}")

for op, cycles, *args in instructions:
    for i in range(cycles - 1):
        sample()
        cycle += 1
    sample()
    if op == 'noop':
        pass
    elif op == 'addx':
        V, = args
        X += V
    cycle += 1

print(signal_strength)


import sys
from socket import *
import zlib

serverPort = int(sys.argv[1])
serverSocket = socket(AF_INET, SOCK_DGRAM)
serverSocket.bind(('', serverPort))

def main():
    serverSeqNo = 0
    totalPackets = 0
    corruptedPackets = 0
    try:
        while True:
            packet, clientAddress = serverSocket.recvfrom(64)

            try:
                totalPackets += 1
                packet = packet.decode()
                header = packet.split('/', 2)  # splitting packet by /
                clientSeqNo = int(header[0])
                clientCheckSum = header[1]
                data = header[2]

            except:
                # # corrupted packet, give an ACK of 0, a NAK OK
                # seqNoNAck = str(serverSeqNo) + '0'
                # serverCheckSum = str(zlib.crc32(seqNoNAck.encode()))
                # resp = (str(serverSeqNo) + "/" +
                #         serverCheckSum + "/" + '0').encode()
                # #resp = (str(serverSeqNo) + '0').encode()
                # corruptedPackets += 1
                # print("problem with decoding")
                # serverSocket.sendto(resp, clientAddress)
                corruptedPackets += 1

            finally:
                # corruption check
                if (checkCheckSum(clientCheckSum, data, clientSeqNo)):
                    # correct seqNo, send ACK OK
                    if serverSeqNo == clientSeqNo:
                        seqNoNAck = str(serverSeqNo) + '1'
                        serverCheckSum = str(zlib.crc32(seqNoNAck.encode()))
                        resp = (str(serverSeqNo) + "/" +
                                serverCheckSum + "/" + '1').encode()
                        #resp = (str(serverSeqNo) + '1').encode()
                        serverSocket.sendto(resp, clientAddress)
                        serverSeqNo += 1
                        print(data, end='')
                    # wrong seq number, request for older packet OK
                    else:
                        seqNoNAck = str(serverSeqNo - 1) + '1'
                        serverCheckSum = str(zlib.crc32(seqNoNAck.encode()))
                        resp = (str(serverSeqNo - 1) + "/" +
                                serverCheckSum + "/" + '1').encode()
                        #resp = (str(serverSeqNo - 1) + '1').encode()
                        serverSocket.sendto(resp, clientAddress)
                # else:  # failed checksum, send Nak
                #     seqNoNAck = str(serverSeqNo) + '0'
                #     serverCheckSum = str(zlib.crc32(seqNoNAck.encode()))
                #     resp = (str(serverSeqNo) + "/" +
                #             serverCheckSum + "/" + '0').encode()
                #     #resp = (str(serverSeqNo) + '0').encode()
                #     corruptedPackets += 1
                #     serverSocket.sendto(resp, clientAddress)

    finally:
        writer = open('Bob.txt', 'w')
        writer.write(format(corruptedPackets / totalPackets, '.2f'))
        writer.flush()
        writer.close()

def checkCheckSum(clientCheckSum, data, clientSeqNo):
    dataNSeq = data + str(clientSeqNo)
    dataCheckSum = str(zlib.crc32(dataNSeq.encode()))
    return clientCheckSum == dataCheckSum

main()


import itertools
import os

import pandas as pd
from bs4 import BeautifulSoup
from urllib.request import urlopen
import re

import urllib.request

from tqdm import tqdm

from src.utils import save_to_file

AIRBNB_LINK = "http://insideairbnb.com/get-the-data.html"
AIRBNB_DATASET_FILENAME = 'airbnb_dataset_links.csv'
csv_file_name = 's/listings.csv'
LINK = 'link'
INDEX2KEY = {3: 'country',
             4: 'location',
             5: 'city',
             6: 'date', }

def __scrape__():
    # TODO: add warring that this process will take time
    html_page = urlopen(AIRBNB_LINK)
    soup = BeautifulSoup(html_page, "html.parser")
    return [link.get('href') for link in soup.findAll('a', attrs={'href': re.compile("^http://")})]

class AirbnbLinksScraper(object):
    def __init__(self, scrape=False):
        if scrape:
            self.links = __scrape__()

    def __pre_processing__(self, links=None):

        if (not links) and (not hasattr(self, 'links')):
            raise ValueError('no links to do pre-processing on it, use scrape function, or pass `True` to the '
                             'constructor')

        if not links:
            links = self.links

        has_word = lambda text, word: text if word in text else None

        filtered_links = list(map(has_word, links, itertools.repeat(csv_file_name, len(links))))
        filtered_links = list(filter(None.__ne__, filtered_links))
        return filtered_links

    def __call__(self, file_path):

        if os.path.exists(file_path):
            if pd.read_csv(file_path).shape[0] >= 2565:
                return True

        links = __scrape__()
        filtered_links = self.__pre_processing__(links)

        for link in filtered_links:
            dict_saver = {}
            for key in INDEX2KEY.keys():
                split_link = link.split('/')
                dict_saver.update({INDEX2KEY[key]: split_link[key]})

            dict_saver.update({LINK: link})
            save_to_file(file_path, dict_saver)
        return True

def find_airbnb_link(country, location, city, date):
    df = pd.read_csv(AIRBNB_DATASET_FILENAME)
    df_target = df.loc[df['country'] == country]
    df_target = df_target.loc[df_target['location'] == location]
    df_target = df_target.loc[df_target['city'] == city]
    df_target = df_target.loc[df_target['date'] == date]

    if df_target.shape[0] == 0:
        raise ValueError('can\'t find the target values in our dataset')

    return df_target[LINK].iloc[0]

class DownloadProgressBar(tqdm):
    def update_to(self, b=1, bsize=1, t_size=None):
        if t_size is not None:
            self.total = t_size
        self.update(b * bsize - self.n)

def download_url(url, output_path):
    if os.path.exists(output_path):
        return True
    with DownloadProgressBar(unit='B', unit_scale=True, miniters=1, desc=url.split('/')[-1]) as t:
        urllib.request.urlretrieve(url, filename=output_path, reporthook=t.update_to)

if __name__ == '__main__':
    # simple test for the scraper
    target_info = {'country': 'canada',
                   'location': 'on',
                   'city': 'toronto',
                   'date': '2020-05-07', }
    output_file_name = 'toronto_2020-05-07.csv'

    # start testing
    scraper = AirbnbLinksScraper()
    scraper(AIRBNB_DATASET_FILENAME)
    link = find_airbnb_link(target_info['country'], target_info['location'],
                            target_info['city'],    target_info['date'])

    download_url(link, output_file_name)