import numpy as np
import pandas as pd
import fiona
import io
from shapely import geometry
import click
from wit_tooling import query_wit_data

def shape_list(key, values, shapefile):
    """
        Get a generator of shapes from the given shapefile
            key: the key to match in 'properties' in the shape file
            values: a list of property values
            shapefile: the name of your shape file
            e.g. key='ORIGID', values=[1, 2, 3, 4, 5],
            shapefile='/g/data/r78/DEA_Wetlands/shapefiles/MDB_ANAE_Aug2017_modified_2019_SB_3577.shp'
    """
    count = len(values)
    with fiona.open(shapefile) as allshapes:
        for shape in allshapes:
            shape_id = shape['properties'].get(key)
            if shape_id is None:
                continue
            if isinstance(shape_id, float):
                shape_id = int(shape_id)
            if shape_id in values:
                yield(shape_id, shape)
                count -= 1
            if count <= 0:
                break

def get_areas(features, pkey='SYSID'):
    """
        Calculate the area of a list/generator of shapes
        input:
            features: a list of shapes indexed by the key
        output:
            a dataframe of area index by the key
    """
    re = pd.DataFrame()
    for f in features:
        va = pd.DataFrame([[f[0], geometry.shape(f[1]['geometry']).area/1e4]], columns=[pkey, 'area'])
        re = re.append(va, sort=False)
    return re.set_index(pkey)

def dump_wit_data(key, feature_list, output, batch=-1):
    """
        dump wit data from the database into a file
        input:
            key: Name to id the polygon
            feature_list: a list or generator of features
        output:
            a csv file to save all the wit data
    """
    count = 0
    if batch > 0:
        fname = output.split('.')[0]
        sub_fname = fname + '_0.csv'
        appendix = 0
    else:
        sub_fname = output

    for f_id, f in feature_list:
        _, wit_data = query_wit_data(f)
        csv_buf = io.StringIO()
        wit_df = pd.DataFrame(data=wit_data, columns=['TIME', 'BS', 'NPV', 'PV', 'WET', 'WATER'])
        wit_df.insert(0, key, f_id)
        wit_df.to_csv(csv_buf, index=False, header=False)
        csv_buf.seek(0)
        with open(sub_fname, 'a') as f:
            f.write(csv_buf.read())
        if batch < 0:
            continue
        count += 1
        if count >= batch:
            with open(sub_fname, 'a') as f:
                f.write(','.join(list(wit_df.columns)))
            count = 0
            appendix += 1
            sub_fname = fname + '_' + str(appendix) + '.csv'
    if count < batch or batch < 0:
         with open(sub_fname, 'a') as f:
            f.write(','.join(list(wit_df.columns)))

def annual_metrics(wit_data, members=['PV', 'WET', 'WATER', 'BS', 'NPV', ['NPV', 'PV', 'WET'],
                                          ['PV', 'WET'], ['WATER', 'WET']], threshold=[25, 75], pkey='SYSID'):
    """
        Compute the annual max, min, mean, count with given wit data, members and threshold
        input:
            wit_data: dataframe of WIT
            members: the elements which the metrics are computed against, can be a column from wit_data, e.g. 'PV'
                         or the sum of wit columns, e.g. ['WATER', 'WET']
            threshold: a list of thresholds such that (elements >= threshold[i]) is True,
                        where i = 0, 1...len(threshold)-1
        output:
            dataframe of metrics
    """
    years = wit_data['TIME']
    i = 0
    wit_df = wit_data.copy(deep=True)
    for m in members:
        if isinstance(m, list):
            wit_df.insert(wit_df.columns.size+i, '+'.join(m), wit_df[m].sum(axis=1))
    years = pd.DatetimeIndex(wit_df['TIME']).year.unique()
    shape_id_list = wit_df[pkey].unique()
    #shane changed 4 to 5 to accomodate median added below
    wit_metrics = [pd.DataFrame()] * 5
    for y in years:
        wit_yearly = wit_df[pd.DatetimeIndex(wit_df['TIME']).year==y].drop(columns=['TIME']).groupby(pkey).max()
        wit_yearly.insert(0, 'YEAR', y)
        wit_yearly = wit_yearly.rename(columns={n: n+'_max' for n in wit_yearly.columns[1:]})
        wit_metrics[0] = wit_metrics[0].append(wit_yearly, sort=False)
    for y in years:
        wit_yearly = wit_df[pd.DatetimeIndex(wit_df['TIME']).year==y].drop(columns=['TIME']).groupby(pkey).min()
        wit_yearly.insert(0, 'YEAR', y)
        wit_yearly = wit_yearly.rename(columns={n: n+'_min' for n in wit_yearly.columns[1:]})
        wit_metrics[1] = wit_metrics[1].append(wit_yearly, sort=False)
    for y in years:
        wit_yearly = wit_df[pd.DatetimeIndex(wit_df['TIME']).year==y].drop(columns=['TIME']).groupby(pkey).mean()
        wit_yearly.insert(0, 'YEAR', y)
        wit_yearly = wit_yearly.rename(columns={n: n+'_mean' for n in wit_yearly.columns[1:]})
        wit_metrics[2] = wit_metrics[2].append(wit_yearly, sort=False)

    #*********************** START ADDED BY SHANE ***********************
    #adding median
    for y in years:
        wit_yearly = wit_df[pd.DatetimeIndex(wit_df['TIME']).year==y].drop(columns=['TIME']).groupby(pkey).median()
        wit_yearly.insert(0, 'YEAR', y)
        wit_yearly = wit_yearly.rename(columns={n: n+'_median' for n in wit_yearly.columns[1:]})
        wit_metrics[3] = wit_metrics[3].append(wit_yearly, sort=False)
    #*********************** END ADDED BY SHANE ***********************
    for y in years:
        wit_yearly = wit_df[pd.DatetimeIndex(wit_df['TIME']).year==y][[pkey, 'BS']].groupby(pkey).count()
        wit_yearly.insert(0, 'YEAR', y)
        wit_yearly = wit_yearly.rename(columns={n: 'count' for n in wit_yearly.columns[1:]})
        #shane changed index from 3 to 4 to accomodate median added above
        wit_metrics[4] = wit_metrics[4].append(wit_yearly, sort=False)
    for t in threshold:
        wit_df_ts = wit_df.copy(deep=True)
        wit_metrics += [pd.DataFrame()]
        wit_df_ts.loc[:, wit_df_ts.columns[2:]] = wit_df_ts.loc[:, wit_df_ts.columns[2:]].mask((wit_df_ts[wit_df_ts.columns[2:]] < t/100), np.nan)
        for y in years:
            wit_yearly = wit_df_ts[pd.DatetimeIndex(wit_df_ts['TIME']).year==y].drop(columns=['TIME']).groupby(pkey).count()
            wit_yearly.insert(0, 'YEAR', y)
            wit_yearly = wit_yearly.rename(columns={n: n+'_count'+str(t) for n in wit_yearly.columns[1:]})
            wit_metrics[-1] = wit_metrics[-1].append(wit_yearly, sort=False)
    wit_yearly_metrics = wit_metrics[0]
    for i in range(len(wit_metrics)-1):
        wit_yearly_metrics = pd.merge(wit_yearly_metrics, wit_metrics[i+1], on=[pkey, 'YEAR'], how='inner')
    return wit_yearly_metrics

def get_event_time(wit_ww, threshold, pkey='SYSID'):
    """
        Compute inundation event time by given threshold
        input:
            wit_df: wetness computed from wit data
            threshold: a value such that (WATER+WET > threshold) = inundation
        output:
            dateframe of inundation event time
    """
    if isinstance(threshold, pd.DataFrame):
        gid = wit_ww.index.unique()[0]
        poly_threshold = threshold.loc[gid].to_numpy()[0]
    else:
        poly_threshold = threshold
    i_start = wit_ww[wit_ww['WW'] >= poly_threshold]['TIME'].min()
    if pd.isnull(i_start):
        re = pd.DataFrame([[np.nan] * 4], columns=['start_time', 'end_time', 'duration', 'gap'], index=wit_ww.index.unique())
        re.index.name = pkey
        return re
    re_idx = np.searchsorted(wit_ww[(wit_ww['WW'] < poly_threshold)]['TIME'].values,
                             wit_ww[(wit_ww['WW'] >= poly_threshold)]['TIME'].values)
    re_idx, count = np.unique(re_idx, return_counts=True)
    start_idx = np.zeros(len(count)+1, dtype='int')
    start_idx[1:] = np.cumsum(count)
    re_start = wit_ww[(wit_ww['WW'] >= poly_threshold)].iloc[start_idx[:-1]][['TIME']].rename(columns={'TIME': 'start_time'})
    re_end = wit_ww[(wit_ww['WW'] >= poly_threshold)].iloc[start_idx[1:] - 1][['TIME']].rename(columns={'TIME': 'end_time'})
    re = pd.concat([re_start, re_end], axis=1)
    re.insert(2, 'duration',
              (re['end_time'] - re['start_time'] + np.timedelta64(1, 'D')).astype('timedelta64[D]').astype('timedelta64[D]'))
    re.insert(3, 'gap', np.concatenate([[np.timedelta64(0, 'D')],
                                        (re['start_time'][1:].values - re['end_time'][:-1].values - np.timedelta64(1, 'D')).astype('timedelta64[D]')]))
    re.insert(0, pkey, wit_ww.index.unique()[0])
    return re.set_index(pkey)

def get_im_stats(grouped_wit, im_time, wit_area):
    """
        Get inundation stats given wit data and events
        input:
            grouped_wit: wit data
            im_time: inundation events in time
        output:
            the stats of inundation events
    """
    gid = grouped_wit.index.unique()[0]
    if gid not in im_time.indices.keys():
        return pd.DataFrame([[np.nan]*5], columns=['start_time', 'max_wet', 'mean_wet', 'max_wet_area', 'mean_wet_area'],
                           index=[gid])
    re_left = np.searchsorted(grouped_wit['TIME'].values.astype('datetime64'),
                         im_time.get_group(gid)['start_time'].values, side='left')
    re_right = np.searchsorted(grouped_wit['TIME'].values.astype('datetime64'),
                         im_time.get_group(gid)['end_time'].values, side='right')
    re = pd.DataFrame()
    for a, b in zip(re_left, re_right):
        tmp = pd.concat([grouped_wit.iloc[a:a+1]['TIME'].rename('start_time').astype('datetime64'),
                         pd.Series(grouped_wit.iloc[a:b]['WW'].max(),index=[gid], name='max_wet'),
                         pd.Series(grouped_wit.iloc[a:b]['WW'].mean(),index=[gid], name='mean_wet')],
                        axis=1)
        tmp.insert(3, 'max_wet_area', tmp['max_wet'].values * wit_area[wit_area.index==gid].values)
        tmp.insert(4, 'mean_wet_area', tmp['mean_wet'].values * wit_area[wit_area.index==gid].values)
        re = re.append(tmp, sort=False)
    re.index.name = grouped_wit.index.name
    return re

def event_time(wit_df, threshold=0.01, pkey='SYSID'):
    """
        Compute the inundation events with given wit data and threshold
        input:
            wit_df: wetness computed from wit data
            threshold: a value such that (WATER+WET > threshold) = inundation,
        output:
            dataframe of events
    """
    return wit_df.groupby(pkey).apply(get_event_time, threshold=threshold, pkey=pkey).dropna().droplevel(0)

def event_stats(wit_df, wit_im, wit_area, pkey='SYSID'):
    """
        Compute inundation event stats with given wit wetness, events defined by (start_time, end_time)
        and polygon areas
        input:
            wit_df: wetness computed from wit data
            wit_im: inundation event
            wit_area: polygon areas indexed by the key
        output:
            dataframe of event stats
    """
    grouped_im = wit_im[['start_time', 'end_time']].groupby(pkey)
    return wit_df.groupby(pkey).apply(get_im_stats, im_time=grouped_im, wit_area=wit_area).droplevel(0)

def inundation_metrics(wit_data, wit_area, threshold=0.01, pkey='SYSID'):
    """
        Compute inundation metrics with given wit data, polygon areas and threshold
        input:
            wit_data: a dataframe of wit_data
            wit_area: polygon areas indexed by the key
            threshold: a value such that (WATER+WET > threshold) = inundation
        output:
            dataframe of inundation metrics
    """
    wit_df = wit_data.copy(deep=True)
    wit_df.insert(2, 'WW', wit_df[['WATER', 'WET']].sum(axis=1))
    wit_df = wit_df.drop(columns=wit_df.columns[3:])
    wit_df['TIME'] = wit_df['TIME'].astype('datetime64')
    wit_df = wit_df.set_index(pkey)
    wit_im_time = event_time(wit_df, threshold, pkey)
    wit_im_stats = event_stats(wit_df, wit_im_time, wit_area, pkey)
    return pd.merge(wit_im_time, wit_im_stats.dropna(), on=[pkey, 'start_time'], how='inner')

def interpolate_wit(grouped_wit, pkey='SYSID'):
    daily_wit = pd.DataFrame({pkey: grouped_wit[pkey].unique()[0], 'TIME': pd.date_range(grouped_wit['TIME'].astype('datetime64[D]').min(), grouped_wit['TIME'].astype('datetime64[D]').max(), freq='D'),
                          'BS': np.nan, 'NPV': np.nan, 'PV': np.nan, 'WET': np.nan, 'WATER': np.nan})
    _, nidx, oidx = np.intersect1d(daily_wit['TIME'].to_numpy().astype('datetime64[D]'), grouped_wit['TIME'].to_numpy().astype('datetime64[D]'),
                  return_indices=True)
    daily_wit.loc[nidx, ["BS","NPV","PV","WET","WATER"]]  = grouped_wit[["BS","NPV","PV","WET","WATER"]].iloc[oidx].to_numpy()
    daily_wit = daily_wit.interpolate(axis=0)
    return daily_wit

def all_time_median(wit_data, members=[['WATER', 'WET']], pkey='SYSID'):
    """
        Compute the all time median
        input:
            wit_data: dataframe of WIT
            members: the elements which the metrics are computed against, can be a column from wit_data, e.g. 'PV'
                         or the sum of wit columns, e.g. ['WATER', 'WET']
        output:
            dataframe of median indexed by pkey
    """
    wit_df = wit_data.copy(deep=True)
    i = 0
    for m in members:
        if isinstance(m, list):
            wit_df.insert(wit_df.columns.size+i, '+'.join(m), wit_df[m].sum(axis=1))
        i += 1
    return wit_df.groupby(pkey).median()

shapefile_path = click.argument('shapefile', type=str, default='/g/data/r78/rjd547/DES-QLD_Project/data/Wet_WGS84_P.shp')
@click.group(help=__doc__)
def main():
    pass

@main.command(name='wit-dump', help='dump wit data from database')
@shapefile_path
@click.option('--pkey', type=str, help='the key to match polygon in the shapefile, e.g., SYSID', default=None)
@click.option('--input-file', type=str, help='input csv with pkey', default=None)
@click.option('--output-file', type=str, help='output csv', default=None)
@click.option('--batch', type=int, help='how manay polygons per file', default=3000)
def wit_dump(shapefile, pkey, input_file, output_file, batch):
    features = shape_list(pkey, pd.read_csv(input_file, header=None).values, shapefile)
    dump_wit_data(pkey, features, output_file, batch)

@main.command(name='wit-metrics', help='compute wit metrics')
@shapefile_path
@click.option('--pkey', type=str, help='the key to match polygon in the shapefile, e.g., SYSID', default=None)
@click.option('--input-file', type=str, help='input csv of wit', default=None)
@click.option('--output-prefix', type=str, help='prefix of output csv', default=None)
def wit_metrics(shapefile, pkey, input_file, output_prefix):
    wit_data = pd.read_csv(input_file, header=None, skipfooter=1,
                       names=[pkey,"TIME","BS","NPV","PV","WET","WATER"], engine='python'
                      )
    features = shape_list(pkey, wit_data[pkey].unique(), shapefile)
    wit_area = get_areas(features, pkey=pkey)
    wit_yearly_metrics = annual_metrics(wit_data, pkey=pkey)
    ofn = output_prefix + "_yearly_metrics.csv"
    wit_yearly_metrics.to_csv(ofn)

    wit_median = all_time_median(wit_data, pkey=pkey)
    wit_median.loc[wit_median['WATER+WET'] < 0.01, 'WATER+WET'] = 0.01
    ofn = output_prefix + "_event_threshold.csv"
    wit_median[['WATER+WET']].to_csv(ofn)

    maxdate = pd.pivot_table(wit_data, index=pkey, values=['TIME'], aggfunc=np.max)
    maxdate['TIME'] = maxdate['TIME'].astype('datetime64')
    wit_im =inundation_metrics(wit_data, wit_area, wit_median[['WATER+WET']], pkey=pkey)
    ofn = output_prefix + '_inudation_metrics.csv'
    wit_im.to_csv(ofn)

    lastevent = pd.pivot_table(wit_im, index=pkey, values=['end_time'], aggfunc=np.max)
    time_since_last = pd.merge(maxdate, lastevent, on=[pkey], how='inner')
    time_since_last.insert(2, 'timesincelast',
              (time_since_last['TIME'] - time_since_last['end_time']).astype('timedelta64[D]'))
    ofn = output_prefix + '_time_since_last_inundation.csv'
    time_since_last.to_csv(ofn)

if __name__ == '__main__':
    main()


# Write a Python program to calculate the sum of three given numbers. If the values are equal, return three times their sum.

def sum_thrice(n, m, o):
    if n == m == o:
        return (n + m + o) * 3
    else:
        return n + m + o

print(sum_thrice(1, 2, 3))
print(sum_thrice(3, 3, 3))


class KUHN():
    """
    A two-agent environment for a kuhn poker game.
    The "state" is s_t = (c_{d}, c_{a}) with c_{d}, c_{a} the cards of player 1
    and player 2, respectively.
    Player 1 (P1) actions are represented as vectors of 3 components.
    The firs is the action taken in the second round given that his opponent has
    passed. The second one is the action taken in the second round given that
    his opponent has bet. The third one is the action taken in the first round.
    Player 2 (P2) can either pass (0) or bet (1).
    """

    def __init__(self, max_steps, batch_size=1):
        self.max_steps = max_steps
        self.batch_size = batch_size
        self.cards = np.array( [0,1,2] )
        #self.payout_mat = payouts
        #self.available_actions = [
        #    np.ones((batch_size, self.NUM_ACTIONS), dtype=int)
        #    for _ in range(self.NUM_AGENTS)
        #]
        self.step_count = None

    #global deal
    def deal(self):
        return np.random.choice(self.cards, 2, replace = False)

    def reset(self):
        self.step_count = 0
        #init_state = np.zeros((self.batch_size, self.NUM_STATES))
        #init_state[:, -1] = 1
        #observations = [init_state, init_state]
        #info = [{'available_actions': aa} for aa in self.available_actions]
        observations = self.deal()
        return observations#, info

    def step(self, action, state):
        ac0, ac1 = action
        ac0 = np.array([ ac0[2], ac0[ac1] ])
        win = -2.0*np.argmax(state) + 1.0 #+1 is P1 has the biggest card, -1 otherwise

        self.step_count += 1

        # Zero-Sum so we just need one componet where we store reward for P1

        if ac0[0] == ac1:
            reward = win + win*ac1
        else:
            if ac0[0] == 1:
                reward = 1
            else:
                reward = (2*win +1)*ac0[1] - ac1

        rewards = [reward, -reward]
        observations = self.deal()

        """
        # The state is a OHE vector indicating [CC, CD, DC, DD, initial], (iff NUM_STATES = 5)
        state0 = np.zeros((self.batch_size, self.NUM_STATES))
        state1 = np.zeros((self.batch_size, self.NUM_STATES))
        for i, (a0, a1) in enumerate(zip(ac0, ac1)):  # iterates over batch dimension
            rewards.append([self.payout_mat[a1][a0], self.payout_mat[a0][a1]])
            state0[i, a0 * 2 + a1] = 1
            state1[i, a1 * 2 + a0] = 1
        """

        done = (self.step_count == self.max_steps)
        #info = [{'available_actions': aa} for aa in self.available_actions]

        return observations, rewards, done


# Written by Wouter Ensink

# This file contains the engine class. This is the main component of the core.
# The UI can give it commands and ask for status about the core and the rhythm generators.

from core.exporters import MidiUtil_MidiFileSessionExporter, JsonFileSessionExporter
from core.sequencer import Sequencer
from core.importers import JsonFileSessionImporter
from core.event_handlers import SimpleAudio_EventHandler
from core.session import Session
from core.session_editor import SessionEditor
from core.euclidean import EuclideanRhythmGenerator

class Engine:
    def __init__(self):
        self.midi_exporter = MidiUtil_MidiFileSessionExporter()
        self.json_importer = JsonFileSessionImporter()
        self.session = Session()
        self.session_editor = SessionEditor()
        self.sequencer = Sequencer()
        self.sequencer.set_event_handler(SimpleAudio_EventHandler())
        self.json_exporter = JsonFileSessionExporter()
        self.generator = EuclideanRhythmGenerator()

    def shut_down(self) -> None:
        self.sequencer.shut_down()

    def load_session_from_json(self, file_name: str) -> None:
        self.load_session(self.json_importer.load_session(file_name))

    def load_session(self, session: Session):
        # if the sequencer is playing, it should stop until the new sequence is fully loaded
        # because otherwise it could be sending events to a handler that doesn't know about the sample yet.
        should_pause_playback = self.sequencer.is_playing()
        if should_pause_playback:
            self.sequencer.stop_playback()

        self.session_editor.set_session(session)
        self.sequencer.load_session(session)
        self.session = session

        if should_pause_playback:
            self.sequencer.start_playback()

    def export_session_to_json(self, file_name: str) -> None:
        self.json_exporter.store_session(self.session, file_name)

    def export_session_to_midi(self, file_name: str) -> None:
        self.midi_exporter.store_session(self.session, file_name)


def solution(a):
    arr=[[0 for _ in range(a)]for _ in range(a)]
    y=0
    x=a//2
    c=1
    arr[y][x]=c
    c+=1
    while True:
        if arr[y-1][x-1]==0:
            y-=1
            x-=1
            if x==-1:
                x=a-1
            if y==-1:
                y=a-1
        else:
            if y+1==a:
                y=0
            else:
                y+=1
            if arr[y][x]!=0:
                break
        arr[y][x]=c
        c+=1
    return arr
num=int(input())
arr=solution(num)
for i in range(num):
    if i!=0:
        print()
    for j in range(num):
        print(arr[i][j],end=' ')


import sys

#sys.path.append('E:/SoftWare/JetBrains/IntellijCode/PythonCode/Python3WebSpider/ZeroStudy/Lesson08/Exercise01')

from MyMoudle.Create_lotto import Create_lotto

print('大乐透号码生成器')
while True:
    times = input('请输入要生成的大乐透号码注数：')
    try:
        times = int(times)
        break
    except:
        print('请输入正确的数量')

lottoCodeList = Create_lotto(times)
for lottoCode in lottoCodeList:
    print(lottoCode)


# %%
import pytest
import numpy as np
import gravitools.double3 as d3
import gravitools.twobody_tools as tt
from gravitools.density_profile_generator import uniform_sphere
from gravitools.binding_energy_calculator import binding_energy_of_uniform_sphere
from gravitools.manybody_tools import kinetic_gravitational_potential

#####################################################

def test_double3_scalar_product():
    a = d3.Double3(1,2,3)
    b = d3.Double3(3,2,1)
    res = d3.scalar_product(a, b)

    assert(res==10)

def test_double3_sum():
    a = d3.Double3(1,2,3)
    b = d3.Double3(3,2,1)
    c = a + b

    assert(c.x==4)
    assert(c.y==4)
    assert(c.z==4)

def test_double3_sub():
    a = d3.Double3(1,2,3)
    b = d3.Double3(3,2,1)
    c = a - b

    assert(c.x==-2)
    assert(c.y==0)
    assert(c.z==2)

#####################################################

def test_star_tools_orbit():
    Mtot  = 1
    peri0 = 1.0
    ecc0  = 0.9

    t, x, y, Vx, Vy = tt.keplerian_trajectory(Mtot, peri=peri0, ecc=ecc0, theta=np.array([1.1]))

    dR = np.array([x[0], y[0], 0])
    dV = np.array([Vx[0], Vy[0], 0])

    ecc, a, peri, d = tt.ecc_semi_peri_distance(Mtot, dR, dV)

    Dperi = abs(peri0-peri)
    Decc = abs(ecc0-ecc)

    assert(Dperi<1e-5)
    assert(Decc<1e-5)

#####################################################

def test_potential_energy():

    R = 2
    N = int(3e+4)

    X, Y, Z = uniform_sphere(N=N, R=R)
    pos     = np.stack([X, Y, Z], axis=1)
    mass    = np.full(N, 1)

    _, U = kinetic_gravitational_potential(M=mass, pos=pos, vel=pos)
    U0   = binding_energy_of_uniform_sphere(R=R, M=N)

    assert( abs((U-U0)/U0)< 1e-2 )

# %%


from simpleimage import SimpleImage

N_TIMES = 9

def main():
    old_img = SimpleImage("images/smiley-face.png")
    old_img.show()
    blurred_img = blur(old_img)
    for i in range(N_TIMES):
        blurred_img = blur(blurred_img)
    blurred_img.show()

def blur(old_image):
    blurred = SimpleImage.blank(old_image.width,  old_image.height)
    for y in range(old_image.height):
        for x in range(old_image.width):
            r_sum = 0
            g_sum = 0
            b_sum = 0
            count = 0
            for i in range(-1, 2, 1):
                for j in range(-1, 2, 1):
                    pixel_x = x + i
                    pixel_y = y + j
                    if 0 <= pixel_x < old_image.width:
                        if 0 <= pixel_y < old_image.height:
                            pixel = old_image.get_pixel(pixel_x, pixel_y)
                            r_sum += pixel.red
                            g_sum += pixel.green
                            b_sum += pixel.blue
                            count += 1
            new_pixel = blurred.get_pixel(x, y)
            new_pixel.red = r_sum/count
            new_pixel.green = g_sum/count
            new_pixel.blue = b_sum / count
    return blurred

if __name__ == '__main__':
    main()


import math
import random
import time

s = int(input())
a = int(input())
n = int(input())
x = int(input())

random.seed(s)

A = [random.randint(1, a) for _ in range(n)]

A.sort()

def measure(f):
    start = time.time()
    result = f()
    end = time.time()
    return (result, end - start)

def contains1():
    return x in A

def contains2():
    for y in A:
        if x == y:
            return True

    return False

def contains3():
    left = 0
    right = len(A)

    while left + 1 < right:
        center = math.floor((left + right) / 2)
        if x < A[center]:
            right = center
        else:
            left = center

    return A[left] == x

funcs = [contains1, contains2, contains3]

for i, func in enumerate(funcs):
    result, measured_time = measure(func)
    print(f"手法{i + 1}:", x, 'を発見' if result else 'は存在しません', '実行時間', measured_time)


from kivymd.uix.responsivelayout import MDResponsiveLayout

from View.HomeScreen.components import (
    HomeMobileScreenView,
    TabletScreenView,
    DesktopScreenView,
)
from View.base_screen import BaseScreenView
from kivy.properties import ListProperty

class HomeScreenView(MDResponsiveLayout, BaseScreenView):
    _data = ListProperty()
    def __init__(self, **kw):
        super().__init__(**kw)
        self.mobile_view = HomeMobileScreenView()
        self.tablet_view = TabletScreenView()
        self.desktop_view = DesktopScreenView()
        # print(self.model.data)
        # print(self.mobile_view.name)
        for x in self.model._data:
            x['father'] = self
        self.mobile_view.ids.home_tile.data = self.model.data
        self.mobile_view.ids.home_tile.bind(scroll_y=self.controller.update_scroll)
        # print(self.ids.home_refresh_layout.ids)
        # print(self.mobile_view.ids)

    def model_is_changed(self) -> None:
        """
        Called whenever any change has occurred in the data model.
        The view in this method tracks these changes and updates the UI
        according to these changes.
        """
        print('model is changed home')

    def testing(self) -> None:
        print('home screen testing new model modifiers method')


import random
from enum import Enum

class Card:

    def __init__(self, suit, rank, player=False):
        self._suit = suit
        self._rank = rank
        self._player = player
        self._cardFront
        self._cardBack

        for card in CardSVGs:
            if self._suit.name in card:
                if self._rank.name in card:
                    self._cardFront = card
                    break

    def printCardFront(self):
        img = mpimg.imread(self._cardFront)
        imgplot = plt.imshow(img)
        plt.show()

    def setPlayer(self, player):
        self._player = player

    def getPlayer(self):
        return self._player

    def getCardNeat(self):
        return (self._suit.value, self._rank.value)

    def getSuit(self):
        return self._suit

    def getRankStr(self):
        return self._rank

    def isEqual(self, card):
        if self._suit == card._suit and self._rank == card._rank:
            return True
        else:
            return False

    def getSimpleCard(self):
        return self._suit.value + self._rank.value

    def isCounter(self):
        if self._rank == Ranks.ACE or self._rank == Ranks.TEN or self._rank == Ranks.KING:
            return True
        else:
            return False

    def getRankNum(self):
        switcher = {
            Ranks.ACE: 6,
            Ranks.TEN: 5,
            Ranks.KING: 4,
            Ranks.QUEEN: 3,
            Ranks.JACK: 2,
            Ranks.NINE: 1
        }
        return switcher.get(self._rank)

def getRankNum(rank):
    switcher = {
        Ranks.ACE : 6,
        Ranks.TEN : 5,
        Ranks.KING : 4,
        Ranks.QUEEN : 3,
        Ranks.JACK : 2,
        Ranks.NINE : 1
    }
    return switcher.get(rank)

class Ranks(Enum):
    ACE = 'A'
    TEN = '10'
    KING = 'K'
    QUEEN = 'Q'
    JACK = 'J'
    NINE = '9'

class Suits(Enum):
    SPADES = 'S'
    CLUBS = 'C'
    DIAMONDS = 'D'
    HEARTS = 'H'

class CardSVGs(Enum):
    CLUBS_ACE = 'CLUB-1-ACE.svg'
    CLUBS_NINE = 'CLUB-9-NINE.svg'
    CLUBS_TEN = 'CLUB-10-TEN.svg'
    CLUBS_JACK = 'CLUB-11-JACK.svg'
    CLUBS_QUEEN = 'CLUB-12-QUEEN.svg'
    CLUBS_KING = 'CLUB-13-KING.svg'
    DIAMONDS_ACE = 'DIAMOND-1-ACE.svg'
    DIAMONDS_NINE = 'DIAMOND-9-NINE.svg'
    DIAMONDS_TEN = 'DIAMOND-10-TEN.svg'
    DIAMONDS_JACK = 'DIAMOND-11-JACK.svg'
    DIAMONDS_QUEEN = 'DIAMOND-12-QUEEN.svg'
    DIAMONDS_KING = 'DIAMOND-13-KING.svg'
    HEARTS_ACE = 'HEART-1-ACE.svg'
    HEARTS_NINE = 'HEART-9-NINE.svg'
    HEARTS_TEN = 'HEART-10-TEN.svg'
    HEARTS_JACK = 'HEART-11-JACK.svg'
    HEARTS_QUEEN = 'HEART-12-QUEEN.svg'
    HEARTS_KING = 'HEART-13-KING.svg'
    SPADES_ACE = 'SPADES-1-ACE.svg'
    SPADES_NINE = 'SPADES-9-NINE.svg'
    SPADES_TEN = 'SPADES-10-TEN.svg'
    SPADES_JACK = 'SPADES-11-JACK.svg'
    SPADES_QUEEN = 'SPADES-12-QUEEN.svg'
    SPADES_KING = 'SPADES-13-KING.svg'

class NoNumberBid(Enum):
    PASS = 'pass'
    BID_OR_BUNCH = "bid or bunch"

def getSuitEnum(str):
    for suit in Suits:
        if str == suit.value:
            return suit

def getRankEnum(str):
    for rank in Ranks:
        if str == rank.value:
            return rank

class Deck:

    def __init__(self):
        self._deck = []
        for suit in Suits:
            for rank in Ranks:
                self._deck.append(Card(suit, rank))
                self._deck.append(Card(suit, rank))

    def shuffle(self):
        random.shuffle(self._deck)

    def takeTopCard(self):
        top = self._deck[len(self._deck)-1]
        self._deck.remove(top)
        return top

class Player:

    def __init__(self, name=""):
        self._name = name
        self._hand = []
        self._bid = ""
        self._meld = 0

    def getName(self):
        return self._name

    def setName(self, name):
        self._name = name

    def getCardFromSimple(self, simpleCard):
        for card in self._hand:
            if card.getSimpleCard() == simpleCard:
                return card

    def resetBid(self):
        self._bid = ""

    def fillHand(self, card):
        self._hand.append(card)
        self.sortHand()

    def isInHand(self, card):
        for c in self._hand:
            if c == card:
                return True
        return False

    def removeCard(self, card):
        self._hand.remove(card)

    def getHand(self):
        return self._hand

    def getSimpleHand(self):
        simpleHand = []
        for card in self._hand:
            simpleHand.append(card.getSimpleCard())
        return simpleHand

    def printHandFront(self):
        for card in self._hand:
            card.printCardFront()

    def sorting(self, card):
        key = card.getSimpleCard()
        return key[0] + str(card.getRankNum())

    def sortHand(self):
        self._hand.sort(key=self.sorting, reverse=True)

    def askBid(self, currentBid, first):
        if self.getBid() == NoNumberBid.PASS:
            return
        bid = input(self.getName() + ", enter bid:")
        bid = bid.lower()
        for b in NoNumberBid:
            if b.value == bid:
                bid = b
        if bid == NoNumberBid.PASS:
            self._bid = bid
        elif bid == NoNumberBid.BID_OR_BUNCH:
            if first is True and currentBid == 240:
                self._bid = bid
            else:
                print(self.getName() + ", enter appropriate bid")
                self.askBid(currentBid, first)
                return
        else:
            try:
                bid = int(bid)
            except ValueError:
                print(self.getName() + ", enter integer bid")
                self.askBid(currentBid, first)
                return
            if bid % 10 != 0:
                print(self.getName() + ", enter appropriate integer bid")
                self.askBid(currentBid, first)
                return
            if bid <= currentBid:
                print(self.getName() + ", enter larger bid")
                self.askBid(currentBid, first)
                return
            self._bid = bid

    def outOfSuit(self, suit):
        for card in self._hand:
            if card.getSuit() == suit:
                return False
        return True

    def canBeat(self, suit, rank):
        for card in self._hand:
            if card.getSuit() == suit:
                if card.getRankNum() > rank:
                    return True
        return False

    def askTrick(self, trickRound, trump):
        leadingTrick = trickRound.isLeadingCard()

        trickSimple = input(self.getName() + ", play trick:").upper()
        trick = Card(getSuitEnum(trickSimple[0]), getRankEnum(trickSimple[1:]), self)
        for card in self._hand:
            if card.isEqual(trick):
                if leadingTrick:
                    return card
                else:
                    firstSuit = trickRound.getFirstCard().getSuit()
                    winner = trickRound.getWinningCard(trump)
                if not self.outOfSuit(firstSuit):
                    winner = trickRound.getWinningCard(trump, True)
                    if trick.getSuit() != firstSuit:
                        print(self.getName() + ", enter card in suit")
                        return
                    elif self.canBeat(firstSuit, winner.getRankNum()):
                        if trick.getRankNum() > winner.getRankNum():
                            return card
                        else:
                            print(self.getName() + ", enter appropriate card. You must win the trick if you can.")
                            return
                    else:
                        return card
                elif not self.outOfSuit(trump):
                    if winner.getSuit() != trump:
                        if trick.getSuit() == trump:
                            return card
                        else:
                            print(self.getName() + ", enter trump card. You must win the trick if you can.")
                            return
                    elif self.canBeat(winner.getSuit(), winner.getRankNum()):
                        if trick.getSuit() == trump and trick.getRankNum() > winner.getRankNum():
                            return card
                        else:
                            print(self.getName() + ", enter trump card. You must win the trick if you can.")
                            return
                    else:
                        return card
                else:
                    return card
        print(self.getName() + ", enter trick card from hand")
        return

    def getBid(self):
        return self._bid

    def getMeld(self):
        return self._meld

    def scoreGroups(self, group, score, doubleScore):
        tempHand = self.getSimpleHand()
        if set(group).issubset(tempHand):
            for card in group:
                tempHand.remove(card)
            if set(group).issubset(tempHand):
                self._meld += doubleScore
            else:
                self._meld += score

    def scoreHand(self, trump):
        fiveNinesNoMeldCheck = False
        if trump is None:
            fiveNinesNoMeldCheck = True

        acesAround = []
        kingsAround = []
        queensAround = []
        jacksAround = []
        for s in Suits:
            acesAround.append(s.value + 'A')
            kingsAround.append(s.value + 'K')
            queensAround.append(s.value + 'Q')
            jacksAround.append(s.value + 'J')

        pinochle = [Suits.SPADES.value + "Q", Suits.DIAMONDS.value + "J"]

        self.scoreGroups(acesAround, 100, 1000)
        self.scoreGroups(kingsAround, 80, 800)
        self.scoreGroups(queensAround, 60, 600)
        self.scoreGroups(jacksAround, 40, 400)

        self.scoreGroups(pinochle, 40, 300)

        for suit in Suits:
            if not fiveNinesNoMeldCheck and suit != trump:
                marriage = [suit.value + "K", suit.value + "Q"]
                self.scoreGroups(marriage, 20, 40)
            else:
                marriage = [suit.value + "K", suit.value + "Q"]
                self.scoreGroups(marriage, 20, 40)

        if not fiveNinesNoMeldCheck:
            run = [trump.value + "A", trump.value + "10", trump.value + "K", trump.value + "Q", trump.value + "J"]
            royalMarriage = [trump.value + "K", trump.value + "Q"]
            royalHalfMarriageA = [trump.value + "A", trump.value + "10", trump.value + "K", trump.value + "K", trump.value + "Q", trump.value + "J"]
            royalHalfMarriageB = [trump.value + "A", trump.value + "10", trump.value + "K", trump.value + "Q", trump.value + "Q", trump.value + "J"]
            nine = [trump.value + "9"]

            if set(run).issubset(self.getSimpleHand()):
                self.scoreGroups(run, 150, 1500)
                if set(royalHalfMarriageA).issubset(self.getSimpleHand()):
                    self._meld += 20
                if set(royalHalfMarriageB).issubset(self.getSimpleHand()):
                    self._meld += 20
            elif set(royalMarriage).issubset(self.getSimpleHand()):
                self.scoreGroups(royalMarriage, 40, 80)

            self.scoreGroups(nine, 10, 20)
            print(self.getName() + "'s meld: " + str(self._meld))

    def loadMeldPoints(self):
        tempMeld = self._meld
        self._meld = 0
        return tempMeld

    def is5NinesNoMeld(self):
        nines = 0
        for card in self._hand:
            if card.getRankNum() == 1:
                nines += 1
        if nines < 5:
            return False
        else:
            self.scoreHand(None)
            if self._meld == 0:
                return True
            else:
                return False

class Team:

    def __init__(self, player1, player2, name):
        self._p1 = player1
        self._p2 = player2
        self._name = name
        self._score = 0
        self._roundScore = 0

    def isOnTeam(self, player):
        if player == self._p1 or player == self._p2:
            return True
        else:
            return False

    def getPartners(self):
        return [self._p1, self._p2]

    def getPartner1(self):
        return self._p1

    def getPartner2(self):
        return self._p2

    def getPartnerOf(self, player):
        if player == self._p1:
            return self._p2
        else:
            return self._p1

    def addScore(self, score, newRound=False):
        if not newRound:
            self._roundScore += score
        else:
            self._score += score

    def getScore(self):
        return self._score

    def getRoundScore(self):
        return self._roundScore

    def getName(self):
        return self._name

    def setName(self, name):
        self._name = name

class Game:

    def __init__(self, players=['', '', '', '']):
        self._p1 = Player(players[0])
        self._p2 = Player(players[1])
        self._p3 = Player(players[2])
        self._p4 = Player(players[3])
        self._allPlayers = [self._p1, self._p2, self._p3, self._p4]
        self._team1 = Team(self._p1, self._p3, "Team 1")
        self._team2 = Team(self._p2, self._p4, "Team 2")
        self._allTeams = [self._team1, self._team2]
        self._gameOver = False

    def askTeamNames(self):
        for team in self._allTeams:
            players = ""
            for player in team.getPartners():
                players += player.getName() + " and "
            players = players.removesuffix(' and ')
            name = input(players + " team name: ")
            team.setName(name)

    def askPlayerNames(self):
        for player in self._allPlayers:
            name = input("Player " + str(self._allPlayers.index(player) + 1) + " name: ")
            player.setName(name)

    def getAllPlayers(self):
        return self._allPlayers

    def getPlayers(self, number): #number is 1-4
        return self._allPlayers[number - 1]

    def getAllTeams(self):
        return self._allTeams

    def getTeams(self, number): # number is 1-2
        return self._allTeams[number-1]

    def showScores(self):
        print("Scores")
        print(self._team1.getName() + ": " + str(self._team1.getScore()))
        print(self._team2.getName() + ": " + str(self._team2.getScore()))

    def gameOver(self):
        self._gameOver = True

    def isGameOver(self):
        return self._gameOver

    def playRound(self):
        round = PinochleRound(self)
        round.deal()
        round.showAllHands()
        round.bidding()
        round.passingCards()
        round.scoreMeld()
        round.trickPlaying()
        round.finishRound()

class Tricks:

    def __init__(self):
        self._cardsPlayed = []
        self._winningcard = None
        self._leadingCard = True

    def playCard(self, card):
        self._cardsPlayed.append(card)
        self._leadingCard = False

    def isLeadingCard(self):
        return self._leadingCard

    def isDone(self):
        if len(self._cardsPlayed) >= 4:
            return True
        else:
            return False

    def getFirstCard(self):
        if not self._leadingCard:
            return self._cardsPlayed[0]
        else:
            return None

    def getWinningCard(self, trump, ignoreTrump=False):
        winRank = 0
        winSuit = self._cardsPlayed[0].getSuit()
        winningCard = None
        for card in self._cardsPlayed:
            if card.getSuit() == winSuit:
                if card.getRankNum() > winRank:
                    winRank = card.getRankNum()
                    winningCard = card
            elif card.getSuit() == trump:
                if not ignoreTrump:
                    winSuit = trump
                    winRank = card.getRankNum()
                    winningCard = card
        return winningCard

    def getCounters(self):
        counters = 0
        for card in self._cardsPlayed:
            if card.isCounter():
                counters += 10
        return counters

class PinochleRound:

    def __init__(self, game):
        self._allPlayers = game.getAllPlayers()
        self._team1 = game.getTeams(1)
        self._team2 = game.getTeams(2)
        self._deck = Deck()
        self._deck.shuffle()
        self._trump = False
        self._finalBid = 0
        self._tookBid = False
        self._shootMoon = False
        self._game = game

    def deal(self):
        for index in range(12):
            for player in self._allPlayers:
                card = self._deck.takeTopCard()
                player.fillHand(card)
                card.setPlayer(player)

    def dealRigged(self):
        for index in range(12):
            for player in self._allPlayers:
                if self._allPlayers.index(player) == 3:
                    card = Card(Suits.SPADES, Ranks.NINE, player)
                else:
                    card = self._deck.takeTopCard()
                player.fillHand(card)
                card.setPlayer(player)

    def reshuffle(self):
        for player in self._allPlayers:
            hand = player.getHand().copy()
            for index in range(len(hand)):
                player.removeCard(hand[index])
        self._deck = Deck()
        self._deck.shuffle()

    def getPlayer(self, playerName):
        for player in self._allPlayers:
            if player.getName() == playerName:
                return player

    def getTeam(self, player):
        if player in self._team1.getPartners():
            return self._team1
        else:
            return self._team2

    def getOtherTeam(self, player):
        if player in self._team1.getPartners():
            return self._team2
        else:
            return self._team1

    def addScore(self, score, player):
        team = self.getTeam(player)
     #   if team == self.getTeam(self._tookBid):
     #       self._biddersScore += score
        team.addScore(score)

    def showHand(self, player):
        print(player.getName() + "'s hand:")
        #for card in player.getHand():
            #print(card.getCardNeat())
        player.printCardFront()

    def showAllHands(self):
        for player in self._allPlayers:
            self.showHand(player)

    def check5NinesNoMeld(self):
        for player in self._allPlayers:
            if player.is5NinesNoMeld():
                while True:
                    answer = input(player.getName() + ", do you want to throw with 5 nines no meld?").upper()
                    if answer == "YES":
                        print(player.getName() + " had 5 nines no meld. Reshuffling and dealing")
                        self.reshuffle()
                        self.deal()
                        self.showAllHands()
                        self.check5NinesNoMeld()
                        break
                    elif answer == "NO":
                        return
                    else:
                        print("Answer with yes or no")

    def bidding(self):
        self.check5NinesNoMeld()
        passed = 0
        currentBid = 240
        for player in self._allPlayers:
            player.resetBid()
        biddingPlayers = self._allPlayers.copy()
        first = True
        while passed < 3:
            for player in biddingPlayers.copy():
                player.askBid(currentBid, first)
                if player.getBid() == NoNumberBid.PASS:
                    passed += 1
                    if passed == 4 and first == True:
                        break
                    biddingPlayers.remove(player)
                    if passed >= 3 and first == False:
                        break
                else:
                    if type(player.getBid()) is int:
                        currentBid = player.getBid()
            else:
                first = False
                continue
            break

        finalBid = biddingPlayers[0].getBid()
        if finalBid == NoNumberBid.PASS:
            print("No bids, reshuffle?")
            self.reshuffle()
            self.deal()
            self.bidding()
            return
        else:
            self._finalBid = finalBid
            self._tookBid = biddingPlayers[0]
            print("Final bid: " + str(finalBid) + ", " + biddingPlayers[0].getName())
            while True:
                trump = input(biddingPlayers[0].getName() + ", enter trump suit:")
                trump = trump.upper()
                for suit in Suits:
                    if trump == suit.name:
                        self._trump = suit
                if self._trump in list(Suits):
                    break

    def pass4Cards(self, playerPassing):
        recieving = self.getTeam(playerPassing).getPartnerOf(playerPassing)
        counter = 1
        self.showHand(playerPassing)
        message = playerPassing.getName() + ", pass card " + str(counter) + ":"
        while counter < 5:
            cardToPassSimple = input(message).upper()
            cardToPass = playerPassing.getCardFromSimple(cardToPassSimple)
            if playerPassing.isInHand(cardToPass):
                recieving.fillHand(cardToPass)
                playerPassing.removeCard(cardToPass)
                counter += 1
                message = playerPassing.getName() + ", pass card " + str(counter) + ":"
            else:
                message = 'Card not in hand. ' + playerPassing.getName() + ", pass card " + str(counter) + ":"

    def passingCards(self):
        player = self._tookBid
        team = self.getTeam(player)
        partner = team.getPartnerOf(player)

        self.pass4Cards(partner)
        self.pass4Cards(player)

    def scoreMeld(self):
        for player in self._allPlayers:
            player.scoreHand(self._trump)

        self.askShootMoon()

        if not self.canMakeBid() and not self._shootMoon:
            self.throwIn()
            return

        for player in self._allPlayers:
            if self._shootMoon:
                if self.getTeam(player) != self.getTeam(self._tookBid):
                    self.addScore(player.loadMeldPoints(), player)
            else:
                self.addScore(player.loadMeldPoints(), player)

    def canMakeBid(self):
        meld = self._tookBid.getMeld() + self.getTeam(self._tookBid).getPartnerOf(self._tookBid).getMeld()
        if meld + 250 < self._finalBid:
            return False
        else:
            return True

    def askShootMoon(self):
        while True:
            answer = input(self._tookBid.getName() + ", do you want to shoot the moon?").upper()
            if answer == "YES":
                print(self._tookBid.getName() + " is shooting the moon")
                self._shootMoon = True
                return
            elif answer == "NO":
                self._shootMoon = False
                return
            else:
                print("Answer with yes or no")

    def getNextPlayer(self, currentPlayer):
        for player in self._allPlayers:
            if player == currentPlayer:
                index = self._allPlayers.index(player)
                return self._allPlayers[(index +  1)%4]

    def trickPlaying(self):
        nextPlayer = self._tookBid
        round = 1
        trickCards = Tricks()
        while round < 13:
            for player in self._allPlayers:
                if trickCards.isDone():
                    counters = trickCards.getCounters()
                    if round == 12:
                        counters += 10
                    winCard = trickCards.getWinningCard(self._trump)
                    self.addScore(counters, winCard.getPlayer())
                    self._game.showScores()
                    trickCards = Tricks()
                    nextPlayer = winCard.getPlayer()
                    round += 1
                    break
                if player == nextPlayer:
                    self.showHand(player)
                    trick = None
                    while trick is None:
                        trick = player.askTrick(trickCards, self._trump)
                    player.removeCard(trick)
                    trickCards.playCard(trick)
                    nextPlayer = self.getNextPlayer(player)

    def madeBid(self):
        if self._shootMoon:
            self._finalBid = 250

        if self.getTeam(self._tookBid).getRoundScore() >= self._finalBid:
            return True
        else:
            if self._shootMoon:
                self._finalBid = 500
            return False

    def finishRound(self):
        biddingTeam = self.getTeam(self._tookBid)
        otherTeam = self.getOtherTeam(self._tookBid)
        print(biddingTeam.getName(), " bid: ", self._finalBid)

        if self.madeBid():
            score = biddingTeam.getRoundScore()
            if self._shootMoon:
                score = 500
            biddingTeam.addScore(score, True)
            print(biddingTeam.getName(), "made bid!")
            print(biddingTeam.getName(), "scored:", score)
        else:
            biddingTeam.addScore(-self._finalBid, True)
            print(biddingTeam.getName(), "did not make the bid! :(")
            print(biddingTeam.getName(), "scored:", -self._finalBid)

        score = otherTeam.getRoundScore()
        otherTeam.addScore(score, True)
        print(otherTeam.getName(), " scored: ", score)

        winner = self.winner()
        if winner is not Null:
            print(winner.getName(), " wins!!")
            self._game.showScores()

    def winner(self): #Null is no winner yet
        t1Score = self._team1.getScore()
        t2Score = self._team2.getScore()

        if t1Score < 1500 and t1Score > -1500 and t2Score < 1500 and t2Score > -1500:
            return Null
        elif t1Score >= 1500 and t2Score < t1Score:
            return self._team1
        elif t2Score >= 1500 and t1Score < t2Score:
            return self._team2
        elif t1Score <= -1500 and t2Score > t1Score:
            return self._team2
        elif t2Score <= -1500 and t1Score > t2Score:
            return self._team1
        else:
            return Null

if __name__ == '__main__':
    players = ["Lizzy", "Micah", "Dad", "Mom"]
    myGame = Game(players)
    myGame.showScores()
  #  myGame.askPlayerNames()
  #  myGame.askTeamNames()
    myGame.playRound()


# None
import random
from random import shuffle
from typing import List

class Solution:
    def mini_median(self, nums):
        nums = sorted(nums)
        n = len(nums)
        mid = n // 2
        return nums[mid] if n & 1 else (nums[mid] + nums[mid - 1]) / 2

    def mom(self, subarrays):
        mom = [self.mini_median(subarray) for subarray in subarrays]
        return self.mini_median(mom)

    def partition(self, nums, l, r, pivot_idx):
        pivot_val = nums[pivot_idx]
        nums[r], nums[pivot_idx] = pivot_val, nums[r]
        store_idx = l
        for i in range(l, r):
            if nums[i] < pivot_val:
                nums[i], nums[store_idx] = nums[store_idx], nums[i]
                store_idx += 1
        nums[store_idx], nums[r] = nums[r], nums[store_idx], nums[r]

    def findMedian(self, nums: List[int]) -> float:
        n = len(nums)
        something = self.mom([nums[i:(i+5)] for i in range(0, n, 5)])
        print(something)

solution = Solution()

def check(input, expected):
    output = solution.findMedian(input)
    assert output == expected

random.seed(5)

a = [1, 2, 3, 4, 5, 6, 7]
b = [1, 2, 3, 4, 5, 6]

shuffle(a)
shuffle(b)

check(a, 4.)
check(b, (3 + 4) / 2)


#!/usr/bin/env python3
# vim: textwidth=0 wrapmargin=0 tabstop=2 shiftwidth=2 softtabstop=2 smartindent smarttab

import os
import yaml, logging, argparse

import random, base64, hashlib
import json
import cgi
#import cgitb
#cgitb.enable(display=0, logdir="/var/www/user-rw/athan.fysh.org/fd-api-logs")

import urllib.request
import requests
import pprint
pp = pprint.PrettyPrinter(indent=2)

import org.miggy.edcapi

###########################################################################
"""
 "  Configuration
"""
###########################################################################
__configfile_fd = os.open("fd-api-config.yaml", os.O_RDONLY)
__configfile = os.fdopen(__configfile_fd)
__config = yaml.load(__configfile, Loader=yaml.CLoader)
###########################################################################

###########################################################################
# Logging
###########################################################################
os.environ['TZ'] = 'UTC'
__default_loglevel = logging.INFO
__logger = logging.getLogger('fd-api')
__logger.setLevel(__default_loglevel)
__logger_ch = logging.StreamHandler()
__logger_ch.setLevel(__default_loglevel)
__logger_formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(module)s.%(funcName)s:\n%(message)s')
__logger_formatter.default_time_format = '%Y-%m-%d %H:%M:%S';
__logger_formatter.default_msec_format = '%s.%03d'
__logger_ch.setFormatter(__logger_formatter)
__logger.addHandler(__logger_ch)
###########################################################################

###########################################################################
# MAIN
###########################################################################
def main():
  __logger.debug('Start-Up')

  if not os.getenv('GATEWAY_INTERFACE'):
    handleCLI()
  else:
    handleCGI()

###########################################################################
# Being called from command-line
###########################################################################
def handleCLI():
  #########################################
  # Command-Line Arguments
  #########################################
  __parser = argparse.ArgumentParser()
  __parser.add_argument("--loglevel", help="set the log level to one of: DEBUG, INFO (default), WARNING, ERROR, CRITICAL")
  __parser.add_argument("cmdrname", nargs=1, help="Specify the Cmdr Name for this Authorization")
  __args = __parser.parse_args()
  cmdrName = __args.cmdrname[0]
  if __args.loglevel:
    __level = getattr(logging, __args.loglevel.upper())
    __logger.setLevel(__level)
    __logger_ch.setLevel(__level)

  #########################################

  ########################################
  # Retrieve and test state
  ########################################
  db = org.miggy.edcapi.database.database(__logger, __config)
  __logger.debug("cmdrName: '{}'".format(cmdrName))
  auth_state = db.getActiveTokenState(cmdrName)
  if auth_state:
    ## Do we have an access_token, and does it work?
    if auth_state['access_token']:
      print("Found un-expired access_token, assuming it's good.")
      return(0)
    else:
      print("Un-expired access_token, but no access_token? WTF!")
      return(-1)
  else:
    print("No auth state with un-expired access_token found, continuing...")
  ########################################

  ########################################
  # Generate Code Verifier
  ########################################
  verifier = random.SystemRandom().getrandbits(8 * 32)
  __logger.debug('raw verifier: {}'.format(verifier))
  # We need a Base64, URL safe, version of this. NB: the '=' on the end is
  # OK in this instance.
  verifier_b64 = base64.urlsafe_b64encode(verifier.to_bytes(32, byteorder='big'))
  __logger.debug('b64 verifier: {}'.format(verifier_b64))
  ########################################

  ########################################
  # Generate Code Challenge
  ########################################
  # Using the URL-safe Base64 version of verifier, with the '=' still on the
  # end
  challenge = hashlib.sha256(verifier_b64).digest()
  __logger.debug('raw challenge: {}'.format(challenge))
  challenge_b64 = base64.urlsafe_b64encode(challenge)
  __logger.debug('b64 challenge: {}'.format(challenge_b64))
  challenge_b64_str = challenge_b64.decode().replace('=','')
  __logger.debug('str challenge: {}'.format(challenge_b64_str))
  ########################################

  ########################################
  # Generate 'State'
  ########################################
  state = random.SystemRandom().getrandbits(8 * 32)
  __logger.debug('raw state: {}'.format(state))
  #state_b64 = base64.b64encode(state.to_bytes(32, byteorder='big'))
  state_b64 = base64.urlsafe_b64encode(state.to_bytes(32, byteorder='big'))
  __logger.debug('b64 state: {}'.format(state_b64))
  state_b64_str = state_b64.decode().replace('=','')
#.replace('+','-').replace('/','_').replace('=','')
  __logger.debug('str state: {}'.format(state_b64_str))
  ########################################

  ########################################
  # Store state and the codes for when redirect_uri is called
  ########################################
  db.storeNewState(state_b64_str, challenge_b64.decode(), verifier_b64.decode(), cmdrName)
  ########################################

  ########################################
  # Get the User's Authorization
  ########################################
  __logger.debug("auth_api_url: '{}'".format(__config.get('auth_api_url')))
  request_uri = (__config.get('auth_api_url') +
      '/auth?'
      'response_type=code'
      '&audience=frontier,steam,epic'
      '&scope=capi'
      '&client_id=' + __config.get('clientid') +
      '&code_challenge=' + challenge_b64_str +
      '&code_challenge_method=S256'
      '&state=' + state_b64_str +
      '&redirect_uri=' + __config.get('redirect_uri')
  )
  print('Go to the following URL and Authorize the Application:\n\n{}\n'.format(request_uri))
  return(0)
  ########################################
###########################################################################

###########################################################################
# Being called as CGI
###########################################################################
def handleCGI():
  print('Content-Type: text/plain')
  print()
  ########################################
  # Check the received code
  ########################################
  getparams = cgi.FieldStorage()
  #cgi.test()
  #print("getparams:\n{}\n".format(getparams))
  if 'code' not in getparams:
    __logger.error("No 'code' received")
    return(-1)
  auth_code = getparams['code'].value
  if 'state' not in getparams:
    __logger.error("No 'state' received")
    return(-1)
  state_recv = getparams['state'].value
  ####
  # Retrieve state
  ####
  db = org.miggy.edcapi.database.database(__logger, __config)
  if not db:
    __logger.error('Failed to open auth state database')
  auth_state = db.getAuthState(state_recv)
  ####

  if auth_state and state_recv != auth_state['state']:
    __logger.error("Received state doesn't match the stored one")
    return(-2)
  __logger.debug("Auth Code: '{}'".format(auth_code))
  __logger.debug("Received State: '{}'".format(state_recv))
  ########################################

  ########################################
  # Make a Token Request
  ########################################
  uri = __config.get('auth_api_url') + '/token'
  data = {
    'grant_type': 'authorization_code',
    'code': auth_code,
    'redirect_uri': __config.get('redirect_uri'),
    'client_id': __config.get('clientid'),
    'code_verifier': auth_state['verifier']
  }
  req_data = ""
  for d in data.keys():
    if d == 'redirect_uri':
      req_data = req_data + urllib.parse.urlencode({d:data[d]}) + "&"
    else:
      req_data = req_data + d + "=" + data.get(d) + "&"
  req_data = req_data[0:-1]
  req_data = req_data.encode('ascii')
  #print("req_data:\n{}\n".format(req_data))
  #return(0)
  ### import http.client as http_client
  ### http_client.HTTPConnection.debuglevel = 1
  ### requests_log = logging.getLogger("requests.packages.urllib3")
  ### requests_log.setLevel(logging.DEBUG)
  ### requests_log.propagate = True

  response = requests.post(uri, data=req_data,
    headers={
      'Content-Type': 'application/x-www-form-urlencoded',
      'User-Agent': __config.get('user_agent')
    }
  )
  tokens = json.loads(response.text)
  print(response.text)
  ########################################

  ########################################
  # Update stored data with the access_token, refresh_token and expires
  ########################################
  db.updateWithAccessToken(
    state_recv,
    tokens['token_type'],
    tokens['access_token'],
    tokens['refresh_token'],
    tokens['expires_in']
  )
  ########################################

  ########################################
  # Retrieve /decode so we know who this Access Token is for
  ########################################
  uri = __config.get('auth_api_url') + '/decode'
  session = requests.Session()
  session.headers.update(
    {
      'User-Agent': __config.get('user_agent'),
      "Authorization": "Bearer " + tokens["access_token"],
      "Content-Type": "application/json"
    }
  )
  response = session.get(uri)
  decode = json.loads(response.text)
  print(response.text)
  db.updateWithCustomerID(tokens['access_token'], decode['usr']['customer_id'])
  ########################################
###########################################################################

if __name__ == '__main__':
      main()


"""
Production Settings for Heroku
"""
import os
import django_heroku

from tfwvirtual.settings.dev import *

ALLOWED_HOSTS = ['tfwvirtual.herokuapp.com']

# Parse database connection url strings like psql://user:pass@127.0.0.1:8458/db
DATABASES = {
    # read os.environ['DATABASE_URL'] and raises ImproperlyConfigured exception if not found
    'default': os.environ.get('DATABASE_URL'),
}

django_heroku.settings(locals())

SECURE_HSTS_SECONDS = 3600
SECURE_SSL_REDIRECT = True
SESSION_COOKIE_SECURE = True
CSRF_COOKIE_SECURE = True
SECURE_HSTS_INCLUDE_SUBDOMAINS = True
SECURE_HSTS_PRELOAD = True


import os
from collections import OrderedDict

os.environ['OPENBLAS_NUM_THREADS'] = '1'
os.environ['OMP_NUM_THREADS'] = '1'
os.environ['MKL_NUM_THREADS'] = '1'
os.environ['TF_XLA_FLAGS'] = '--tf_xla_enable_xla_devices'

import tensorflow as tf

tf.config.threading.set_inter_op_parallelism_threads(1)
tf.config.threading.set_intra_op_parallelism_threads(1)

import numpy as np
np.random.seed(0)

import sys
sys.path.append('./precompiler')

import graph
from graph import convert_keras_to_graph

from benchmarks import benchmark, get_benchmarks

import argparse

import logging
logging.basicConfig(filename='logger.out', filemode='w', level=logging.INFO)

import json

def split_mat(x_size, w_size, array_size, tile_first_dim=None):
    no_row, no_col = array_size

    if tile_first_dim is None:
        partition_size = (no_row, no_row, no_col)
    else:
        partition_size = (tile_first_dim, no_row, no_col)

    dim1 = int(x_size[0])
    dim2 = int(w_size[0])
    dim3 = int(w_size[1])

    no_row_tile = int( np.ceil (dim2 / partition_size[1]) )
    no_col_tile = int( np.ceil (dim3 / partition_size[2]) )

    w_tile_dim = {i:{} for i in range(no_row_tile)}
    for j in range(no_col_tile):
        for i in range(no_row_tile):
            tile_dim1 = min((i+1)*partition_size[1], dim2) - i*partition_size[1]
            tile_dim2 = min((j+1)*partition_size[2], dim3) - j*partition_size[2]
            w_tile_dim[i][j] = [tile_dim1,tile_dim2]

    no_batch_tile = int( np.ceil (dim1 / partition_size[0]) )
    x_tile_dim = {i:{} for i in range(no_batch_tile)}

    for j in range(no_row_tile):
        for i in range(no_batch_tile):
            tile_dim1 = min((i+1)*partition_size[0], dim1) - i*partition_size[0]
            tile_dim2 = min((j+1)*partition_size[1], dim2) - j*partition_size[1]
            x_tile_dim[i][j] = [tile_dim1, tile_dim2]

    return x_tile_dim, w_tile_dim, no_batch_tile, no_row_tile, no_col_tile

def partition_layer(layer_node, array_size, partition_size):
    if layer_node.layer_type == 'Conv2D' or layer_node.layer_type == 'Dense':
        gemm_info = {}

        input_size = layer_node.layer_attr["input_size"]
        weight_size = layer_node.layer_attr["weight_size"]

        if layer_node.layer_type == 'Conv2D':
            gemm_info["kernel_size"] = layer_node.layer_attr["kernel_size"]

        gemm_info["input_size"] = input_size
        gemm_info["weight_size"] = weight_size

        x_tile_dim, w_tile_dim, no_batch_tile, no_row_tile, no_col_tile = split_mat(input_size, weight_size, array_size, partition_size)
        no_tiles = (no_batch_tile, no_row_tile, no_col_tile)

        gemm_info["x_tile_dim"] = x_tile_dim
        gemm_info["w_tile_dim"] = w_tile_dim
        gemm_info["no_tiles"] = no_tiles

        return gemm_info
    else:
        logging.info("No GEMM operation found at layer {} of type {}.".format(layer_node.layer_name, layer_node.layer_type))
        return None

def all_dependencies_scheduled(layer_name, graph, layer_schedules):
    node = graph.get_node(layer_name)

    for s in node.src:
        if s.layer_name not in layer_schedules:
            return False

    return True

def precompile_model(model, array_size, partition_size=None):
    graph = convert_keras_to_graph(model)

    raw_input = 1

    layers = OrderedDict()
    for layer_name in graph.get_layer_names():
        layer_node = graph.get_node(layer_name)
        gemm_op = partition_layer(layer_node, array_size, partition_size)

        dependencies = [s.layer_name for s in layer_node.src]

        layers[layer_name] = {"gemm_op": gemm_op, "deps": dependencies, "raw_input":raw_input, "layer_type": layer_node.layer_type}

        if gemm_op is not None:
            raw_input = 0 #toggle raw_input after the first layer with gemm ops

    return layers

def main():
    parser = argparse.ArgumentParser()
    parser.add_argument('--model', type=str, required=False, default='bert_medium')
    parser.add_argument('--extra_models', type=str, nargs='+', required=False, default=[])
    parser.add_argument('--batch_size', type=int, required=False, default=1, help='Batch size')
    parser.add_argument('--sentence_len', type=int, required=False, default=100, help='Sentence length for transformer model')
    parser.add_argument('--imsize', type=int, required=False, default=299)
    parser.add_argument('--array_size', type=int, nargs='+', required=False, default=[32,32], help='Array size')
    parser.add_argument('--out_dir', type=str, required=False, default="experiments/tmp")
    parser.add_argument('--partition_size', type=int, required=False, default=None)
    parser.add_argument('--read_only', type=int, required=False, default=1)
    parser.add_argument('--enable_schedule_duplication', type=int, required=False, default=1)

    args = parser.parse_args()

    batch_size = args.batch_size
    sentence_len = args.sentence_len

    array_size = args.array_size

    imsize = args.imsize
    partition_size = args.partition_size
    out_dir = args.out_dir
    extra_models = args.extra_models
    extra_models = [m for m in extra_models if m != "None"]

    if len(extra_models) > 0:
        assert args.enable_schedule_duplication == False, "Schedule duplication is supported only for a single BERT model"

    json_out = {"args":args.__dict__}
    for m in [args.model] + extra_models:
        bm = get_benchmarks(m, batch_size, imsize, sentence_len, args.read_only)
        if bm.model_type == "BERT" and args.enable_schedule_duplication:
            keras_model = bm.get_keras_model(no_layers=1)
            no_repeat = bm.no_layers
        else:
            keras_model = bm.get_keras_model()
            no_repeat = 1

        layers = precompile_model(keras_model, array_size=array_size, partition_size=partition_size)
        json_out[m] = {"order":list(layers.keys()), "layers":layers, "no_repeat":no_repeat, "no_ops":bm.no_ops}

    os.makedirs(out_dir, exist_ok=True)
    with open(out_dir+"/precompiled_model.json", "w") as outfile:
        json.dump(json_out, outfile)

    print("precompiled model is saved at: {}".format(out_dir))

if __name__ == "__main__":
    main()


import requests

def download():
    """Function to download the latest version of the mapping between OMIM and uniprot."""
    url = 'http://www.uniprot.org/docs/mimtosp.txt'
    file_Name = 'data.txt'
    data = requests.get(url)
    file = open(file_Name, 'wb')
    for line in data.iter_content():
        file.write(line)
    file.close()

download()


# Francisco Abimael Oro Estrada
# N.C. 423115639
# Practica 10 - Actividad 4

import math
import random as rd

def closestPair(P):
    minimum_distance = 1000
    for i in range(len(P)):
        for j in range(i+1, len(P)):
            distance = math.sqrt((P[i][0] - P[j][0]) ** 2 + (P[i][1] - P[j][1]) ** 2)
            if distance < minimum_distance:
                minimum_distance = distance
    return minimum_distance

# Using a list of tuples to test the closest pair

random_points = [(rd.randint(0,10), rd. randint(0,10)) for i in range(10)]
print("Generated the following set of ordered pairs : ")
print(random_points)
print(f"The minimum distance is : {closestPair(random_points)}")