import numpy as np
import math
import matplotlib.pyplot as plt

# Load the data:
X = np.load('data/q3x.npy')
y = np.load('data/q3y.npy')

n = X.shape[0]
X = np.append(np.ones((n, 1)), np.reshape(X, (n, 1)), axis = 1)
print(X, X.shape)

########################## i ###########################
# Use normal equation to get the result for the weight:
theta = np.linalg.inv(np.dot(X.T, X)).dot(X.T).dot(y)

print(theta)

plt.figure(figsize=(10,6))
plt.scatter(X[:,1], y, facecolors='none', edgecolors='blue')
plt.plot(X[:,1], X.dot(theta), color='green')
plt.xlabel("X")
plt.ylabel("y")
plt.show()

########################## ii ###########################
bandwidth = 0.8
def LWLR(X, y, bandwidth):
    # Choose each point between the minimum and the maximum as with step 0.1 as the center points
    x_list = np.arange(min(X[:,1]), max(X[:,1]) + 1, 0.1)
    prediction_list = []
    for k in range(len(x_list)):
        R = np.zeros((n, n))
        for i in range(n):
            center = x_list[k]
            R[i,i] = math.exp(-(center - X[i,1])**2/(2*bandwidth**2))
        # Calculate the theta matrix and then get the predictions:
        theta = np.linalg.inv(X.T.dot(R).dot(X)).dot(X.T).dot(R).dot(y)
        prediction_list.append(theta[0] + theta[1]*x_list[k])
    plt.figure(figsize=(10,6))
    plt.scatter(X[:,1], y, facecolors='none', edgecolors='blue')
    plt.plot(x_list, prediction_list, color='green')
    plt.title("This is the plot with bandwidth equaling to {}".format(bandwidth))
    plt.xlabel("X")
    plt.ylabel("y")
    plt.show()
LWLR(X, y, 0.8)

########################## iii ###########################
bandwidth_list = [.1,.3,2,10]
for i in bandwidth_list:
    LWLR(X, y, i)


#! /usr/bin/env python

## Trying something new:
"""
This script contains all the code for plotting figure 1 of Ammon's BayesBattleBots paper
For questions, contact Ammon Perkes (perkes.ammon@gmail.com)
"""

import numpy as np
from matplotlib import pyplot as plt
import copy
from tqdm import tqdm

from fish import Fish
from fight import Fight
from tank import Tank
from simulation import Simulation,SimParams
from matplotlib import cm
from params import Params
from simulation import Simulation

## Define some global variables to determine if you will plot and save figures.
PLOT = True
SAVE = False

sim = Simulation()
params = Params()
params.outcome_params = [0.5,-0.5,-0.8]
#params.set_L()
params.awareness = 0.5
params.acuity = 0.1

params.set_params()
#params.size=50
#params.prior = True

#params.effort_method = [None,'!']
#params.effort_method = 'ExplorePoly'
params.effort_method = 'SmoothPoly'
params.poly_param_c = 0

params.post_acuity = True
params.f_method = 'shuffled'

params.n_fish = 5
params.n_rounds = 30
params.iterations = 500
#params.n_rounds = params.n_fights * (params.n_fish-1)

## Set up a tank
cost_array = np.empty([params.iterations,params.n_fish,params.n_rounds * (params.n_fish-1)])
error_array = np.empty([params.iterations,params.n_fish,params.n_rounds * (params.n_fish - 1) + 1])

for i in tqdm(range(params.iterations)):
    fishes = [Fish(f,params) for f in range(5)]

    tank = Tank(fishes,params)
    tank.run_all(progress=False)

    error_array[i] = sim._calc_error(tank)
    for f in range(len(fishes)):
        cost_array[i,f] = np.array(tank.fishes[f].win_record)[:,3]

fig,(ax,ax1) = plt.subplots(1,2)

mean_int = np.nanmean(cost_array,axis=(0,1))
sem_int = np.nanstd(cost_array,axis=(0,1)) / np.sqrt(params.iterations)
ax.plot(mean_int,color='black')
ax.fill_between(range(len(mean_int)),mean_int-sem_int,mean_int+sem_int,color='gray',alpha=0.5)
ax.set_xlabel('Contest number')
ax.set_ylabel('Mean fight Intensity\n(+/- SEM of iterations')
ax.set_title('Fight intensity decreases over repeated contests')

## Plot error
mean_err = np.mean(error_array,axis=(0,1))
sem_err = np.std(error_array,axis=(0,1)) / np.sqrt(params.iterations)
ax1.plot(mean_err,color='black')
ax1.fill_between(range(len(mean_err)),mean_err-sem_err,mean_err+sem_err,color='gray',alpha=0.5)
ax1.set_xlabel('Contest number')
ax1.set_ylabel('Mean error \n(+/- SEM of iterations')
ax1.set_title('Estimate error decreases over repeated contests')

#fig.savefig('./figures/figure2c_intensity.png',dpi=300)

if PLOT:
    plt.show()


from flask import Flask
from src.config.env import Env

from werkzeug.utils import import_string

api_blueprints = ["hook_bp"]

def create_app():
    app = Flask(__name__)

    # Register blueprints
    for bp_name in api_blueprints:
        print("Registering bp: %s" % bp_name)
        bp = import_string("src.routes.%s:bp" % (bp_name))
        app.register_blueprint(bp)

    return app

if __name__ == "__main__":
    app = create_app()

    app.run(port=Env().PORT)


import numpy as np
#from air_characteristics import air
import CoolProp.CoolProp as cp
from models.gas_jet import Gas_Jet
import pandas as pd
air = Gas_Jet()
import plotly.express as px
#mass volumique kg/m3 et chaleur specifique W/m.K
def air_rho_cp(T, P):
    return cp.PropsSI('D', 'T', T, 'P', P, 'Air'), cp.PropsSI('C', 'T', T, 'P', P, 'Air') #W/m.K

def source_coordinates(xs, ys, zs, ax, bx, cx, air_outlets): #空调出风口位置
    #等比例网格化
    axx = np.linspace(0, xs, ax, retstep=True)[0]
    bxx = np.linspace(0, ys, bx, retstep=True)[0]
    cxx = np.linspace(0, zs, cx, retstep=True)[0]

    #修正下长度
    ax = len(axx)
    bx = len(bxx)
    cx = len(cxx)

    axxx = np.array([[i] * bx * cx for i in axx])
    bxxx = np.array([[[j] * cx for j in bxx] * ax ])
    cxxx = np.array([[k for k in cxx] * ax * bx])

    axxx = axxx.flatten()
    bxxx = bxxx.flatten()
    cxxx = cxxx.flatten()
    #xxx, yyy, zzz = np.where(zeros == 0)
    zzz = np.reshape(cxxx, (ax, bx, cx))
    yyy = np.reshape(bxxx, (ax, bx, cx))
    xxx = np.reshape(axxx, (ax, bx, cx))

    coors = np.concatenate((xxx[:, :, :, None], yyy[:, :, :, None], zzz[:, :, :, None]), axis=-1)
    outlet_projections = []
    for x in range(len(coors)):
        for y in range(len(coors[0])):
            for z in range(len(coors[0][0])):
                xval = coors[x][y][z][0]
                yval = coors[x][y][z][1]
                zval = coors[x][y][z][2]
                #print((y, yval))
                if int(xval) in [int(air_outlets[i][0]) for i in range(len(air_outlets))]:
                #or int(xval) in [int(air_outlets[i][0]) - 1 for i in range(len(air_outlets))] or int(xval) in [int(air_outlets[i][0]) + 1 for i in range(len(air_outlets))]:
                    #print('1')
                    if int(yval) in [int(air_outlets[i][1]) for i in range(len(air_outlets))]:
                    #or int(yval) in [int(air_outlets[i][1]) - 1 for i in range(len(air_outlets))] or int(yval) in [int(air_outlets[i][1]) + 1 for i in range(len(air_outlets))] :
                        #print('2')
                        if int(zval) in [int(air_outlets[i][2]) for i in range(len(air_outlets))]:
                        #or int(zval) in [int(air_outlets[i][2]) - 1 for i in range(len(air_outlets))] or int(zval) in [int(air_outlets[i][2]) + 1 for i in range(len(air_outlets))]:
                            outlet_projections.append((xval, yval, zval))

    return coors, outlet_projections

def structure(coors, projection_outlets, d0, a, Te, T0, v0, cx, zs, alpha): #Setting initial temperatures of the environmental block according to the ac outlet's gas jet characteristics

    bundle = {'x': [], 'y': [], 'z': [], 'T': [], 'P': [], 'Rho': [], 'Cp': [], 'Type': []}

    Temperatures = []
    Receive_or_not = []
    cooling_umbrella = [] #umbrella顶点记录下来，谁在下面谁受冷

    for x in range(len(coors)):
        #print(x)
        Temperatures.append([])
        Receive_or_not.append([])

        for y in range(len(coors[0])):
            Temperatures[x].append([])
            Receive_or_not[x].append([])
            #print((x,y))
            s = y #从这儿看
            R = air.R(a, s, d0/2)
            T_jet = air.T(Te, T0, R, s, v0, d0/2)
            #print(z_deviation)
            for z in range(len(coors[0][0])):
                #print(z)
                xval = coors[x][y][z][0]
                yval = coors[x][y][z][1]
                zval = coors[x][y][z][2]

                bundle['x'].append(xval)
                bundle['y'].append(yval)
                bundle['z'].append(zval)

                if (xval,yval,zval) in projection_outlets: #固定出风口位置
                    #print('出风口位置')
                    T = T0
                    bundle['Type'].append('Active') #Active相当是自发热or发冷，Passive受热or受冷
                    Receive_or_not[x][y].append(False)
                    cooling_umbrella.append((y,z))

                elif zval < projection_outlets[0][2] and xval in [int(projection_outlets[i][0]) for i in range(len(projection_outlets))]: #横向射流影响
                    #print(T_jet)
                    s = abs(yval - y) #相对于出风口的s，如果出风口y=3， yva=4，s= yval - y，
                    z_deviation, traj = air.trajectory(d0, s, alpha, a ,T0, Te, v0)
                    if zval == projection_outlets[0][2] + int(z_deviation): #出风口射流经过位置
                    #z_deviation在这里是负数因为不考虑浮力，
                        T = T_jet
                        bundle['Type'].append('Active')
                        Receive_or_not[x][y].append(False)
                        cooling_umbrella.append((y,z))
                    else:
                        T = Te
                        bundle['Type'].append('Passive')
                        Receive_or_not[x][y].append(True)

                elif (xval, yval) in [(projection_outlets[i][0], projection_outlets[i][1]) for i in range(len(projection_outlets))] and zval < projection_outlets[0][2]: #出风口正下方
                    T = Te - 3 * (zval) / (zs)
                    bundle['Type'].append('Active') #Active相当是自发热or发冷，Passive受热or受冷
                    Receive_or_not[x][y].append(False)
                    cooling_umbrella.append((y,z))

                else:
                    T = Te
                    bundle['Type'].append('Passive')
                    Receive_or_not[x][y].append(True)

                    #cooling_umbrella.append(None) #不是umbrella就是None

                Temperatures[x][y].append(T)
                bundle['T'].append(T) #大家都一样
                bundle['P'].append(10350) #pascal
                rho, Cp = air_rho_cp(T + 273.15, 10350)
                bundle['Rho'].append(rho)
                bundle['Cp'].append(Cp)
    print((len(bundle['T']), len(bundle['P']), len(bundle['Rho']), len(bundle['Cp']), len(bundle['x']),
    len(bundle['y']), len(bundle['z'])))
    df = pd.DataFrame(bundle)
    df['R'] = air.R(a=a, s = df['y'], r0 = d0/2)
    df['Qv'] = air.Qv(Qv0= 300, R = df['R'], r0 = d0/2)
    df['v2'] = air.v2(v0 = v0,Qv=df['Qv'], Qv0=300)
    return df, Temperatures, cooling_umbrella, Receive_or_not

def heat_transfer(df, ax, bx, cx, zs, dt, dx, lamb, d0, T0, passengers, v0, total_time_of_simulation, Temperatures, cooling_umbrella, Receive_or_not):

    cs = Temperatures.copy() #current state
    df['moment 0 T']= df['T'].copy()
    count = 0
    cold_q = 0
    for t in range(int(total_time_of_simulation)):
        print(t)
        ns = cs.copy()
        new_T_list = []
        for x in range(ax):
            count += 1
            for y in range(bx):
                count += 1
                for z in range(cx):
                    count += 1

                    a = lamb / (df['Rho'][x+y+z] * df['Cp'][x+y+z])
                    dy = dx
                    dz = dx

                    #if y == 0 and z == 5:
                    #    new_value = T0

                    #else:
                    if x == ax - 1:
                        A = 0
                    else:
                        A = cs[x + 1][y][z]

                    if x == 0:
                        B = 0
                    else:
                        B = cs[x - 1][y][z]

                    if y == bx - 1:
                        C = 0
                    else:
                        C = cs[x][y + 1][z]

                    if y == 0:
                        D = 0
                    else:
                        D = cs[x][y - 1][z]

                    if z == cx - 1:
                        E = 0
                    else:
                        E = cs[x][y][z + 1]

                    if z == 0:
                        F = 0
                    else:
                        F = cs[x][y][z - 1]

                        #if count < 600:
                        #    if df['v2'][count] > 1.9:
                        #        cold_q = 200
                        #    elif df['v2'][count] < 1.6:
                        #        cold_q = 80
                        #    rho = df['Rho'][count]
                        #    Cp = df['Cp'][count]
                        #else:
                        #    cold_q = 0
                        #    rho = 1
                        #    Cp = 1000
                    for (yu,zu) in cooling_umbrella:
                        if y == yu and z < zu:
                            #print(y,z)
                            cold_q = 100 * (z+1 / zu+1) #垂直等比例扩散
                            pass
                        #else:
                        #   cold_q = 0

                    #if (x, y) in [(projection_outlets[i][0], projection_outlets[i][0]) for i in range(len(air_outlets))]: #在出风口地下的会受到定期冷量
                        #   cold_q = 10 * (z+1) / (zs+1)

                    if (x,y) in passengers and z in [0, 1 * cx / zs, 2 * cx / zs]:
                        hot_q = 100 * ( z+1 / 3)
                    else:
                        hot_q = 0

                    rho = 1
                    Cp = 1000

                    if count < ax*bx*cx and Receive_or_not[x][y][z] == False:
                        #print((x,y,z))
                        #print('Active')
                        s = y #从这儿看
                        R = air.R(a, s, d0/2)
                        Te_t = np.mean([i for i in [A, B, C, D, E, F] if i != 0])
                        T_jet = air.T(Te_t, T0, air.R(a, s, d0/2), s, v0, d0/2)
                    else:
                        ns[x][y][z] = cs[x][y][z] - a * dt *( (A - 2 * cs[x][y][z] + B)/dx**2 +(C - 2 * cs[x][y][z] + D)/dy**2 +
                        (E - 2 * cs[x][y][z] + F)/dz**2 ) - dt * cold_q / (rho * Cp) + dt * hot_q / (rho * Cp)
                    new_value = ns[x][y][z]

                    new_T_list.append(new_value)

        cs = ns.copy()
        #print(new_T_list)
        df['moment ' + str(t) + ' T'] = new_T_list.copy() #以一维形式传回到dataframe方便可视化

    return df


# -*- coding: utf-8 -*-
"""
Created on Mon Feb 17 16:10:16 2020

@author: Marko
"""

import numpy as np
import pandas as pd
#import matplotlib.pyplot as plt
#from collections import Counter
from unidecode import unidecode
import os
def choose_gw():
    df = pd.read_csv("GLK.csv")
    names = df.columns.to_list()
    temp = {}
    for i,n in enumerate(names):
        if n.isdigit():
            temp[int(n)]= names[i+1]
    print('Choose one of the following gameweeks: ')
    for k in temp.keys():
        print(k, ' ', end = '')
    while True:
        try:
            x = int(input('Enter gameweek number: '))
            if x in temp.keys():
                print('Selected gameweek ',x)
                break
            else:
                print('Choose only from available gameweeks')
        except ValueError:
            print('Need integer number')
        except:
            print('unexptected error')
            break
    return temp[x]
def combine_players_id(gw = 'Average'):
    print('[INFO] APPLYING ID LIST TO PREDICTION DATAFRAME - - ')
    glk = pd.read_csv("GLK.csv")
    dfd = pd.read_csv("DEF.csv")
    mid = pd.read_csv("MID.csv")
    fwd = pd.read_csv("FWD.csv")

    ## CHANGE DUPLICATE NAMES
    df_pedro = mid.index[(mid['last_name']=='Pedro') & (mid['Team']=='CHE')]
    mid.at[df_pedro,'first_name']= ' Ledesma'
    df_bruno = mid.index[(mid['last_name']=='Fernandes') & (mid['Team']=='MUN')]
    mid.at[df_bruno,'first_name']= ' Bruno'
    df_gedson = mid.index[(mid['last_name']=='Fernandes') & (mid['Team']=='TOT')]
    mid.at[df_gedson,'first_name']= ' Gedson'
    df_gabriel = fwd.index[(fwd['last_name']=='Jesus') & (fwd['Team']=='MCI')]
    fwd.at[df_gabriel,'first_name']= ' Gabriel'
    df_rosa = mid.index[(mid['last_name']=='Rosa') & (mid['Team']=='WHU')]
    mid.at[df_rosa,'first_name']= ' Bernardo Costa Da'
    df_berbha = dfd.index[(dfd['last_name']=='Bernardo') & (dfd['Team']=='BHA')]
    dfd.at[df_berbha,'first_name']= ' Fernandes da Silva Junior'

    ## SELECT COLUMNS OF INTEREST
    names = glk.columns.to_list()
    index = names[0:3]+[gw]+['Price']
    def convert_dataframe(a):
        a = a[index]
        a['Price'] =a['Price'].str[1:] # remove pound symbol from price
        a['Price']=a['Price'].astype(float) # convert price from string to float
        a = a.replace(np.nan, '',regex = True)   # NaN values in names convert to ''
        for col in names[:2]:
            a[col] = a[col].apply(unidecode)  # remove name accents for manual search
        mask = a['first_name'] == ''
        a['name']='' # make new column
        a['first_name']=a['first_name'].str[1:]
        a['name'][~mask] =a['first_name'] + ' ' + a['last_name']   # has first name
        a['name'][mask] = a['last_name'] # no first name
        cols = a.columns.to_list()
        cols = cols[-1:] + cols[:-1]
        a = a[cols]
        return a
    glk,dfd,mid,fwd = [convert_dataframe(a) for a in (glk,dfd,mid,fwd)]
    glk['Pos'] = 'G'
    dfd['Pos'] = 'D'
    mid['Pos'] = 'M'
    fwd['Pos'] = 'F'
    all_p = [glk,dfd,mid,fwd]
    df = pd.concat(all_p, ignore_index = True)
    df= df.rename(columns = {gw:'Average'})

    ## GET IDLIST
    dfid = pd.read_csv('player_idlist.csv')
    names_id = dfid.columns.to_list()
    dfid = dfid.replace(np.nan, '',regex = True)   # NaN values in names convert to ''
    for col in names_id[:2]:
        dfid[col] = dfid[col].apply(unidecode)  # remove name accents for manual search
    dfid['name']= dfid['first_name']+' '+dfid['second_name']

    ##   make sets of unique values
    set1 = set(df['name'])
    set2 = set(dfid['name'])
    ##   set1 intersection set2 - give ID's from IDLIST
    df['id']=0
    set12 = set1.intersection(set2)
    for row in df.itertuples():
        if row[1] in set12: # row = index, name,...
            string = row[1]
            df.at[row.Index, 'id']= dfid.loc[dfid['name']==string]['id']

    ## IF THEY DONT INTERSECT, BUT NAME IS SUBSTRING OF SET2 (example KEPA in KEPA ARRIZABALAGA)
    list12 = list(set1-set2)
    list21 = list(set2-set1)
    mapp = []
    for i,l12 in enumerate(list12):
        for j,l21 in enumerate(list21):
            if l12 in l21:
                mapp.append((i,j))
                break
    for i in mapp:
        df_name = list12[i[0]]
        dfid_name = list21[i[1]]
       # df.loc[df['name']==df_name, ['id']] = dfid.loc[df['name']==dfid_name]['id']
        df_index = df.index[df['name']==df_name]
        dfid_index = dfid.index[dfid['name']==dfid_name].values
        idd = dfid.loc[dfid_index]['id']
        idd = idd.to_numpy()
        df.at[df_index,'id'] = idd
       # print(idd,'**',list12[i[0]],'---', list21[i[1]])

    ## OTHER NAMES HAVE TO BE GIVEN MANUALLY
    templist = []
    for i in mapp:
        templist.append(list21[i[1]])
    set_did = set(templist)
    set_to_do = (set2-set1)-set_did
    list_dfid_to_do = list(set_to_do)
    list_df_to_do = ['Cuco Martina','Lucas Moura','Xande Silva','Andre Gomes','Chicharito','Gedson Fernandes','Bruno Fernandes',\
    'Angelino','Joselu','Trezeguet','Fernandinho','Baston','Kiko Femenia','Gabriel Jesus','Jorginho','Ki Sung-yueng',\
    'Bernardo Silva', 'Jota','Fernandes da Silva Junior Bernardo','Ledesma Pedro','Jonny','Fabinho']
    # PRINT THEM  TO VISUALLY CONFIRM

    #for x,y in zip(list_df_to_do, list_dfid_to_do):
    #    print("{:<40}{:<50}".format(x,y))

    for i in range(len(list_df_to_do)):
        df_name = list_df_to_do[i]
        dfid_name = list_dfid_to_do[i]
       # df.loc[df['name']==df_name, ['id']] = dfid.loc[df['name']==dfid_name]['id']
        df_index = df.index[df['name']==df_name]
        dfid_index = dfid.index[dfid['name']==dfid_name].values
        idd = dfid.loc[dfid_index]['id']
        idd = idd.to_numpy()
        df.at[df_index,'id'] = idd

     ## SAVE DF to CSV
    df.to_csv('players_with_id.csv')
    print('[INFO] ID LIST TO PREDICTION DATAFRAME APPLIED- SAVED AS players_with_id.csv ')


""" Script for blob detection originaly inspired by http://www.learnopencv.com/blob-detection-using-opencv-python-c/ at 13th of Juny 2015
    Now it returns clusterBuster relics and hsitogramms
"""

# Standard imports
import numpy as np
import cv2
#import pyfits as fits
#import scipy.ndimage.morphology    as morp #morp.binary_dilation(input, structure=None, iterations=1, mask=None, output=None, border_value=0, origin=0, brute_force=False)
from scipy import ndimage                # used to compute the centroid
import clusterbuster.surveyclasses as cbclass
import clusterbuster.maput as maput

def RelicExtraction(image, z, contourMask = [], Imcenter=False, GCl=False, dinfo=False, rinfo= False, faintexcl=False,
                    subtracted=False, term=False, cnt_minlength=5, gather_histo_information=True):

    """ Extracts Relics from a numpy array
    gather_histo_information: 0 of not derived, 1 if derived

    See http://photutils.readthedocs.io/en/stable/api/photutils.detect_sources.html
    for possible alternative of implementation
    """

    if not GCl:
        GCl = cbclass.Galaxycluster('NoName', 0, 0, z)
    if not dinfo: #If no detection info specified, create a default one
        dinfo = cbclass.DetInfo()
    if not rinfo: #If no relic region is specified, create a default one
        rinfo = cbclass.RelicRegion(name='', cnt=contourMask, rtype=-1, alpha=1.2)
    if not Imcenter:
        Imcenter = [[0,0], [image.shape[0]/2, image.shape[1]/2]]  # [ [Astronomical Coords], [Pixelcoords] ]

    if term:
        print('###==== Sub-Step X.1: Executing RelicExtraction(2d-numpy array) ====###')

    relics = []

    ## Way of extracting relics: Relic detection by simple thresholding
    (contours, hierarchy) = maput.GetThreshContours(image, dinfo.limit, rinfo.cnt)

    for jj, cnt in enumerate(contours):
        if term:
            print('%6i out of %6i: len(cnt)=%6i' % (jj+1, len(contours), len(cnt)))

        M = cv2.moments(cnt)
        if cnt.shape[0] < cnt_minlength or M['m00'] == 0 : # cnt >= 3 needed for moment analysis & cnt >= 5 for ellipse fitting
            #print 'Contour of', len(cnt), 'ergo less than', cnt_minlength, 'points identified. It will not be considered further.'
            continue

        #cx = int(M['m10']/M['m00'])
        #cy = int(M['m01']/M['m00'])

        # Minimal enclosing circle
        (x, y), radius = cv2.minEnclosingCircle(cnt)

        # mask image, so that every value outside of the contour is set to zero
        region = maput.ContourMasking(image, [cnt])

        flux             = 1e3*np.sum(region)/dinfo.Abeam[0]  # in mJy
        GCl.flux_vol     = 1e3*np.sum(image )/dinfo.Abeam[0]  # in mJy
        if faintexcl and flux < faintexcl:
            continue

        try:
            subregion = maput.ContourMasking(subtracted, [cnt])
            flux_ps = 1e3*np.sum(subregion)/dinfo.Abeam[0]
        except:
            flux_ps = 0

        centroid = ndimage.measurements.center_of_mass(region)
        cov, theta_iner = maput.inertial_axis(region)[2:4]  # compute moment of inertia and gaussian fit

        Dec = Imcenter[0][1] + (centroid[0]-Imcenter[1][1])*dinfo.spixel/3600
        RA  = Imcenter[0][0] - (centroid[1]-Imcenter[1][0])*dinfo.spixel/3600/np.cos(Dec*np.pi/180)  #Please mind the additional factor due to the projection!

        theta_elong = (np.degrees(theta_iner)+180) % 180
        LAS = 2*radius*(dinfo.spixel/60)
        area = (dinfo.spixel/60)**2*cv2.contourArea(cnt)

        region[np.isnan(region)] = 0
        rel = np.where(region > 0)

        if gather_histo_information:
            """ Creates the necessary masks and array for the FLUX histogram """
            """ The same is done with Distance, Angle and Mach number """
            RA_arr  = Imcenter[0][0] - (rel[1] - Imcenter[1][0])*dinfo.spixel/3600/np.cos(Dec*np.pi/180)
            Dec_arr = Imcenter[0][1] + (rel[0] - Imcenter[1][1])*dinfo.spixel/3600
            distance = np.sqrt(np.add(np.power(np.abs(GCl.RA.value-RA_arr) * np.cos(Dec_arr*np.pi/180), 2),
                                       np.power(np.abs(Dec_arr-GCl.Dec.value), 2))) * GCl.cosmoPS * 3600      #2D-array in kpc, np.linalg.norm( [GCl.RA-RA, Dec-GCl.Dec] ) * GCl.cosmoPS *3600
            angle = np.mod(np.arctan2(-(GCl.RA.value-RA_arr)*np.cos(Dec_arr*np.pi/180), Dec_arr-GCl.Dec.value)
                           + 0.5*np.pi, 2.*np.pi)   #2D-array in kpc, np.linalg.norm( [GCl.RA-RA, Dec-GCl.Dec] ) * GCl.cosmoPS *3600
            weights = region[rel]
            Dproj_pix = np.average(distance, weights=weights)  # in kpc
        else:
            distance = None
            angle = None
            weights = None
            Dproj_pix = 0

        relic = cbclass.Relic(rinfo, dinfo, RA, Dec, LAS, area, GCl=GCl, alpha=rinfo.alpha, alphaFLAG=rinfo.alphaFLAG,
                              theta_elong=theta_elong, cov=cov, cnt=cnt, F=flux, F_ps=flux_ps, Dproj_pix=Dproj_pix,
                              sparseD=distance, sparseW=weights, sparseA=angle, pmask=rel)
        relics.append(relic)

    return relics


#-*-coding:utf8-*-
from appium import webdriver
import time

class WechatTest():
    def __init__(self):
        desired_caps = {}
        desired_caps['platformName'] = 'Android'
        desired_caps['platformVersion'] ='4.4.2'
        desired_caps['deviceName']='Android Emulator'
        desired_caps['appPackage']='com.taobao.taobao'
        desired_caps['appActivity']='com.taobao.android.trade.cart.CartActivity'
        self.driver = webdriver.Remote('http://localhost:4723/wd/hub', desired_caps)

    def quit(self):
        time.sleep(5)
        self.driver.quit()

    def test_login(self):
        time.sleep(35)
        self.driver.find_element_by_name(u'购物车').click()
        time.sleep(35)
        self.driver.find_element_by_name(u'LOVEHEYNEW').click()
        time.sleep(15)
        self.driver.find_element_by_name(u'微淘动态').click()
        time.sleep(10)
        x = self.driver.get_window_size()['width']
        y = self.driver.get_window_size()['height']
        self.driver.swipe(x / 2, y * 3 / 4, x / 2, y / 4, 150)
        time.sleep(10)
        self.driver.swipe(x / 2, y * 3 / 4, x / 2, y / 4, 150)
        time.sleep(5)

        self.driver.find_elements_by_class_name('android.view.View')[12].click()
        time.sleep(5)
        self.driver.find_element_by_name('回复楼主').send_keys("1")
        self.driver.find_elements_by_class_name('android.view.View')[3].click()
        time.sleep(5)

if __name__ == '__main__':

     wechat = WechatTest()
     wechat.test_login()


import logging
from typing import Callable

import pcapi.connectors.notion as notion_connector
from pcapi.core.providers.models import VenueProvider
import pcapi.core.providers.repository as providers_repository
import pcapi.local_providers
from pcapi.local_providers.provider_api import synchronize_provider_api
from pcapi.repository import transaction
from pcapi.scheduled_tasks.logger import CronStatus
from pcapi.scheduled_tasks.logger import build_cron_log_message

logger = logging.getLogger(__name__)

def synchronize_data_for_provider(provider_name: str, limit: int | None = None) -> None:
    provider_class = get_local_provider_class_by_name(provider_name)
    try:
        provider = provider_class()
        provider.updateObjects(limit)
    except Exception:  # pylint: disable=broad-except
        logger.exception(build_cron_log_message(name=provider_name, status=CronStatus.FAILED))

def synchronize_venue_providers_for_provider(provider_id: int, limit: int | None = None) -> None:
    venue_providers = providers_repository.get_active_venue_providers_by_provider(provider_id)
    for venue_provider in venue_providers:
        try:
            with transaction():
                synchronize_venue_provider(venue_provider, limit)
        except Exception as exc:  # pylint: disable=broad-except
            notion_connector.add_to_synchronization_error_database(
                exception=exc,
                provider_name=venue_provider.provider.name,
                venue_id=venue_provider.venueId,  # type: ignore [arg-type]
                venue_id_at_offer_provider=venue_provider.venueIdAtOfferProvider,  # type: ignore [arg-type]
            )
            logger.exception(
                "Could not synchronize venue provider",
                extra={
                    "venue_provider": venue_provider.id,
                    "venue": venue_provider.venueId,
                    "provider": venue_provider.providerId,
                    "exc": exc,
                },
            )

def get_local_provider_class_by_name(class_name: str) -> Callable:
    return getattr(pcapi.local_providers, class_name)

def synchronize_venue_provider(venue_provider: VenueProvider, limit: int | None = None) -> None:
    if venue_provider.provider.implements_provider_api and not venue_provider.provider.isCinemaProvider:
        synchronize_provider_api.synchronize_venue_provider(venue_provider)

    else:
        assert venue_provider.provider.localClass in [
            "AllocineStocks",
            "CDSStocks",
        ], "Only AllocineStocks or CDSStocks should reach this code"
        provider_class = get_local_provider_class_by_name(venue_provider.provider.localClass)

        logger.info(
            "Starting synchronization of venue_provider=%s with provider=%s",
            venue_provider.id,
            venue_provider.provider.localClass,
        )
        provider = provider_class(venue_provider)
        provider.updateObjects(limit)
        logger.info(
            "Ended synchronization of venue_provider=%s with provider=%s",
            venue_provider.id,
            venue_provider.provider.localClass,
        )


"""
Given an array of intervals where intervals[i] = [start, end],
merge all overlapping intervals, and return an array of the non-overlapping intervals
that cover all the intervals in the input.
"""

from collections import deque

def merge(intervals: list[list[int]]) -> list[list[int]]:
    intervals = sorted(intervals)
    merged = deque()
    for start, end in intervals:
        flag = False
        for i, (s, e) in enumerate(merged):
            if (s <= start <= e) or (s <= end <= e):
                merged[i] = [min(start, s), max(end, e)]
                flag = True
                break
        if not flag:
            merged.append([start, end])
    return merged

if __name__ == '__main__':
    test1 = [[1, 3], [2, 6], [8, 10], [15, 18], [2, 4]]
    test2 = [[1, 4], [4, 5]]
    test3 = [[1, 4], [0, 5]]
    print(merge(test1))


"""chat_settings

Revision ID: 20190314182214
Revises: 20190314175025
Create Date: 2019-03-14 18:22:14.635279

"""

import sqlalchemy as sa
from alembic import op
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm.session import Session

# revision identifiers, used by Alembic.
revision = "20190314182214"
down_revision = "20190314175025"
branch_labels = None
depends_on = None

Base = declarative_base()

class Chat(Base):
    __tablename__ = "chats"

    id = sa.Column(sa.BigInteger, primary_key=True, autoincrement=False)
    default_currency = sa.Column(sa.Text, default="USD", nullable=False)
    default_currency_position = sa.Column(sa.Boolean, default=True, nullable=False)
    created_at = sa.Column(sa.TIMESTAMP, server_default=sa.func.now(), nullable=False)
    modified_at = sa.Column(
        sa.TIMESTAMP,
        server_default=sa.func.now(),
        onupdate=sa.func.now(),
        nullable=False,
    )

def upgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.add_column("chats", sa.Column("default_currency", sa.Text(), nullable=True))
    op.add_column(
        "chats", sa.Column("default_currency_position", sa.Boolean(), nullable=True)
    )
    # ### end Alembic commands ###

    session = Session(bind=op.get_bind())
    session.query(Chat).update(
        {
            "default_currency": "USD",
            "default_currency_position": True,
            "modified_at": Chat.modified_at,
        }
    )

    op.alter_column("chats", "default_currency", nullable=False)
    op.alter_column("chats", "default_currency_position", nullable=False)

def downgrade():
    pass


import logging
from typing import Any, Tuple

from linotp.lib.policy.evaluate import PolicyEvaluator
from linotp.lib.policy.util import get_policies
from linotp.lib.user import User

LOG = logging.getLogger(__name__)

def search_policy(param, only_active=True):
    """
    Function to retrieve the list of policies.

    attributes:

    - name:   (optional) will only return the policy with the name
    - user:   (optional) will only return the policies for this user
    - realm:  (optional) will only return the policies of this realm
    - scope:  (optional) will only return the policies within this scope
    - action: (optional) will only return the policies with this action
         The action can also be something like "otppin" and will
         return policies containing "otppin = 2"

    :return: a dictionary with the policies. The name of the policy being
             the key
    """

    #
    # filter the policies with the new engine

    policy_elve = PolicyEvaluator(get_policies())

    #
    # install the filters

    policy_elve.set_filters(params=param)

    #
    # add the special filter for activ or inactive policies

    if only_active:
        policy_elve.filter_for_active(state=True)

    #
    # finally we apply the filter

    new_pols = policy_elve.evaluate()

    return new_pols

def getPolicy(param, only_active=True):
    """
    Function to retrieve the list of policies.

    attributes:

    - name:   (optional) will only return the policy with the name
    - user:   (optional) will only return the policies for this user
    - realm:  (optional) will only return the policies of this realm
    - scope:  (optional) will only return the policies within this scope
    - action: (optional) will only return the policies with this action
         The action can also be something like "otppin" and will
         return policies containing "otppin = 2"

    :return: a dictionary with the policies. The name of the policy being
             the key
    """

    #
    # filter the policies with the new engine

    policy_elve = PolicyEvaluator(get_policies())

    #
    # install the filters

    policy_elve.set_filters(params=param)

    #
    # add the special filter for activ or inactive policies

    if only_active:
        policy_elve.filter_for_active(state=True)

    if ("user" in param and param["user"] is not None) or (
        "action" in param and param["action"] is not None
    ):
        policy_elve.filter_for_time()

    #
    # finally we apply the filter

    new_pols = policy_elve.evaluate()

    return new_pols

def is_authorized(admin_user: User, scope: str, action: str) -> bool:
    """
    This internally used function checks whether the currently authenticated
    administrative user is authorized to perform an action in the given scope.

    This method can only be used for administrative users and therefore does
    not take REALMS into account!

    :param admin_user: the admin user to check
    :param scope: policy scope to use (system, audit, monitoring, reporting, tools)
    :param action: action to check in the scope (e.g. read or write)

    returns:
        authenticated : `boolean`
            boolean value whether user is authorized
    """

    policy_eval = PolicyEvaluator(get_policies())

    LOG.debug("Evaluating policies for the user: %r", admin_user)

    scope_policies = policy_eval.has_policy(
        {
            "scope": scope,
            "active": True,
        }
    )

    # if no policy was defined at all -> the access is not restricted
    if len(scope_policies) == 0:
        LOG.info(
            "No active policies in scope %s found - access to this scope is"
            " not restricted!",
            scope,
        )
        return True

    # if any policy is defined, check if the admin_user is allowed to execute
    # the given action by an active policy

    filters = {
        "user": admin_user,
        "scope": scope,
        "action": action,
    }
    policies = policy_eval.set_filters(filters).evaluate(scope_policies)

    LOG.debug("Found the following policies: %r", policies)

    return len(policies) > 0

def get_client_policy(
    client,
    scope=None,
    action=None,
    realm=None,
    user=None,
    find_resolver=True,
    userObj=None,
    active_only=True,
):
    """
    This function returns the dictionary of policies for the given client.

    1. First it searches for all policies matching (scope, action, realm) and
    checks, whether the given client is contained in the policy field client.
    If no policy for the given client is found it takes the policy without
    a client

    2. Then it strips down the returnable policies to those, that only contain
    the username - UNLESS - none of the above policies contains a username

    3. then we try to find resolvers in the username (OPTIONAL)

    4. if nothing matched so far, we try the extended policy check

    """

    policy_eval = PolicyEvaluator(get_policies())

    if realm:
        policy_eval.filter_for_realm(realm)

    if scope:
        policy_eval.filter_for_scope(scope)

    if action:
        policy_eval.filter_for_action(action)

    if client:
        policy_eval.filter_for_client(client)

    policy_eval.filter_for_time()

    if active_only:
        policy_eval.filter_for_active(state=True)

    if userObj:
        policy_eval.filter_for_user(userObj)
    elif user:
        policy_eval.filter_for_user(user)

    policies = policy_eval.evaluate()

    return policies

def has_client_policy(
    client,
    scope=None,
    action=None,
    realm=None,
    user=None,
    find_resolver=True,
    userObj=None,
    active_only=True,
):
    """
    This function returns the dictionary of policies for the given client.

    1. First it searches for all policies matching (scope, action, realm) and
    checks, whether the given client is contained in the policy field client.
    If no policy for the given client is found it takes the policy without
    a client

    2. Then it strips down the returnable policies to those, that only contain
    the username - UNLESS - none of the above policies contains a username

    3. then we try to find resolvers in the username (OPTIONAL)

    4. if nothing matched so far, we try the extended policy check

    The difference to the get_policy is, that it restores the already installed
    filters for an existance check

    """

    policy_eval = PolicyEvaluator(get_policies())

    param = {}

    if realm:
        param["realm"] = realm

    if scope:
        param["scope"] = scope

    if action:
        param["action"] = action

    if active_only:
        policy_eval.filter_for_active(state=True)

    if client:
        param["client"] = client

    if userObj:
        param["user"] = userObj
    elif user:
        param["user"] = user

    policies = policy_eval.has_policy(param)

    return policies

# eof


#! /usr/bin/env python
"""This module simply adds miscellaneous code that the main modules can use."""
from __future__ import absolute_import
import logging

import requests

from mozci.utils.authentication import get_credentials

LOG = logging.getLogger('mozci')

def _public_url(url):
    """
    If we run the script outside the Release Engineering infrastructure
    we need to use the public interface rather than the internal one.
    """
    replace_urls = [
        ("http://pvtbuilds.pvt.build",
         "https://pvtbuilds"),
        ("http://tooltool.pvt.build.mozilla.org/build",
         "https://secure.pub.build.mozilla.org/tooltool/pvt/build")
    ]
    for from_, to_ in replace_urls:
        if url.startswith(from_):
            new_url = url.replace(from_, to_)
            LOG.debug("Replacing url %s ->\n %s" % (url, new_url))
            return new_url
    return url

def _all_urls_reachable(urls, auth=None):
    """Determine if the URLs are reachable."""
    for url in urls:
        url_tested = _public_url(url)
        LOG.debug("We are going to test if we can reach %s" % url_tested)
        req = requests.head(url_tested, auth=get_credentials())
        if not req.ok:
            LOG.warning("We can't reach %s for this reason %s" %
                        (url, req.reason))
            return False

    return True


import atexit
import io
import sys

def getParent(x):
    return (x - 1) // 2

def leftChild(x):
    return (2 * x + 1) if (2 * x + 1) < curr_size else -1

def rightChild(x):
    return (2 * x + 2) if (2 * x + 2) < curr_size else -1

def heapify():
    curr_ind = curr_size - 1
    while getParent(curr_ind) != -1 and heap[getParent(curr_ind)] > heap[curr_ind]:
        heap[curr_ind], heap[getParent(curr_ind)] = heap[getParent(curr_ind)], heap[curr_ind]
        curr_ind = getParent(curr_ind)
    return

def heapifyDown(x):
    if x >= curr_size:
        return
    if getParent(x) != -1 and heap[x] < heap[getParent(x)]:
        heap[x], heap[getParent(x)] = heap[getParent(x)], heap[x]
        heapifyDown(getParent(x))
    if leftChild(x)==-1 or (leftChild(x)!=-1 and heap[x]<heap[leftChild(x)]):
        if rightChild(x)==-1 or (rightChild(x)!=-1 and heap[x]<heap[rightChild(x)]):
            return
    if rightChild(x)==-1:
        heap[x], heap[leftChild(x)] = heap[leftChild(x)], heap[x]
        heapifyDown(leftChild(x))
    elif leftChild(x) == -1:
        heap[x], heap[rightChild(x)] = heap[rightChild(x)], heap[x]
        heapifyDown(rightChild(x))
    else:
        if heap[rightChild(x)]<heap[leftChild(x)]:
            heap[x], heap[rightChild(x)] = heap[rightChild(x)], heap[x]
            heapifyDown(rightChild(x))
        else:
            heap[x], heap[leftChild(x)] = heap[leftChild(x)], heap[x]
            heapifyDown(leftChild(x))
    return

def insertKey (x):
    global curr_size
    heap[curr_size] = x
    curr_size += 1
    heapify()

def deleteKey (x):
    global curr_size
    if x >= curr_size:
        return
    heap[x] = heap[curr_size - 1]
    heap[curr_size - 1] = 0
    curr_size -= 1
    heapifyDown(x)

def extractMin ():
    if curr_size == 0:
        return -1
    val = heap[0]
    deleteKey(0)
    return val

_INPUT_LINES = sys.stdin.read().splitlines()
input = iter(_INPUT_LINES).__next__
_OUTPUT_BUFFER = io.StringIO()
sys.stdout = _OUTPUT_BUFFER

@atexit.register

def write():
    sys.__stdout__.write(_OUTPUT_BUFFER.getvalue())

heap = []  # our heap to be used
curr_size = 0  # current size of heap

if __name__ == '__main__':
    test_cases = int(input('Enter the numbr of test cases:- '))
    for cases in range(test_cases):
        n = int(input('Enter the size of the heap:- '))
        a = list(map(int, input('Enter the elements of the heap:- ').strip().split()))
        curr_size = 0
        heap = [0 for i in range(n)]
        i = 0
        while i < len(a):
            if a[i] == 1:
                insertKey(a[i + 1])
                i += 1
            elif a[i] == 2:
                deleteKey(a[i + 1])
                i += 1
            else:
                print(extractMin (), end=" ")
            i += 1
        print()


import RPi.GPIO as GPIO
import time
from mfrc522 import SimpleMFRC522
from datetime import datetime, time as dt_time

# Set the GPIO mode
GPIO.setmode(GPIO.BOARD)

# Define the motor driver pins for the stepper motor
motor_pins = [13, 11, 15, 12]

# Set the motor pins as output
for pin in motor_pins:
    GPIO.setup(pin, GPIO.OUT)

# Define the servo motor pin
servo_pin = 16

# Create an instance of the RFID reader
reader = SimpleMFRC522()

# Define the stepper motor sequence
seq = [
    [1, 0, 0, 1],  # Step 1
    [1, 0, 0, 0],  # Step 2
    [1, 1, 0, 0],  # Step 3
    [0, 1, 0, 0],  # Step 4
    [0, 1, 1, 0],  # Step 5
    [0, 0, 1, 0],  # Step 6
    [0, 0, 1, 1],  # Step 7
    [0, 0, 0, 1]   # Step 8
]

try:
    while True:
        current_time = datetime.now().time()

        # Check if the current time is within the desired time range
        start_time = dt_time(14, 38)  # Start time: 2:38 PM
        end_time = dt_time(14, 45)    # End time: 2:45 PM

        if start_time <= current_time <= end_time:
            # Wait for an RFID tag to be detected
            print("Hold a tag near the reader")
            id, text = reader.read()

            # If a tag is detected, activate the stepper motor and servo motor
            if id is not None:
                print("Tag detected")

                # Function to move the stepper motor for 60 degrees clockwise
                def move_stepper_motor_clockwise(delay):
                    steps = 0
                    while steps < 100:  # Adjust steps for 60 degrees rotation
                        for halfstep in range(8):
                            for pin in range(4):
                                GPIO.output(motor_pins[pin], seq[halfstep][pin])
                            time.sleep(delay)
                            steps += 1

                # Function to move the stepper motor for 60 degrees counterclockwise
                def move_stepper_motor_counterclockwise(delay):
                    steps = 0
                    while steps < 100:  # Adjust steps for 60 degrees rotation
                        for halfstep in range(7, -1, -1):
                            for pin in range(4):
                                GPIO.output(motor_pins[pin], seq[halfstep][pin])
                            time.sleep(delay)
                            steps += 1

                # Code for controlling the servo motor
                GPIO.setup(servo_pin, GPIO.OUT)
                pwm = GPIO.PWM(servo_pin, 50)  # 50 Hz frequency
                pwm.start(0)

                # Rotate the stepper motor 60 degrees clockwise
                move_stepper_motor_clockwise(0.01)

                # Rotate the servo motor 120 degrees clockwise
                duty_cycle = 2 + (120 / 18)  # Calculate duty cycle for 120 degrees
                GPIO.output(servo_pin, True)
                pwm.ChangeDutyCycle(duty_cycle)
                time.sleep(1)
                GPIO.output(servo_pin, False)
                pwm.ChangeDutyCycle(0)

                # Rotate the servo motor 120 degrees counterclockwise
                duty_cycle = 2 + (0 / 18)  # Calculate duty cycle for 0 degrees
                GPIO.output(servo_pin, True)
                pwm.ChangeDutyCycle(duty_cycle)
                time.sleep(1)
                GPIO.output(servo_pin, False)
                pwm.ChangeDutyCycle(0)

                # Rotate the stepper motor 60 degrees counterclockwise
                move_stepper_motor_counterclockwise(0.01)

                pwm.stop()

        # Delay between checking the time
        time.sleep(60)  # Check every minute

except KeyboardInterrupt:
    # Stop the motors and cleanup GPIO pins on keyboard interrupt
    GPIO.output(motor_pins, 0)
    GPIO.cleanup()


import calendar
from datetime import date

from django.contrib import admin
from django.db.models import Sum, Count
from django.utils.html import format_html
from django.utils.html import mark_safe

from .forms import StudentFeeAdd
from .models import Student, StudentFee, FeeGroup, FeeType#, FeeSummary

# Register your models here.
admin.site.register(FeeGroup)
admin.site.register(FeeType)

admin.site.site_header = "My School Admin"
admin.site.site_title = "My School Admin Portal"
admin.site.index_title = "Welcome to My School Portal"

@admin.register(Student)
class StudentAdmin(admin.ModelAdmin):
    """ Display Class of Student Model in Admin Panel"""

    # remove delete actions
    def get_actions(self, request):
        actions = super().get_actions(request)
        if 'delete_selected' in actions:
            del actions['delete_selected']
        return actions

    # Custom Actions
    def expel_from_school(self, request, queryset):
        rows_updated = queryset.update(is_studying=False)
        if rows_updated == 1:
            message_bit = "1 student was"
        else:
            message_bit = "%s students were" % rows_updated
        self.message_user(request, "%s successfully marked as expelled" % message_bit)

    expel_from_school.short_description = 'Expel From School'
    expel_from_school.allowed_permissions = ('change',)

    def last_fee_submitted(self):
        paid_color = 'green'
        unpaid_color = 'red'

        if self.is_studying:
            obj = self.studentfee_set.last()
            if obj is not None:  # if a record exists
                if obj.valid_until >= date.today():  # if paid this month
                    return format_html(
                        '{}',
                        paid_color,
                        calendar.month_name[int(obj.valid_until.month)] + ', ' + str(obj.valid_until.year)
                    )
                else:  # if not paid this month
                    return format_html(
                        '{}',
                        unpaid_color,
                        calendar.month_name[int(obj.date.month)] + ', ' + str(obj.date.year)
                    )
            else:  # if record does not exists
                return format_html(
                    '{}',
                    unpaid_color,
                    "No Fee Paid"
                )
        else:
            return "Left School"

    last_fee_submitted.short_description = 'Last Fee Submitted'

    def profile_image_display(self, obj):
        return mark_safe(
            ''.format(
                url=obj.profile_image.url,
                width=200,
                height=200,
                style='',
            )
        )

    profile_image_display.short_description = "Student Image"

    empty_value_display = '--Empty--'

    list_display = (
        'full_name',
        'father_name',
        'is_studying',
        'gender',
        last_fee_submitted,
    )

    list_filter = (
        'is_studying',
        'current_class',
        'gender'
    )

    search_fields = (
        'first_name', 'last_name', 'admission_no'
    )

    ordering = ('first_name',)

    fieldsets = (
        ("School Record", {
            'fields': (
                'admission_no',
                'date_of_admission',
                'is_studying',
                'current_class',
                'profile_image',
                'profile_image_display',  # callable function,
            )
        }),
        ("Personal Information", {
            'fields': ('first_name', 'last_name', 'date_of_birth', 'gender', 'address')
        }),
        ("Guardian Information", {
            'fields': ('father_name', 'father_cnic', 'fathers_phone_no', 'fathers_proffesion')
        })
    )

    actions = ['expel_from_school', ]

    def get_readonly_fields(self, request, obj=None):
        """ Make admission_no and date_of_admission uneditable if
        opened the admin change form but editable if opened
        the create form
        """

        if obj:  # if the object exists then make them readonly
            return ['admission_no', 'date_of_admission', 'profile_image_display']
        else:
            return ['profile_image_display', ]

@admin.register(StudentFee)
class StudentFeeAdmin(admin.ModelAdmin):
    """ Admin display class for the model StudentFee """

    # Delete Delete Action from admin
    def get_actions(self, request):
        actions = super().get_actions(request)
        if 'delete_selected' in actions:
            del actions['delete_selected']
        return actions

    form = StudentFeeAdd

    raw_id_fields = (
        'student',
        'fee_group',
        )
    # Filtering
    list_filter = (
        'valid_until',
    )

    # searching
    search_fields = [
        'student__admission_no',
        'student__first_name',
        'student__last_name',
    ]

    list_display = (
        'student',
        'valid_until',
        'total_amount',
        'date_submitted',
    )

# @admin.register(FeeSummary)
# class FeeSummary(admin.ModelAdmin):
#     change_list_template = 'students/admin/fee_summary_change_list.html'
#     date_hierarchy = 'date'

#     def changelist_view(self, request, extra_context=None):
#         response = super().changelist_view(
#             request,
#             extra_context=extra_context,
#         )

#         try:
#             qs = response.context_data['cl'].queryset
#         except (AttributeError, KeyError):
#             return response

#         metrics = {
#             'total': Count('id'),
#             'total_sales': Sum('amount'),
#         }

#         response.context_data['summary'] = list(
#             qs
#                 .values('date')
#                 .annotate(**metrics)
#                 .order_by('date')
#         )

#         response.context_data['summary_total'] = dict(
#             qs.aggregate(**metrics)
#         )

#         return response


def data(read_data,file):

    if read_data is True:

        #Reading system information
        from scripts.readData import data_file
        print('Reading data...')
        data_file('datasystem/'+str(file)+'.xlsx')
        # delete temporal files

def data_consistency(stages, seriesBack, seriesForw):

    import pickle
    from utils.paramvalidation import paramlimits

    # Load the dictionary back from the pickle file
    dict_data = pickle.load(open("savedata/data_save.p", "rb"))
    # No of maximum number of stages
    noStages = len(dict_data['horizon'])

    # validating input parameters
    paramlimits(stages, seriesBack, seriesForw, noStages)

def parameters(param_calculation,sensDem,stages,eps_area,eps_all):

    import pickle

    # Load the dictionary back from the pickle file
    dict_data = pickle.load(open("savedata/data_save.p", "rb"))

    # calculation options SI or NO
    if param_calculation is True:
        print('Parameters calculation ...')

        # Creating fixed input files '''
        from utils.input_data import inputdata
        inputdata(dict_data, sensDem)
        from utils.input_hydro import inputhydro
        inputhydro(dict_data)

        from utils.input_wind import inputwindSet, inputInflowWind
        inputwindSet(dict_data, stages, 1, 0)
        inputInflowWind(dict_data, stages, eps_area, eps_all)

        from utils.input_others import inputbatteries, inputlines
        inputbatteries(dict_data, stages)
        inputlines(dict_data, stages)

def grid(param_opf, stages):

    # opf restrictions
    if param_opf is True:
        print('Parameters opf ...')

        from utils.opf_data import ybus
        ybus(stages)

def wmodel2(wind_model2, stages, seriesBack):

    import pickle

    # Load the dictionary back from the pickle file
    dict_data = pickle.load(open("savedata/data_save.p", "rb"))

    # Including wind power plants with model 2
    if wind_model2 is True:
        print('Model of wind power plants with losses ...')

        from utils.readWind import historical10m, format10m
        historical10m()
        format10m()

        from utils.input_wind import inputwindSet #, inputInflowWind, energyRealWind
        inputwindSet(dict_data, stages, 0, 1)
        # factores = energyRealWind(dict_data, seriesBack, stages)

def optimization(stages, seriesBack, eps_risk, commit, parallel, param_opf, max_iter, results,
                 policy, simulation, seriesForw, extra_stages, curves, gates, params):

    import pickle
    from scripts import forward
    from scripts import backward
    from scripts import optimality
    from utils import classes
    import sys, json
    import redis
    r = redis.StrictRedis(host='localhost', port=6379, db=0)

    # Load the dictionary back from the pickle file
    dict_data = pickle.load(open("savedata/data_save.p", "rb"))

    # dictionaries
    batteries = dict_data['batteries']
    hydroPlants = dict_data['hydroPlants']
    dict_batt = pickle.load(open("savedata/batt_save.p", "rb"))

    # Iteration inf _ improve the states under evaluation
    sol_vol = [[] for x in range(stages+1)] # Hydro iteration
    sol_lvl = [[] for x in range(stages+1)] # Batteries iteration
    sol_vol[0].append(dict_data['volData'][0])
    sol_lvl[0].append([dict_data['battData'][0][x]*dict_batt["b_storage"][x][0][0] for x in range(len(batteries))])

    iteration = 0 # Counter for number of iterations
    confidence = 0 # stop criteria

    # Save operational cost by iteration
    operative_cost = [[], []]

    # define: parameter classes
    # deterministic / stochastic analysis
    stochastic = True
    if seriesBack == 1: stochastic = False # Deterministic

    dataParamB = classes.param_B(stages, seriesBack, stochastic, eps_risk, commit, parallel, param_opf, gates)
    dataParamF = classes.param_F(stages, seriesForw, max_iter, results, param_opf, gates)

    # export options SI or NO
    if results is True:
        from utils.saveresults import printresults

    #==============================================================================
    # loop iterations
    if policy is True:

        while not iteration >= max_iter and not confidence >= 2:

            # save the FCF - backward steps
            fcf_backward = [[] for x in range(stages+1)]
            fcf_backward[stages]=[[[0]*len(hydroPlants), [0]*len(batteries), 0]]

            # Backward_Risk6_par to parallel simulation
            fcf_backward = backward.data(dataParamB, fcf_backward, sol_vol, iteration, sol_lvl)

            data = {}
            data['state'] = 'loopIterations'
            data['message'] = 'Iterando backward ' + str(iteration)
            data['phase'] = 3
            data['percent'] = ((iteration + 1) / max_iter) * 50
            json_data = json.dumps(data)
            r.publish('room/' +str(params['id']), json_data)
            percent = str(data['percent']) + '% Backward'
            print(percent)

            # Forward stage - Pyomo module
            (sol_vol, sol_lvl, sol_costs, sol_scn) = forward.data(confidence, fcf_backward,
            dataParamF, iteration, sol_vol, sol_lvl)

            data = {}
            data['state'] = 'loopIterations'
            data['message'] = 'Iterando Forward ' + str(iteration)
            data['phase'] = 3
            data['percent'] = ((iteration + 1) / max_iter) * 100
            percent = str(data['percent']) + '% Forward'
            print(percent)

            json_data = json.dumps(data)
            r.publish('room/' +str(params['id']), json_data)

            # confidence
            confd, op_cost, op_inf = optimality.data(sol_costs, seriesForw)
            confidence += confd
            iteration += 1

            # Saver results
            operative_cost[0].append(op_cost), operative_cost[1].append(op_inf)

            if iteration == max_iter or confidence == 2:
                datafcf = {"fcf_backward":fcf_backward, "sol_vol":sol_vol, "sol_lvl":sol_lvl, 'sol_scn':sol_scn}
                pickle.dump(datafcf, open("savedata/fcfdata.p", "wb"))

                # generate report
                if results is True:
                    print('Writing results ...')
                    # results files and reports
                    printresults(seriesForw, (stages-extra_stages), sol_scn, curves)

    elif policy is False and simulation is True:

        # stages to be simulate
        dict_fcf = pickle.load(open("savedata/fcfdata.p", "rb"))
        fcf_backward = dict_fcf['fcf_backward']

        sol_vol = dict_fcf['sol_vol']
        sol_lvl = dict_fcf['sol_lvl']
        iteration = 0
        confidence = 1

        # Forward stage - Pyomo module
        (sol_vol, sol_lvl, sol_costs, sol_scn) = forward.data(confidence, fcf_backward,
        dataParamF, iteration, sol_vol, sol_lvl)

        # Saver results
        confidence, op_cost, op_inf = optimality.data(sol_costs,seriesForw)
        operative_cost[0].append(op_cost), operative_cost[1].append(op_inf)

        # generate report
        if results is True:
            print('Writing results ...')
            # results files and reports
            printresults(seriesForw, (stages-extra_stages), sol_scn, curves)

    elif policy is False and simulation is False:

        if results is True:

            # recover results
            dict_fcf = pickle.load(open("savedata/fcfdata.p", "rb"))
            sol_scn = dict_fcf['sol_scn']

            print('Writing results ...')
            # results files and reports
            printresults(seriesForw, (stages-extra_stages), sol_scn, curves)


import logging
from unittest import TestCase
from Signage.src.google_street_view_etl import GoogleStreetViewEtl as GSVE
import geopandas as gpd
import numpy as np
import random

class TestGoogleStreetViewEtl(TestCase):
    @classmethod
    def _get_iter(cls):
        _st_shp = gpd.read_file(
            "/Users/sunghoonyang/PycharmProjects/groundwork-detection/Signage/asset/geo_export_ce677b00-822e-465b-8b4f-aacaff026101.shp")
        mh_sts = \
            _st_shp[(_st_shp["borocode"] == "2") & (_st_shp["st_width"] > 20) & (_st_shp["st_width"] < 30)][
                'geometry']
        for street in list(mh_sts.get_values()).__reversed__():
            for i in np.arange(0, len(street.xy[0]), 5):
                x = street.xy[0][i]
                y = street.xy[1][i]
                yield x, y

    @classmethod
    def _get_puma_iter(cls):
        _raw = gpd.read_file(
            r"/Users/sunghoonyang/Google Drive/Argo/groundwork-detection/intersection_dta/StreetsOnlyGCSNA1983/OnStreetOnlyGCSNA1983.shp")
        # random sampling from the population of intersection coordinates
        # in the below set up each coordinate pair will create 6 * 2 = 12 images
        _x_shp = _raw.loc[random.sample(range(0, _raw.size), int(1e4)), :]
        for ix, _row in _x_shp.iterrows():
            puma, pt = _row
            if pt is np.nan:
                logging.warning('Point is np.nan. Skipping...')
                continue
            yield pt.x, pt.y, {'demarcation': puma, 'fov': [30, 90], 'heading': list(np.arange(0, 360, 60))}

    @classmethod
    def _get_nh_iter(cls):
        _raw = gpd.read_file(
            r"/Users/sunghoonyang/Google Drive/Argo/groundwork-detection/intersection_dta/20190114 Neighborhood Intersections/neighborhood_intersections.shp")
        # random sampling from the population of intersection coordinates
        # in the below set up each coordinate pair will create 6 * 2 = 12 images
        _x_shp = _raw.loc[random.sample(range(0, _raw.size), int(1e4)), :]
        for ix, _row in _x_shp.iterrows():
            nh, pt = _row
            if pt is np.nan:
                logging.warning('Point is np.nan. Skipping...')
                continue
            yield pt.x, pt.y, {'demarcation': nh, 'fov': [30, 90], 'heading': list(np.arange(0, 360, 60))}

    def test_iter_work(self):
        GSVE.work(
            TestGoogleStreetViewEtl._get_iter()
            , r'/Users/sunghoonyang/Google Drive/Argo/groundwork-detection/img'
        )

    def test_puma_iter_work(self):
        GSVE.work(
            TestGoogleStreetViewEtl._get_puma_iter()
            , r'/Users/sunghoonyang/Google Drive/Argo/groundwork-detection/img'
        )

    def test_nh_iter_work(self):
        GSVE.work(
            TestGoogleStreetViewEtl._get_nh_iter()
            , r'/Users/sunghoonyang/Google Drive/Argo/groundwork-detection/img/neighborhood-images/'
        )


#coding=utf-8
# 05.16 교수요청사항
# 기존의 Search Engine 에서 했던것처럼
# 단어들을 lexical 단위에서 + 형태소 단위에서
# 구조가 아닌 단어들의 이치를 보고 하면 어떻게 되느냐에 대한 코드 작성

import operator
import os
from whoosh.index import create_in
from whoosh.fields import *
from whoosh.qparser import QueryParser
from typing import List, TextIO,Dict
import time
'''__________ CONFIG AREA START __________'''
DATA_DIR: str         = "../WISEKB/data/"
Q_FILE_NAME: str      = "tmpQ_WT.txt" # Q.txt
Q_MORP_FILE_NAME: str = "tmpQ_M_WT.txt" ## Q_MORP.txt
'''__________ CONFIG AREA END   __________'''

def log(tag, text)-> None:
    # Info tag
    if (tag == 'i'):
        print("[INFO] " + text)
    # Error tag
    elif (tag == 'e'):
        print("[ERROR] " + text)
    # Success tag
    elif (tag == 's'):
        print("[SUCCESS] " + text)

def get_data_from_txt(_filename)-> List[str]:
    """`

    :return: data List
    """
    dataList :List[str] = []
    f : TextIO = open(file=_filename, mode='r', encoding='utf8')

    for line in f.readlines():
        dataList.append(line.strip())

    f.close()
    log('s', "{} 파일에서 {} 줄 불러옴".format(_filename, len(dataList)))

    return dataList

def extract_morp_str(_morpStr: str) -> str:
    """

    :param _morpStr: morp long string
    :return: 품사만 남은 string
    """
    tmp: str = ""
    splitList = _morpStr.split(' ')
    for morp in splitList:
        try:
            tmp += morp.split('/')[1] + " "
        except:  # 공백인 경우, 형태소분석결과가 없음
            pass
    return tmp.strip()

def tmp_get_morp_from_list(_sentece)-> str:
    idx: int = QList.index(_sentece)
    tmp: str = ""
    splitList = QMList[idx].split(' ')
    for morp in splitList:
        try:
            tmp += morp.strip() + " "
        except:  # 공백인 경우, 형태소분석결과가 없음
            pass

    return tmp.strip()

def get_morp_from_list(_sentece)-> str:
    idx: int = QList.index(_sentece)
    morpStr: str = extract_morp_str(QMList[idx])
    return morpStr

if __name__ == "__main__":
    # Load dataset data
    QList: List[str] = get_data_from_txt(DATA_DIR + Q_FILE_NAME)
    QMList: List[str] = get_data_from_txt(DATA_DIR + Q_MORP_FILE_NAME)
    tuneQMList :List[str] = []
    # Set index directory
    indexdir = './origin_ndx'
    if not os.path.exists(indexdir):
        os.makedirs(indexdir)

    # Set schema
    schema = Schema(title=TEXT(stored=True),
                    path=ID(stored=True),
                    content=NGRAMWORDS(minsize=2, maxsize=3, stored=True),
                    idx=ID(stored=True))
    # create schema
    ix = create_in(indexdir, schema)

    # Define the writer for search Inverted
    writer = ix.writer()

    # Preprocess
    # 1. lexical 단위에서 할꺼면 그냥 문장 그대로 content 에 넣으면 됨.
    # 2. 형태소 단위니까 태그 안 떼고 넣기로함

    #for fori in range(len(QList)):# 1. Lexical
        #tuneQMList.append(QList[fori])# 1. Lexical
    for fori in range(len(QMList)):
        tuneQMList.append(QMList[fori])# 2. g형태소단위

    # Build DB
    for fori in range( len(QList) ):
        writer.add_document(title=u"{}".format(QList[fori]),
                            path=u"/wt",
                            content=u"{}".format(tuneQMList[fori]),
                            idx=u"{}".format(fori))
    writer.commit()

    # create query datas from input file and
    # create output file stream
    f = open('input.txt','r',encoding='utf8')
    querys: List[str] = f.readlines()
    f.close()

    outF = open('output.txt','w',encoding='utf8')
    '''
    # 데이터 모자른거 채울때 문서수정할때
    for query in querys:
        query = query.strip()
        try:
            queryIdx = QList.index(query)
        except:
            print(query)
    exit(-1)
    '''

    # Search
    with ix.searcher() as searcher:
        qp = QueryParser("content", ix.schema)
        idx = 1
        # time checking
        start = time.time()
        for query in querys:
            dataDict: Dict[int, int] = {}
            log('i', "{}번째 검색중..".format(idx))
            idx += 1
            query = query.strip()
            queryIdx = QList.index(query)

            # 1. lexical 단위이기에 필요없음
            #    추가적으로 N-gram 햇던부분도 필요없어서 뺌
            # querySplit = query.split(' ')
            # for q in querySplit:
            #     user_q = qp.parse(u'{}'.format(q))
            #     results = searcher.search(user_q, limit=5)
            #     for r in results:
            #         try:
            #             dataDict[r['idx']] += r.score
            #         except:
            #             dataDict[r['idx']] = r.score
            #
            # sortedTmp = sorted(dataDict.items(), key=operator.itemgetter(1), reverse=True)

            # 2. 형태소 단위이기에 필요없음
            morpStr = tmp_get_morp_from_list(query)
            splitMorp = morpStr.split(' ')
            for q in splitMorp:
                user_q = qp.parse(u'{}'.format(q))
                results = searcher.search(user_q, limit=5)
                for r in results:
                    try:
                        dataDict[r['idx']] += r.score
                    except:
                        dataDict[r['idx']] = r.score

            sortedTmp = sorted(dataDict.items(), key=operator.itemgetter(1), reverse=True)

            #morpStr = get_morp_from_list(query)
            #splitMorp = morpStr.split(' ')

            # # bi-gram weight sum
            # for fori in range(len(splitMorp) - 1):
            #     user_q = qp.parse(u'{}'.format(splitMorp[fori]+" "+splitMorp[fori+1]))
            #     results = searcher.search(user_q, limit=10)
            #     for r in results:
            #         try:
            #             dataDict[r['idx']] += r.score
            #         except:
            #             dataDict[r['idx']] = r.score
            # # Tri-gram weight sum
            # # 여기를 지우면 단순하게 bi-gram 까지만의 weight sum 을 이용
            # for fori in range(len(splitMorp) - 2):
            #     user_q = qp.parse(u'{}'.format(splitMorp[fori]+" "+splitMorp[fori+1]+" "+splitMorp[fori+2]))
            #     results = searcher.search(user_q, limit=10)
            #     for r in results:
            #         try:
            #             dataDict[r['idx']] += r.score
            #         except:
            #             dataDict[r['idx']] = r.score
            # sortedTmp = sorted(dataDict.items(), key=operator.itemgetter(1), reverse=True)
            # Toprank 5개 뽑아야하니까
            cnt = 0
            if len(sortedTmp) < 6:
                for _ in range(5):
                    outF.write('\n')
            else:
                while True:
                    if cnt == 5:
                        break

                    top = sortedTmp.pop(0)

                    if int(top[0]) == queryIdx: # 자기랑 같은 문장은 제외
                        first = False
                        pass
                    else:
                        outF.write(QList[int(top[0])] + '\n')
                        cnt += 1
        end = time.time()
        # time checking end
        print(end-start) # only bi-gram = 42.87초, 개당 0.21초  | include tri-gram 57.36초 개당 0.28초
    outF.close()


"""
BFS
1st group
    check visited
    add group
2nd+ group
    group -> check visited initial
    check visited
    add group

if len(group) > 0:
    Calc

처음부터 말렸다. DFS BFS 중에 고민했고, BFS가 더 효율적으로 제거할 수 있을거라 생각했다.
근데, 생각보다 모든 Cell을 Search하는게 시간을 많이 잡아먹었다.
비효율적으로 Search 할 수 밖에 없다고 생각은 했는데,
바꾼 영역만을 다시 Search하는게 더 좋다는 것은 영역이 커질수록 영향을 많이 준다는 것을 깨달았다...
생각해보면 N=50일 때, 가장 마지막 일부 영역만 숫자가 바뀐다면,
굳이 처음부터 Search를 할 필요는 없을테니....아쉽다.
"""
# start 21.04.15 AM09:32
# Reading 3mins
# Alg Writing  7mins
# First AM10:42 - Wrong Answer
# Second 21.04.17 PM03:40 - Time
# Third 21.04.17 PM05:00 - PASS

import sys; input = sys.stdin.readline
from collections import deque

class MAP():
    def __init__(self, tbl, N, L, R):
        self.N = N
        self.L = L
        self.R = R
        self.M = tbl
        self.visited = None
        self.groups = None
        self.sums = None
        self.GM = None
        self.flag = True
        self.dirs = [[0, 1], [1, 0], [0, -1], [-1, 0]]

        self.raw_gm = [[-1 for _ in range(self.N)] for _ in range(self.N)]
        self.raw_vis = [[0 for _ in range(self.N)] for _ in range(self.N)]
        # self.print(self.M)
        # print("")

    def print(self, tbl):
        print('\n')
        for i in range(self.N):
            for j in range(self.N):
                print(tbl[i][j], end=' ')
            print('\n')
        print("===================")
        return

    def feasible(self, r, c):
        if 0 <= r < self.N and 0 <= c < self.N:
            return True
        else:
            return False

    def thres(self, v):
        if self.L <= abs(v) <= self.R:
            return True
        else:
            return False

    def BFS(self, pr, pc, g):
        if not self.visited[pr][pc]:
            self.visited[pr][pc] = 1
            visited = [row[:] for row in self.visited]

            dq = deque([(pr, pc)])
            tmp = [(pr, pc)]
            _s = 0
            while dq:
                r, c = dq.popleft()
                visited[r][c] = 1
                self.GM[r][c] = g
                pv = self.M[r][c]
                _s += pv
                # print(dq)

                for d in self.dirs:
                    nr, nc = r+d[0], c+d[1]
                    if self.feasible(nr, nc) and not visited[nr][nc]:
                        nv = self.M[nr][nc]
                        if self.thres(nv - pv) and self.GM[nr][nc] < 0:
                            visited[nr][nc] = 1
                            self.visited[nr][nc] = 1
                            dq.append((nr, nc))
                            tmp.append((nr, nc))
                            # print(dq)
                            # self.visited[nr][nc] = 1
                            # tmp.append((nr, nc))
                            # _s += nv
                            # self.GM[nr][nc] = g
            if len(tmp) > 1:
                self.groups.append(tmp)
                self.sums.append(_s)
                return True
            else:
                self.GM[pr][pc] = 1
                return False
        else:
            return False

    def init_map(self):
        self.GM = [raw[:] for raw in self.raw_gm]
        self.visited = [raw[:] for raw in self.raw_vis]
        self.groups = []
        self.sums = []
        return

    def run(self):
        step = 0
        search = deque([])  #! 이게 진짜 좋은 부분인 듯.
        for i in range(self.N):
            for j in range(self.N):
                search.append((i, j))

        while self.flag:
            g = 2
            self.init_map()
            while search:
                i, j = search.popleft()
                if self.BFS(i, j, g):
                    g = g+1

            # self.print(self.GM)
            # self.print(self.visited)

            if len(self.groups):
                self.flag = True

                for gg, ss in zip(self.groups, self.sums):
                    avg_sums = ss//len(gg)
                    for cell in gg:
                        r, c = cell
                        self.M[r][c] = avg_sums
                        search.append((r,c))  #! 이게 진짜 좋은 부분인 듯.

                step += 1
                # self.print(self.M)
                # print("")
            else:
                self.flag = False

        return step

def main():
    N, L, R = list(map(int, input().split()))
    tbl = []
    for _ in range(N):
        tbl.append(list(map(int, input().split())))
    m = MAP(tbl, N, L, R)
    ret = m.run()
    print(ret)

if __name__ == '__main__':
    main()


from qiskit import QuantumCircuit, ClassicalRegister, QuantumRegister
from qiskit import Aer, execute
from qiskit.extensions.quantum_initializer.initializer import Initialize
import matplotlib.pyplot as plt
import random
import math

'''Calculate QC'''
def w(x):
    count=0
    while x:
        count+=1
        x&=(x-1)
    return count
def QC(x):
    QC=12*x-6*w(int(x/2))-6*math.floor(math.log2(x/2))-8-2
    print("QC=", QC)
    return QC

'''Important settings'''
add_bit=3   # Users can customize add_bit.
s_number=add_bit+1
total_qubit_number=QC(add_bit)

'''random addition'''
rand_int_a = random.randint(0, 2**add_bit-1)
rand_addend_a = bin(rand_int_a)[2:].zfill(add_bit)
rand_int_b = random.randint(0, 2**add_bit-1)
rand_addend_b = bin(rand_int_b)[2:].zfill(add_bit)
print("a =",rand_addend_a ,"b =",rand_addend_b)
rand_int_sum=rand_int_a+rand_int_b
rand_sum = bin(rand_int_sum)[2:].zfill(add_bit+1)
print("real sum =",rand_sum )
circuit = QuantumCircuit(total_qubit_number,s_number)
print(add_bit, "bits quantum Ling adder")

'''initialize'''

strr=''
for i in range(add_bit):
    strr=strr+'00'+rand_addend_b[i]+rand_addend_a[i]
print(strr)
Initial_state='0'*(total_qubit_number-4*add_bit)+strr
print("Initial_state",Initial_state)
circuit.append(Initialize(Initial_state), range(total_qubit_number))

'''customize OR gate'''
qc = QuantumCircuit(3, name='OR')
qc.x(0)
qc.x(1)
qc.ccx(0,1,2)
qc.x(0)
qc.x(1)
qc.x(2)
OR_gate = qc.to_instruction()
'''Different Steps'''
def step1(circuit,a0,b0,acilla0,acilla1):
    circuit.ccx(a0,b0,acilla0)
    circuit.cx(a0, acilla1)
    circuit.cx(b0, acilla1)
    circuit.cx(acilla0, acilla1)
    circuit.cx(a0, b0)
def step1_uncomputation(circuit,a0,b0,acilla0,acilla1):
    circuit.cx(acilla0, acilla1)
    circuit.cx(a0, acilla1)
    circuit.ccx(a0,acilla1,acilla0)
def step2(circuit,p_i,g_i,p_ii,g_ii,acilla0,acilla1):
    circuit.ccx(p_i, p_ii, acilla0)
    circuit.append(OR_gate, [g_i, g_ii, acilla1])
def step2_last(circuit,g_i,g_ii,acilla1):
    circuit.append(OR_gate, [g_i, g_ii, acilla1])
def step2_uncomputation(circuit,p_i,g_i,p_ii,g_ii,acilla0,acilla1):
    circuit.append(OR_gate, [g_i, g_ii, acilla1])
    circuit.ccx(p_i, p_ii, acilla0)
def step2_last_uncomputation(circuit,g_i,g_ii,acilla1):
    circuit.append(OR_gate, [g_i, g_ii, acilla1])
###################################################################
def step3_G(circuit,gx,px,gy,py,acilla0, acilla1): #p0=0,p1=0; g0=gl0
    circuit.ccx(gy,px, acilla0)
    circuit.append(OR_gate, [gx,acilla0, acilla1])
def step3_P(circuit,px,py,acilla2): #p0=0,p1=0; g0=gl0
    circuit.ccx(py,px, acilla2)
#(gx, px) ◦ (gy, py) = (gx + px · gy, px · py) (10)
#Hi = Gi + Pi−1 · Gi−2, Hi=final G?
def propagation(circuit,gx,px,gy,py,ancilla_base): #gp
    ancilla1=ancilla_base+1
    ancilla2=ancilla_base+2
    p_next=px
    #g_next=gx|p_special&gy #00 0
    print("G")
    step3_G(circuit, gx, px, gy, py,ancilla_base, ancilla1)
    g_next=ancilla1
    ancilla_base=ancilla1+1
    #g_next = gx | gy & px  # 00 0
    if (py!=3) and (px!=3):
        print("P")
        step3_P(circuit,px,py,ancilla2)
        p_next=ancilla2
        ancilla_base=ancilla2+1
    return g_next,p_next,ancilla_base#p_next

""" Utility functions"""
pow2 = lambda x: (2 ** x)
log2 = lambda x: x.bit_length()

'''Brent Kung Tree'''
def BKTree(bitwidth):
    log2_bitwidth = log2(bitwidth - 1)  # Upsweep length for BK
    """ Creates the prefix tree.
    """
    bitwidth_i = bitwidth - 1  # Counting from 0
    matrix = [[None for i in range(bitwidth_i)] for i in range(bitwidth_i)]
    for idx_row in range(log2_bitwidth):
        shift_length = pow2(idx_row + 1)  # Shift lenght; Sequence in the loop 2, 4, 8, 16..
        starting_index = shift_length - 2  # Starting indexes in the matrix; Sequence in the loop 0 2 6 14 ...
        starting_value = pow2(
            idx_row) - 1  # Starting values in the matrix; Sequence in the loop 0 1 3 7 15(shift_length/2 - 1)
        # Mades the row values and indexes sequences
        values_seq = list(range(starting_value, bitwidth_i, shift_length))
        indexes_seq = list(range(starting_index, bitwidth_i, shift_length))
        if not indexes_seq:  # There is no other index
            continue
            # If the root of prefixtree wasnt saved yet. The index (bitwidth) is not power of two.
            # indexes_seq = [bitwidth_i - 1] # Save the right-most index {The index of index -> (-1 -1)}
        # Fill the row
        for index, val in zip(indexes_seq, values_seq):
            matrix[idx_row][index] = val
    """ Creates the inverse tree.
    """
    for idx_row in range(1, log2_bitwidth + 1):
        shift = 2 ** idx_row  # Sequence  2 4 8 16 32
        values_start = shift - 1  # Sequence 1 3 7 15
        indexes_start = (-4 + 3 * (2 ** idx_row)) // 2  # Sequence 1 4 10 22 46 etc.
        values = range(values_start, bitwidth_i, shift)
        indexes = range(indexes_start, bitwidth_i, shift)
        # Fill the row
        for index, val in zip(indexes, values):
            matrix[-idx_row][
                index] = val  # Do not manipulate with idx_row, else it will not be usable for Lander Sklansky and Han Carlson adders
    return matrix

def Brent_Kung(circuit,g_location, p_location,ancilla_base):
    print("BK_Begin")
    print("length", len(g_location))
    bit_num = len(g_location)
    # establish bit_num BK tree, do propagation and generation
    BK_Matrix = BKTree(bit_num)
    size = bit_num - 1
    print("BKtest","g_location", g_location, "p_location", p_location)
    for i in range(size):
        for j in range(size):
            if BK_Matrix[i][j] != None:  # j小了一个1
                index_now = j + 1
                if BK_Matrix[i][j]==0:
                    p_location_x=0
                else:
                    p_location_x = p_location[BK_Matrix[i][j]-1]
                #列表p左移，G3,P2
                print("g_"+str(index_now),g_location[index_now],
                      "p_"+str(index_now),p_location[index_now],
                      "g_"+str(BK_Matrix[i][j]),g_location[BK_Matrix[i][j]],
                      "p_"+str(BK_Matrix[i][j]),p_location_x)
                g_location[index_now], p_location[index_now],ancilla_base= propagation(circuit,g_location[index_now],
                                                                       p_location[index_now],g_location[BK_Matrix[i][j]],
                                                                       p_location[BK_Matrix[i][j]],ancilla_base)
    print(BK_Matrix)
    print("BK_End")
    return ancilla_base

def step3(circuit, p_location, g_location,H_location,ancilla_base):
    print("Ling_Begin")
    print("length", len(g_location))
    bit_num=len(g_location)
    #establish Ling-based Brent Kung Propagation Tree to get H
    G_number = [0 for i in range(add_bit)]
    P_number = [0 for i in range(add_bit)]
    index_BK_1=[i for i in range(0,bit_num,2)]
    index_BK_2 = [i for i in range(1, bit_num, 2)]
    g_BK_1=[g_location[i] for i in index_BK_1]
    p_BK_1 = [p_location[i] for i in index_BK_1]
    g_BK_2=[g_location[i] for i in index_BK_2]
    p_BK_2 = [p_location[i] for i in index_BK_2]
    print("g_location=",g_location,"p_location=",p_location)
    print("g_BK_1",g_BK_1,"p_BK_1",p_BK_1)
    print("g_BK_2",g_BK_2,"p_BK_2",p_BK_2)
    print("index_BK_1",index_BK_1,"index_BK_2",index_BK_2)
    #BK trees=>H
    ancilla_base=Brent_Kung(circuit,g_BK_1, p_BK_1,ancilla_base)
    Brent_Kung(circuit,g_BK_2, p_BK_2,ancilla_base)
    print("After BK")
    print("g_BK_1",g_BK_1,"p_BK_1",p_BK_1)
    print("g_BK_2",g_BK_2,"p_BK_2",p_BK_2)
    for i in range(len(index_BK_1)):
        G_number[index_BK_1[i]]=g_BK_1[i]
        #print("G_"+str(index_BK_1[i]),g_BK_1[i])
        P_number[index_BK_1[i]]=p_BK_1[i]
        #print("P_"+str(index_BK_1[i]),p_BK_1[i])
    for i in range(len(index_BK_2)):
        G_number[index_BK_2[i]]=g_BK_2[i]
        #print("G_"+str(index_BK_2[i]),g_BK_2[i])
        P_number[index_BK_2[i]]=p_BK_2[i]
        #print("P_"+str(index_BK_2[i]),p_BK_2[i])
    print(G_number,P_number)
    # H_BK_1=Brent_Kung(g_BK_1,p_BK_1)
    # H_BK_2=Brent_Kung(g_BK_2, p_BK_2)
    for i in range(bit_num):
        H_location[i] = G_number[i]
        #H_number[i] = G_number[i]|(P_number[i-1]&G_number[i-2])
    print("G0", G_number[0],"g0",g_location[0])
    H_location[0] = g_location[0]  # H0 = g0
    print("Ling_End")
    print("H",H_location)
    return H_location,G_number,P_number
###################################################################
def step4(H_i, d_ii, p_i):
    # circuit.cx(d_ii, p_i)
    # circuit.cswap(H_i, d_ii, p_i)
    circuit.ccx(H_i, p_i, d_ii)
def step4_last(H_i,p_i,acilla0):
    circuit.ccx(H_i,p_i, acilla0)
'''Establish the proposed adder'''
#Step 1
for index in range(add_bit):
    step1(circuit, 4*index, 4*index+1, 4*index+2, 4*index+3) #d=4*index+1,g=4*index+2,p=4*index+3
    print("Step 1",4*index, 4*index+1, 4*index+2, 4*index+3)
circuit.barrier()

#Step 2
p_location=[0 for i in range(add_bit)]
g_location=[0 for i in range(add_bit)]
p_location[0]=3
p_location[1]=3
g_location[0]=2

Step2_ancilla_base=4*add_bit
ancilla_base=Step2_ancilla_base
odd_count=add_bit-1
even_count=add_bit-1
if (add_bit-1)%2==0:
    odd_count=odd_count-1
else:
    even_count=even_count-1
for index in range(0, even_count, 2):
    print("Step2_even", index)
    step2(circuit, 4 * index + 3, 4 * index + 2, 4 * (index + 1) + 3, 4 * (index + 1) + 2, ancilla_base,ancilla_base + 1)
    p_location[index+2]=ancilla_base
    g_location[index+1] = ancilla_base+1
    if index==0:
        H2=ancilla_base + 1
    ancilla_base=ancilla_base+2
if even_count!=add_bit-1:
    print("Step2_last", even_count)
    index=even_count
    step2_last(circuit, 4 * index + 2, 4 * (index + 1) + 2, ancilla_base)
    g_location[index+1] = ancilla_base
    ancilla_base = ancilla_base + 1
#circuit.barrier()
for index in range(1, odd_count , 2):
    print("Step2_odd", index)
    step2(circuit, 4 * index + 3, 4 * index + 2, 4 * (index + 1) + 3, 4 * (index + 1) + 2, ancilla_base,ancilla_base + 1)
    p_location[index+2]=ancilla_base
    g_location[index+1] = ancilla_base+1
    ancilla_base=ancilla_base+2
if odd_count != add_bit-1:
    print("Step2_last", odd_count)
    index = odd_count
    step2_last(circuit, 4 * index + 2, 4 * (index + 1) + 2, ancilla_base)
    g_location[index+1] = ancilla_base
    ancilla_base = ancilla_base + 1
print("ancilla_base",ancilla_base)
print("p",p_location)
print("g",g_location)
circuit.barrier()
# GL0=g0
# PL1=8
# GL1=9
# step2_last(circuit,g2,g3,20)
# GL3=20

#Step 3
#G0=g0
#P0=0,P1=0,前两个操作不做
#输入所有p，g的位置
H_location=[0 for i in range(add_bit)]
step3(circuit, p_location, g_location,H_location,ancilla_base)
#H_location=step3(circuit, p_location, g_location,H_location)
#[2,17,22,24]
circuit.barrier()
#Step 4
# step4(H0,d1,p0), step4(H1,d2,p1)
H1=2
index=1
#S0
step4(H1,4*index+1,4*(index-1)+3) #Hi-1,di,pi-1
index=2
step4(H2,4*index+1,4*(index-1)+3)
'''Hi位置怎么定'''
for index in range(3,add_bit):
    step4(H_location[index-1],4*index+1,4*(index-1)+3) #d=4*index+1,g=4*index+2,p=4*index+3
    print("H_location",H_location[index])
    print("Step 4",4*index+1,4*(index-1)+3)
index=add_bit-1
#最后两位，Hn,Sn+1 16,12,
step4_last(H_location[add_bit-1],4*index+3,total_qubit_number-1)#last qubit
circuit.barrier()

print("Uncomputation")
#Step 2-Uncomputation
if odd_count != add_bit-1:
    ancilla_base = ancilla_base - 1
    print("Step2_last", odd_count)
    index = odd_count
    step2_last_uncomputation(circuit, 4 * index + 2, 4 * (index + 1) + 2, ancilla_base)

for index in range(odd_count-2,-1 , -2):
    print("Step2_odd", index)
    ancilla_base = ancilla_base - 2
    step2_uncomputation(circuit, 4 * index + 3, 4 * index + 2, 4 * (index + 1) + 3, 4 * (index + 1) + 2, ancilla_base,ancilla_base + 1)
if even_count!=add_bit-1:
    print("Step2_last", even_count)
    ancilla_base = ancilla_base - 1
    index=even_count
    step2_last_uncomputation(circuit, 4 * index + 2, 4 * (index + 1) + 2, ancilla_base)
for index in range(even_count-2, -2, -2):
    print("Step2_even", index)
    ancilla_base=ancilla_base-2
    step2_uncomputation(circuit, 4 * index + 3, 4 * index + 2, 4 * (index + 1) + 3, 4 * (index + 1) + 2, ancilla_base,ancilla_base + 1)
circuit.barrier()
#################################################################
#Step 1-Uncomputation
for index in range(add_bit-1,-1,-1):
    step1_uncomputation(circuit, 4*index, 4*index+1, 4*index+2, 4*index+3) #d=4*index+1,g=4*index+2,p=4*index+3
    print("Step 1",4*index, 4*index+1, 4*index+2, 4*index+3)
circuit.barrier()

'''Simulation'''
print("Simulation")
# measure_list=[1,5,11,17,25] #S0,1,2,3,4
measure_list=[1+i*4 for i in range(add_bit)]
measure_list.append(total_qubit_number-1)
circuit.measure(measure_list, range(add_bit+1))
print("Finish setting")
# Select the QasmSimulator from the Aer provider
simulator = Aer.get_backend('qasm_simulator')
# Execute
print("Execute")
result = execute(circuit, simulator, shots=3, memory=True).result()
print("memory")
memory = result.get_memory(circuit)
print(memory)
print("real sum =",rand_sum )
flag=0
S_number=memory[0]
for i in range(add_bit+1):
    if S_number[i]!=str(rand_sum[i]):
        flag=flag+1
        print("i",i,S_number[i],int(rand_sum[i]))
        # Si = Hi−1 · di + Hi−1 · (di ⊕ pi−1) , if 0 < i < n
        # Si = (Hi−1 * pi−1) ⊕ di
if flag==0:
    print("Corret!")
else:
    print("Wrong!",flag)

'''Draw Diagram'''
#print(circuit.draw(output='latex_source'))
# circuit.draw(output='mpl')
# plt.show()


# auther：Liul8
# date：2020/7/27 15:01
# tools：PyCharm
# Python：3.7.7
from flask import Flask, request, jsonify
from pytesseract import pytesseract
from PIL import Image
import os
import urllib.request

app = Flask(__name__)
ALLOWED_EXTENSIONS = {'png', 'jpg', 'jpeg'}

def allowed_file(filename):
    return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS

def get_blackwhite_image(picture_name, threshold=160):
    """图片处理成黑白色"""
    table = [0 if _ < threshold else 1 for _ in range(256)]
    image = Image.open(picture_name)
    imgry = image.convert('L')
    out = imgry.point(table, '1')
    return out

def download_image(url):
    files = 'images'
    try:
        if not os.path.exists(files):
            os.makedirs(files)  # 如果没有这个path则直接创建
        image_path = os.path.join(files, "validate_code.jpg")
        # 利用urllib.request.urltrieve方法下载图片
        urllib.request.urlretrieve(url, filename=image_path)
        return image_path
    except IOError as e:
        print(1, e)
        return False
    except Exception as e:
        print(2, e)
        return False

@app.route("/validate-code-recognition", methods=['POST'])
def validate_code_recognition():
    flag = request.form.get("flag", True)
    image = request.files.get("image", None)
    lang = request.form.get("lang", "eng")
    oem = request.form.get("oem", "1")
    psm = request.form.get("psm", "3")
    url = request.form.get("url", None)
    config = f"-l {lang} --oem {oem} --psm {psm}"
    if not image and not url:
        return jsonify({"msg": "image file don`t exist!", "code": 0}), 400
    if image:
        filename = image.filename
    else:
        filename = download_image(url)
        image = filename
    if not allowed_file(filename):
        return jsonify({"msg": f"Allowed file types are: {ALLOWED_EXTENSIONS}", "code": 0}), 400

    if flag:
        image = get_blackwhite_image(image)
    else:
        image = Image.open(image)
    text = pytesseract.image_to_string(image, config=config)
    return jsonify({"code": 1, "msg": "success", "data": {"text": text}}), 200

if __name__ == "__main__":
    app.run(host="0.0.0.0", port=5000)


"""Management command for syncing requirements."""
from argparse import ArgumentParser
from collections import defaultdict
from logging import getLogger
from typing import Any, Dict, List

from django.core.mail import send_mail
from django.core.management.base import BaseCommand
from django.db.utils import IntegrityError
from django.template.loader import render_to_string
from django.utils.timezone import now as tz_now
from requirements.parser import parse
from requirements.requirement import Requirement

from ...models import PackageVersion
from ...settings import REQUIREMENTS_FILE

logger = getLogger(__name__)

def create_package_version(requirement: Requirement) -> None:
    """Create a new PackageVersion from a requirement. Handles errors."""
    try:
        PackageVersion(requirement=requirement).save()
        logger.info("Package '%s' added.", requirement.name)  # noqa
    except IntegrityError:
        logger.info("Package '%s' already exists.", requirement.name)  # noqa

def local() -> None:
    """Load local requirements file."""
    logger.info("Loading requirements from local file.")
    with open(REQUIREMENTS_FILE, "r") as f:
        requirements = parse(f)
        for r in requirements:
            logger.debug("Creating new package: %r", r)
            create_package_version(r)

def remote() -> Dict[str, List]:
    """Update package info from PyPI."""
    logger.info("Fetching latest data from PyPI.")
    results = defaultdict(list)
    packages = PackageVersion.objects.exclude(is_editable=True)
    for pv in packages:
        pv.update_from_pypi()
        results[pv.diff_status].append(pv)
        logger.debug("Updated package from PyPI: %r", pv)
    results["refreshed_at"] = tz_now()
    return results

def clean() -> None:
    """Clean out all packages."""
    PackageVersion.objects.all().delete()
    logger.info("Deleted all existing packages.")

class Command(BaseCommand):

    help = (
        "This command can be used to load up a requirements file "
        "and check against PyPI for updates."
    )

    def add_arguments(self, parser: ArgumentParser) -> None:
        parser.add_argument(
            "--local",
            action="store_true",
            dest="local",
            default=False,
            help="Load local requirements file",
        )
        parser.add_argument(
            "--remote",
            action="store_true",
            dest="remote",
            default=False,
            help="Load latest from PyPI",
        )
        parser.add_argument(
            "--clean",
            action="store_true",
            dest="clean",
            default=False,
            help="Delete all existing requirements",
        )
        parser.add_argument("--notify", help="Send results notification email")
        parser.add_argument(
            "--from",
            default="Django Package Monitor <packages@example.com>",
            help="Notification email 'from' address",
        )
        parser.add_argument(
            "--subject",
            default="Package manager update",
            help="Notification email subject line.",
        )

    def handle(self, *args: Any, **options: Any) -> None:
        """Run the managemement command."""
        if options["clean"]:
            clean()

        if options["local"]:
            local()

        if options["remote"]:
            results = remote()
            if options["notify"]:
                send_mail(
                    options["subject"],
                    render_to_string("summary.txt", results),
                    options["from"],
                    [options["notify"]],
                    html_message=render_to_string("summary.html", results),
                    fail_silently=False,
                )


from typing import Tuple
from neural import *
from sklearn.model_selection import train_test_split
import matplotlib.pyplot as plt
import numpy as np

def parse_line(line: str) -> Tuple[List[float], List[float]]:
    """Splits line of CSV into inputs and output (transormfing output as appropriate)

    Args:
        line - one line of the CSV as a string

    Returns:
        tuple of input list and output list
    """
    tokens = line.split("\t")
    # print(tokens)
    out = int(tokens[0])
    # print(out)
    output = [0 if out < 3000000 else 0.5 if out < 5000000 else 1]
    # print(output)

    inpt = [float(x) for x in tokens[1:5]]
    # print(inpt)
    return (inpt, output)

def normalize(data: List[Tuple[List[float], List[float]]]):
    """Makes the data range for each input feature from 0 to 1

    Args:
        data - list of (input, output) tuples

    Returns:
        normalized data where input features are mapped to 0-1 range (output already
        mapped in parse_line)
    """
    leasts = len(data[0][0]) * [100.0]
    mosts = len(data[0][0]) * [0.0]

    for i in range(len(data)):
        for j in range(len(data[i][0])):
            if data[i][0][j] < leasts[j]:
                leasts[j] = data[i][0][j]
            if data[i][0][j] > mosts[j]:
                mosts[j] = data[i][0][j]

    for i in range(len(data)):
        for j in range(len(data[i][0])):
            data[i][0][j] = (data[i][0][j] - leasts[j]) / \
                (mosts[j] - leasts[j])
    return data

with open("data.txt", "r") as f:
    f.readline()
    training_data = [parse_line(line)
                     for line in f.readlines() if len(line) > 4]

# for line in training_data:
#     print(line)

td = normalize(training_data)

train_data, test_data = train_test_split(td, test_size=.15)
print(len(train_data))
print(len(test_data))
# for line in td:
#     print(line)

nn = NeuralNet(4, 6, 1)

nn.train(train_data, learning_rate=.85)
result = nn.test_with_expected(test_data)
x, y = [], []
print(x, y)
for i in result:
    print(f"desired: {i[1]}, actual: {i[2]}")
    x += (i[1])
    y += (i[2])
print(x, y)

# print(result)

# make data:
# np.random.seed(3)
# x = 0.5 + np.arange(10)
# y = np.random.uniform(2, 7, len(x))

# # plot
# fig, ax = plt.subplots()

# ax.bar(x, y, width=1, edgecolor="white", linewidth=0.7)

# ax.set(xlim=(0, 8), xticks=np.arange(0, 10),
#        ylim=(0, 8), yticks=np.arange(0, 10))

# plt.show()

# plt.style.use('_mpl-gallery-nogrid')

# # make data
# x = [1,2]
# colors = plt.get_cmap('Blues')(np.linspace(0.2, 0.7, len(x)))

# # plot
# fig, ax = plt.subplots()
# ax.pie(x, colors=colors, radius=3, center=(4, 4),
#        wedgeprops={"linewidth": 1, "edgecolor": "white"}, frame=True)

# ax.set(xlim=(0, 8), xticks=np.arange(1, 8),
#        ylim=(0, 8), yticks=np.arange(1, 8))

# plt.show()

plt.style.use('_mpl-gallery')

# make the data
# np.random.seed(3)
# x = 4 + np.random.normal(0, 2, 24)
# y = 4 + np.random.normal(0, 2, len(x))
# size and color:
sizes = np.random.uniform(15, 80, len(x))
colors = np.random.uniform(15, 80, len(x))

# plot
fig, ax = plt.subplots()

ax.scatter(x, y, s=sizes, c=colors, vmin=0, vmax=1)

ax.set(xlim=(0, 1), xticks=np.arange(0, 1),
       ylim=(0, 1), yticks=np.arange(0, 1))

plt.show()