text:
"""
http://en.wikipedia.org/wiki/Test_functions_for_optimization

minimum: f(-10,1) = 0
for
-15 < x < -5
-3 < y < 3
"""

from numpy import exp, cos, sqrt, pi
import numpy as np

from base_function import BaseFunction
from pygmin.systems import BaseSystem

class Bulkin(BaseFunction):
    xmin = np.array([-15.,-3.])
    xmax = np.array([-5.,3.])
    target_E = 0.
    def getEnergy(self, coords):
        x, y = coords
        E = 100. * sqrt(abs(y - 0.01 * x**2)) + 0.01 * abs(x + 10.)
        return E

    def get_random_configuration(self):
        x = np.random.uniform(-13,-8, 1)
        y = np.random.uniform(-4,-4, 1)
        return np.array([x,y]).flatten()

class BukinSystem(BaseSystem):
    def get_potential(self):
        return Bulkin()

if __name__ == "__main__":
    from base_function import makeplot2d
    makeplot2d(Bulkin())

max_stars_repo_name: alvinwan/explore

max_issues_repo_name: alvinwan/explore

max_forks_repo_name: alvinwan/explore

reason: import numpy,from numpy


text:
import numpy as np
from sklearn import cluster
from sklearn.preprocessing import normalize
from munkres import Munkres

from sklearn.metrics.cluster import normalized_mutual_info_score
from sklearn.metrics.cluster import adjusted_rand_score

from scipy.sparse.linalg import svds
from scipy import sparse as sp
from scipy.special import comb

np.random.seed(1)

def best_map(L1, L2):
    #L1 should be the groundtruth labels and L2 should be the clustering labels we got
    Label1 = np.unique(L1)
    nClass1 = len(Label1)
    Label2 = np.unique(L2)
    nClass2 = len(Label2)
    nClass = np.maximum(nClass1,nClass2)
    G = np.zeros((nClass,nClass))
    for i in range(nClass1):
        ind_cla1 = L1 == Label1[i]
        ind_cla1 = ind_cla1.astype(float)
        for j in range(nClass2):
            ind_cla2 = L2 == Label2[j]
            ind_cla2 = ind_cla2.astype(float)
            G[i,j] = np.sum(ind_cla2 * ind_cla1)
    m = Munkres()
    index = m.compute(-G.T)
    index = np.array(index)
    c = index[:,1]
    newL2 = np.zeros(L2.shape)
    for i in range(nClass2):
        newL2[L2 == Label2[i]] = Label1[c[i]]
    return newL2

def thrC(C, ro):
    if ro < 1:
        N = C.shape[1]
        Cp = np.zeros((N,N))
        S = np.abs(np.sort(-np.abs(C),axis=0))
        Ind = np.argsort(-np.abs(C),axis=0)
        for i in range(N):
            cL1 = np.sum(S[:,i]).astype(float)
            stop = False
            csum = 0
            t = 0
            while(stop == False):
                # print(S.shape, t, i)
                csum = csum + S[t,i]
                if csum > ro*cL1:
                    stop = True
                    Cp[Ind[0:t+1,i],i] = C[Ind[0:t+1,i],i]
                t = t + 1
    else:
        Cp = C
    return Cp

def post_proC(C, K, d, alpha):
    # C: coefficient matrix, K: number of clusters, d: dimension of each subspace
    C = 0.5*(C + C.T)
    r = min(d*K + 1, C.shape[0]-1)
    U, S, _ = svds(C, r, v0=np.ones(C.shape[0]))
    U = U[:,::-1]
    S = np.sqrt(S[::-1])
    S = np.diag(S)
    U = U.dot(S)
    U = normalize(U, norm='l2', axis = 1)
    Z = U.dot(U.T)
    Z = Z * (Z>0)
    L = np.abs(Z ** alpha)
    L = L/L.max()
    L = 0.5 * (L + L.T)
    spectral = cluster.SpectralClustering(n_clusters=K, eigen_solver='arpack', affinity='precomputed', assign_labels='discretize', random_state=66)
    spectral.fit(L)
    grp = spectral.fit_predict(L) + 1
    return grp, L

def err_rate(gt_s, s):
    c_x = best_map(gt_s, s)
    err_x = np.sum(gt_s[:] != c_x[:])
    missrate = err_x.astype(float) / (gt_s.shape[0])
    return missrate

def f1_score(gt_s, s):
    N = len(gt_s)
    num_t = 0
    num_h = 0
    num_i = 0
    for n in range(N-1):
        tn = (gt_s[n] == gt_s[n+1:]).astype('int')
        hn = (s[n] == s[n+1:]).astype('int')
        num_t += np.sum(tn)
        num_h += np.sum(hn)
        num_i += np.sum(tn * hn)
    p = r = f = 1
    if num_h > 0:
        p = num_i / num_h
    if num_t > 0:
        r = num_i / num_t
    if p + r == 0:
        f = 0
    else:
        f = 2 * p * r / (p + r)
    return f

def rand_index_score(clusters, classes):
    tp_plus_fp = comb(np.bincount(clusters), 2).sum()
    tp_plus_fn = comb(np.bincount(classes), 2).sum()
    A = np.c_[(clusters, classes)]
    tp = sum(comb(np.bincount(A[A[:, 0] == i, 1]), 2).sum()
             for i in set(clusters))
    fp = tp_plus_fp - tp
    fn = tp_plus_fn - tp
    tn = comb(len(A), 2) - tp - fp - fn
    return (tp + tn) / (tp + fp + fn + tn)

ext: py

max_stars_repo_name: Geovhbn/MvDSCN

max_issues_repo_name: Geovhbn/MvDSCN

max_forks_repo_name: Geovhbn/MvDSCN

reason: import numpy,from scipy


text:
# Generates the following data files from MIMIC:
# adult_icu.gz: data from adult ICUs
# n_icu.gz: data from neonatal ICUs
# adult_notes.gz: clinical notes from adult ICUs

# Import libraries
import numpy as np
import pandas as pd
import psycopg2
from scipy.stats import ks_2samp
import os
import random

# Ouput directory to generate the files
mimicdir = os.path.expanduser("./mimic_data/")

random.seed(42)

# create a database connection
sqluser = 'mimicuser'
dbname = 'mimic'
schema_name = 'mimiciii'

# Connect to local postgres version of mimic
con = psycopg2.connect(dbname=dbname, user=sqluser, host='127.0.0.1', password='PASSWORD')
cur = con.cursor()
cur.execute('SET search_path to ' + schema_name)

#========helper function for imputing missing values

def replace(group):
  """
  takes in a pandas group, and replaces the
  null value with the mean of the none null
  values of the same group
  """
  mask = group.isnull()
  group[mask] = group[~mask].mean()
  return group

#========get the icu details

# this query extracts the following:
#   Unique ids for the admission, patient and icu stay
#   Patient gender
#   admission & discharge times
#   length of stay
#   age
#   ethnicity
#   admission type
#   in hospital death?
#   in icu death?
#   one year from admission death?
#   first hospital stay
#   icu intime, icu outime
#   los in icu
#   first icu stay?

denquery = \
"""
-- This query extracts useful demographic/administrative information for patient ICU stays
--DROP MATERIALIZED VIEW IF EXISTS icustay_detail CASCADE;
--CREATE MATERIALIZED VIEW icustay_detail as

--ie is the icustays table
--adm is the admissions table
SELECT ie.subject_id, ie.hadm_id, ie.icustay_id
, pat.gender
, adm.admittime, adm.dischtime, adm.diagnosis
, ROUND( (CAST(adm.dischtime AS DATE) - CAST(adm.admittime AS DATE)) , 4) AS los_hospital
, ROUND( (CAST(adm.admittime AS DATE) - CAST(pat.dob AS DATE))  / 365, 4) AS age
, adm.ethnicity, adm.ADMISSION_TYPE
--, adm.hospital_expire_flag
, CASE when adm.deathtime between ie.intime and ie.outtime THEN 1 ELSE 0 END AS mort_icu
, DENSE_RANK() OVER (PARTITION BY adm.subject_id ORDER BY adm.admittime) AS hospstay_seq
, CASE
    WHEN DENSE_RANK() OVER (PARTITION BY adm.subject_id ORDER BY adm.admittime) = 1 THEN 1
    ELSE 0 END AS first_hosp_stay
-- icu level factors
, ie.intime, ie.outtime
, ie.FIRST_CAREUNIT
, ROUND( (CAST(ie.outtime AS DATE) - CAST(ie.intime AS DATE)) , 4) AS los_icu
, DENSE_RANK() OVER (PARTITION BY ie.hadm_id ORDER BY ie.intime) AS icustay_seq

-- first ICU stay *for the current hospitalization*
, CASE
    WHEN DENSE_RANK() OVER (PARTITION BY ie.hadm_id ORDER BY ie.intime) = 1 THEN 1
    ELSE 0 END AS first_icu_stay

FROM icustays ie
INNER JOIN admissions adm
    ON ie.hadm_id = adm.hadm_id
INNER JOIN patients pat
    ON ie.subject_id = pat.subject_id
WHERE adm.has_chartevents_data = 1
ORDER BY ie.subject_id, adm.admittime, ie.intime;

"""

den = pd.read_sql_query(denquery,con)

#----drop patients with less than 48 hour
den['los_icu_hr'] = (den.outtime - den.intime).astype('timedelta64[h]')
den = den[(den.los_icu_hr >= 48)]
den = den[(den.age<300)]
den.drop('los_icu_hr', axis = 1, inplace = True)
# den.isnull().sum()

#----clean up

# micu --> medical
# csru --> cardiac surgery recovery unit
# sicu --> surgical icu
# tsicu --> Trauma Surgical Intensive Care Unit
# NICU --> Neonatal

den['adult_icu'] = np.where(den['first_careunit'].isin(['PICU', 'NICU']), 0, 1)
den['gender'] = np.where(den['gender']=="M", 1, 0)

# no need to yell
den.ethnicity = den.ethnicity.str.lower()
den.ethnicity.loc[(den.ethnicity.str.contains('^white'))] = 'white'
den.ethnicity.loc[(den.ethnicity.str.contains('^black'))] = 'black'
den.ethnicity.loc[(den.ethnicity.str.contains('^hisp')) | (den.ethnicity.str.contains('^latin'))] = 'hispanic'
den.ethnicity.loc[(den.ethnicity.str.contains('^asia'))] = 'asian'
den.ethnicity.loc[~(den.ethnicity.str.contains('|'.join(['white', 'black', 'hispanic', 'asian'])))] = 'other'

den = pd.concat([den, pd.get_dummies(den['ethnicity'], prefix='eth')], axis = 1)
den = pd.concat([den, pd.get_dummies(den['admission_type'], prefix='admType')], axis = 1)

den.drop(['diagnosis', 'hospstay_seq', 'los_icu','icustay_seq', 'admittime', 'dischtime','los_hospital', 'intime', 'outtime', 'ethnicity', 'admission_type', 'first_careunit'], axis = 1, inplace = True)

#========= 48 hour vitals query

# these are the normal ranges. useful to clean
# up the data

vitquery = \
"""
-- This query pivots the vital signs for the first 48 hours of a patient's stay
-- Vital signs include heart rate, blood pressure, respiration rate, and temperature
-- DROP MATERIALIZED VIEW IF EXISTS vitalsfirstday CASCADE;
-- create materialized view vitalsfirstday as
SELECT pvt.subject_id, pvt.hadm_id, pvt.icustay_id

-- Easier names
, min(case when VitalID = 1 then valuenum else null end) as HeartRate_Min
, max(case when VitalID = 1 then valuenum else null end) as HeartRate_Max
, avg(case when VitalID = 1 then valuenum else null end) as HeartRate_Mean
, min(case when VitalID = 2 then valuenum else null end) as SysBP_Min
, max(case when VitalID = 2 then valuenum else null end) as SysBP_Max
, avg(case when VitalID = 2 then valuenum else null end) as SysBP_Mean
, min(case when VitalID = 3 then valuenum else null end) as DiasBP_Min
, max(case when VitalID = 3 then valuenum else null end) as DiasBP_Max
, avg(case when VitalID = 3 then valuenum else null end) as DiasBP_Mean
, min(case when VitalID = 4 then valuenum else null end) as MeanBP_Min
, max(case when VitalID = 4 then valuenum else null end) as MeanBP_Max
, avg(case when VitalID = 4 then valuenum else null end) as MeanBP_Mean
, min(case when VitalID = 5 then valuenum else null end) as RespRate_Min
, max(case when VitalID = 5 then valuenum else null end) as RespRate_Max
, avg(case when VitalID = 5 then valuenum else null end) as RespRate_Mean
, min(case when VitalID = 6 then valuenum else null end) as TempC_Min
, max(case when VitalID = 6 then valuenum else null end) as TempC_Max
, avg(case when VitalID = 6 then valuenum else null end) as TempC_Mean
, min(case when VitalID = 7 then valuenum else null end) as SpO2_Min
, max(case when VitalID = 7 then valuenum else null end) as SpO2_Max
, avg(case when VitalID = 7 then valuenum else null end) as SpO2_Mean
, min(case when VitalID = 8 then valuenum else null end) as Glucose_Min
, max(case when VitalID = 8 then valuenum else null end) as Glucose_Max
, avg(case when VitalID = 8 then valuenum else null end) as Glucose_Mean

FROM  (
  select ie.subject_id, ie.hadm_id, ie.icustay_id
  , case
    when itemid in (211,220045) and valuenum > 0 and valuenum < 300 then 1 -- HeartRate
    when itemid in (51,442,455,6701,220179,220050) and valuenum > 0 and valuenum < 400 then 2 -- SysBP
    when itemid in (8368,8440,8441,8555,220180,220051) and valuenum > 0 and valuenum < 300 then 3 -- DiasBP
    when itemid in (456,52,6702,443,220052,220181,225312) and valuenum > 0 and valuenum < 300 then 4 -- MeanBP
    when itemid in (615,618,220210,224690) and valuenum > 0 and valuenum < 70 then 5 -- RespRate
    when itemid in (223761,678) and valuenum > 70 and valuenum < 120  then 6 -- TempF, converted to degC in valuenum call
    when itemid in (223762,676) and valuenum > 10 and valuenum < 50  then 6 -- TempC
    when itemid in (646,220277) and valuenum > 0 and valuenum <= 100 then 7 -- SpO2
    when itemid in (807,811,1529,3745,3744,225664,220621,226537) and valuenum > 0 then 8 -- Glucose

    else null end as VitalID
      -- convert F to C
  , case when itemid in (223761,678) then (valuenum-32)/1.8 else valuenum end as valuenum

  from icustays ie
  left join chartevents ce
  on ie.subject_id = ce.subject_id and ie.hadm_id = ce.hadm_id and ie.icustay_id = ce.icustay_id
  and ce.charttime between ie.intime and ie.intime + interval '48' hour
  -- exclude rows marked as error
  and ce.error IS DISTINCT FROM 1
  where ce.itemid in
  (
  -- HEART RATE
  211, --"Heart Rate"
  220045, --"Heart Rate"

  -- Systolic/diastolic

  51, --	Arterial BP [Systolic]
  442, --	Manual BP [Systolic]
  455, --	NBP [Systolic]
  6701, --	Arterial BP #2 [Systolic]
  220179, --	Non Invasive Blood Pressure systolic
  220050, --	Arterial Blood Pressure systolic

  8368, --	Arterial BP [Diastolic]
  8440, --	Manual BP [Diastolic]
  8441, --	NBP [Diastolic]
  8555, --	Arterial BP #2 [Diastolic]
  220180, --	Non Invasive Blood Pressure diastolic
  220051, --	Arterial Blood Pressure diastolic

  -- MEAN ARTERIAL PRESSURE
  456, --"NBP Mean"
  52, --"Arterial BP Mean"
  6702, --	Arterial BP Mean #2
  443, --	Manual BP Mean(calc)
  220052, --"Arterial Blood Pressure mean"
  220181, --"Non Invasive Blood Pressure mean"
  225312, --"ART BP mean"

  -- RESPIRATORY RATE
  618,--	Respiratory Rate
  615,--	Resp Rate (Total)
  220210,--	Respiratory Rate
  224690, --	Respiratory Rate (Total)

  -- SPO2, peripheral
  646, 220277,

  -- GLUCOSE, both lab and fingerstick
  807,--	Fingerstick Glucose
  811,--	Glucose (70-105)
  1529,--	Glucose
  3745,--	BloodGlucose
  3744,--	Blood Glucose
  225664,--	Glucose finger stick
  220621,--	Glucose (serum)
  226537,--	Glucose (whole blood)

  -- TEMPERATURE
  223762, -- "Temperature Celsius"
  676,	-- "Temperature C"
  223761, -- "Temperature Fahrenheit"
  678 --	"Temperature F"

  )
) pvt
group by pvt.subject_id, pvt.hadm_id, pvt.icustay_id
order by pvt.subject_id, pvt.hadm_id, pvt.icustay_id;
"""

vit48 = pd.read_sql_query(vitquery,con)
vit48.isnull().sum()

#===============48 hour labs query

# This query does the following:
#   it extracts the lab events in the first 48 hours
#   it labels the lab items and cleans up their values
#   it will create a set of lab values
#   48 hours.
labquery = \
"""
WITH pvt AS (
  --- ie is the icu stay
  --- ad is the admissions table
  --- le is the lab events table
  SELECT ie.subject_id, ie.hadm_id, ie.icustay_id, le.charttime
  -- here we assign labels to ITEMIDs
  -- this also fuses together multiple ITEMIDs containing the same data
  , CASE
        when le.itemid = 50868 then 'ANION GAP'
        when le.itemid = 50862 then 'ALBUMIN'
        when le.itemid = 50882 then 'BICARBONATE'
        when le.itemid = 50885 then 'BILIRUBIN'
        when le.itemid = 50912 then 'CREATININE'
        when le.itemid = 50806 then 'CHLORIDE'
        when le.itemid = 50902 then 'CHLORIDE'
        when le.itemid = 50809 then 'GLUCOSE'
        when le.itemid = 50931 then 'GLUCOSE'
        when le.itemid = 50810 then 'HEMATOCRIT'
        when le.itemid = 51221 then 'HEMATOCRIT'
        when le.itemid = 50811 then 'HEMOGLOBIN'
        when le.itemid = 51222 then 'HEMOGLOBIN'
        when le.itemid = 50813 then 'LACTATE'
        when le.itemid = 50960 then 'MAGNESIUM'
        when le.itemid = 50970 then 'PHOSPHATE'
        when le.itemid = 51265 then 'PLATELET'
        when le.itemid = 50822 then 'POTASSIUM'
        when le.itemid = 50971 then 'POTASSIUM'
        when le.itemid = 51275 then 'PTT'
        when le.itemid = 51237 then 'INR'
        when le.itemid = 51274 then 'PT'
        when le.itemid = 50824 then 'SODIUM'
        when le.itemid = 50983 then 'SODIUM'
        when le.itemid = 51006 then 'BUN'
        when le.itemid = 51300 then 'WBC'
        when le.itemid = 51301 then 'WBC'
      ELSE null
      END AS label
  , -- add in some sanity checks on the values
    -- the where clause below requires all valuenum to be > 0,
    -- so these are only upper limit checks
    CASE
      when le.itemid = 50862 and le.valuenum >    10 then null -- g/dL 'ALBUMIN'
      when le.itemid = 50868 and le.valuenum > 10000 then null -- mEq/L 'ANION GAP'
      when le.itemid = 50882 and le.valuenum > 10000 then null -- mEq/L 'BICARBONATE'
      when le.itemid = 50885 and le.valuenum >   150 then null -- mg/dL 'BILIRUBIN'
      when le.itemid = 50806 and le.valuenum > 10000 then null -- mEq/L 'CHLORIDE'
      when le.itemid = 50902 and le.valuenum > 10000 then null -- mEq/L 'CHLORIDE'
      when le.itemid = 50912 and le.valuenum >   150 then null -- mg/dL 'CREATININE'
      when le.itemid = 50809 and le.valuenum > 10000 then null -- mg/dL 'GLUCOSE'
      when le.itemid = 50931 and le.valuenum > 10000 then null -- mg/dL 'GLUCOSE'
      when le.itemid = 50810 and le.valuenum >   100 then null -- % 'HEMATOCRIT'
      when le.itemid = 51221 and le.valuenum >   100 then null -- % 'HEMATOCRIT'
      when le.itemid = 50811 and le.valuenum >    50 then null -- g/dL 'HEMOGLOBIN'
      when le.itemid = 51222 and le.valuenum >    50 then null -- g/dL 'HEMOGLOBIN'
      when le.itemid = 50813 and le.valuenum >    50 then null -- mmol/L 'LACTATE'
      when le.itemid = 50960 and le.valuenum >    60 then null -- mmol/L 'MAGNESIUM'
      when le.itemid = 50970 and le.valuenum >    60 then null -- mg/dL 'PHOSPHATE'
      when le.itemid = 51265 and le.valuenum > 10000 then null -- K/uL 'PLATELET'
      when le.itemid = 50822 and le.valuenum >    30 then null -- mEq/L 'POTASSIUM'
      when le.itemid = 50971 and le.valuenum >    30 then null -- mEq/L 'POTASSIUM'
      when le.itemid = 51275 and le.valuenum >   150 then null -- sec 'PTT'
      when le.itemid = 51237 and le.valuenum >    50 then null -- 'INR'
      when le.itemid = 51274 and le.valuenum >   150 then null -- sec 'PT'
      when le.itemid = 50824 and le.valuenum >   200 then null -- mEq/L == mmol/L 'SODIUM'
      when le.itemid = 50983 and le.valuenum >   200 then null -- mEq/L == mmol/L 'SODIUM'
      when le.itemid = 51006 and le.valuenum >   300 then null -- 'BUN'
      when le.itemid = 51300 and le.valuenum >  1000 then null -- 'WBC'
      when le.itemid = 51301 and le.valuenum >  1000 then null -- 'WBC'
    ELSE le.valuenum
    END AS valuenum
  FROM icustays ie

  LEFT JOIN labevents le
    ON le.subject_id = ie.subject_id
    AND le.hadm_id = ie.hadm_id
    -- TODO: they are using lab times 6 hours before the start of the
    -- ICU stay.
    AND le.charttime between (ie.intime - interval '6' hour)
    AND (ie.intime + interval '48' hour)
    AND le.itemid IN
    (
      -- comment is: LABEL | CATEGORY | FLUID | NUMBER OF ROWS IN LABEVENTS
      50868, -- ANION GAP | CHEMISTRY | BLOOD | 769895
      50862, -- ALBUMIN | CHEMISTRY | BLOOD | 146697
      50882, -- BICARBONATE | CHEMISTRY | BLOOD | 780733
      50885, -- BILIRUBIN, TOTAL | CHEMISTRY | BLOOD | 238277
      50912, -- CREATININE | CHEMISTRY | BLOOD | 797476
      50902, -- CHLORIDE | CHEMISTRY | BLOOD | 795568
      50806, -- CHLORIDE, WHOLE BLOOD | BLOOD GAS | BLOOD | 48187
      50931, -- GLUCOSE | CHEMISTRY | BLOOD | 748981
      50809, -- GLUCOSE | BLOOD GAS | BLOOD | 196734
      51221, -- HEMATOCRIT | HEMATOLOGY | BLOOD | 881846
      50810, -- HEMATOCRIT, CALCULATED | BLOOD GAS | BLOOD | 89715
      51222, -- HEMOGLOBIN | HEMATOLOGY | BLOOD | 752523
      50811, -- HEMOGLOBIN | BLOOD GAS | BLOOD | 89712
      50813, -- LACTATE | BLOOD GAS | BLOOD | 187124
      50960, -- MAGNESIUM | CHEMISTRY | BLOOD | 664191
      50970, -- PHOSPHATE | CHEMISTRY | BLOOD | 590524
      51265, -- PLATELET COUNT | HEMATOLOGY | BLOOD | 778444
      50971, -- POTASSIUM | CHEMISTRY | BLOOD | 845825
      50822, -- POTASSIUM, WHOLE BLOOD | BLOOD GAS | BLOOD | 192946
      51275, -- PTT | HEMATOLOGY | BLOOD | 474937
      51237, -- INR(PT) | HEMATOLOGY | BLOOD | 471183
      51274, -- PT | HEMATOLOGY | BLOOD | 469090
      50983, -- SODIUM | CHEMISTRY | BLOOD | 808489
      50824, -- SODIUM, WHOLE BLOOD | BLOOD GAS | BLOOD | 71503
      51006, -- UREA NITROGEN | CHEMISTRY | BLOOD | 791925
      51301, -- WHITE BLOOD CELLS | HEMATOLOGY | BLOOD | 753301
      51300  -- WBC COUNT | HEMATOLOGY | BLOOD | 2371
    )
    AND le.valuenum IS NOT null
    AND le.valuenum > 0 -- lab values cannot be 0 and cannot be negative

    LEFT JOIN admissions ad
    ON ie.subject_id = ad.subject_id
    AND ie.hadm_id = ad.hadm_id

),
ranked AS (
SELECT pvt.*, DENSE_RANK() OVER (PARTITION BY
    pvt.subject_id, pvt.hadm_id,pvt.icustay_id,pvt.label ORDER BY pvt.charttime) as drank
FROM pvt
)
SELECT r.subject_id, r.hadm_id, r.icustay_id
  , max(case when label = 'ANION GAP' then valuenum else null end) as ANIONGAP
  , max(case when label = 'ALBUMIN' then valuenum else null end) as ALBUMIN
  , max(case when label = 'BICARBONATE' then valuenum else null end) as BICARBONATE
  , max(case when label = 'BILIRUBIN' then valuenum else null end) as BILIRUBIN
  , max(case when label = 'CREATININE' then valuenum else null end) as CREATININE
  , max(case when label = 'CHLORIDE' then valuenum else null end) as CHLORIDE
  , max(case when label = 'GLUCOSE' then valuenum else null end) as GLUCOSE
  , max(case when label = 'HEMATOCRIT' then valuenum else null end) as HEMATOCRIT
  , max(case when label = 'HEMOGLOBIN' then valuenum else null end) as HEMOGLOBIN
  , max(case when label = 'LACTATE' then valuenum else null end) as LACTATE
  , max(case when label = 'MAGNESIUM' then valuenum else null end) as MAGNESIUM
  , max(case when label = 'PHOSPHATE' then valuenum else null end) as PHOSPHATE
  , max(case when label = 'PLATELET' then valuenum else null end) as PLATELET
  , max(case when label = 'POTASSIUM' then valuenum else null end) as POTASSIUM
  , max(case when label = 'PTT' then valuenum else null end) as PTT
  , max(case when label = 'INR' then valuenum else null end) as INR
  , max(case when label = 'PT' then valuenum else null end) as PT
  , max(case when label = 'SODIUM' then valuenum else null end) as SODIUM
  , max(case when label = 'BUN' then valuenum else null end) as BUN
  , max(case when label = 'WBC' then valuenum else null end) as WBC

FROM ranked r
WHERE r.drank = 1
GROUP BY r.subject_id, r.hadm_id, r.icustay_id,  r.drank
ORDER BY r.subject_id, r.hadm_id, r.icustay_id,  r.drank;
"""

lab48 = pd.read_sql_query(labquery,con)

#=========notes
notesquery = \
"""
SELECT fin.subject_id, fin.hadm_id, fin.icustay_id, string_agg(fin.text, ' ') as chartext
FROM (
  select ie.subject_id, ie.hadm_id, ie.icustay_id, ne.text
  from icustays ie
  left join noteevents ne
  on ie.subject_id = ne.subject_id and ie.hadm_id = ne.hadm_id
  and ne.charttime between ie.intime and ie.intime + interval '48' hour
  --and ne.iserror != '1'
) fin
group by fin.subject_id, fin.hadm_id, fin.icustay_id
order by fin.subject_id, fin.hadm_id, fin.icustay_id;
"""

notes48 = pd.read_sql_query(notesquery,con)

#=====combine all variables
mort_ds = den.merge(vit48,how = 'left',    on = ['subject_id', 'hadm_id', 'icustay_id'])
mort_ds = mort_ds.merge(lab48,how = 'left',    on = ['subject_id', 'hadm_id', 'icustay_id'])

#======missing values (following joydeep ghosh's paper)

# create means by age group and gender
mort_ds['age_group'] = pd.cut(mort_ds['age'], [-1,5,10,15,20, 25, 40,60, 80, 200],
   labels = ['l5','5_10', '10_15', '15_20', '20_25', '25_40', '40_60',  '60_80', '80p'])

mort_ds = mort_ds.groupby(['age_group', 'gender'])
mort_ds = mort_ds.transform(replace)
#mort_ds.drop('age_group', 1, inplace =True )

# one missing variable
adult_icu = mort_ds[(mort_ds.adult_icu==1)].dropna()
# create training and testing labels
msk = np.random.rand(len(adult_icu)) < 0.7
adult_icu['train'] = np.where(msk, 1, 0)
adult_icu.to_csv(os.path.join(mimicdir, 'adult_icu.gz'), compression='gzip',  index = False)

# notes
adult_notes = notes48.merge(adult_icu[['train', 'subject_id', 'hadm_id', 'icustay_id', 'mort_icu']], how = 'right', on = ['subject_id', 'hadm_id', 'icustay_id'])
adult_notes.to_csv(os.path.join(mimicdir, 'adult_notes.gz'), compression='gzip',  index = False)

max_issues_repo_name: MDenu/HST-homework

max_forks_repo_name: MDenu/HST-homework


text:
# Copyright 2020 Jérémie Donà, Jean-Yves Franceschi, Patrick Gallinari, Sylvain Lamprier

# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at

#     http://www.apache.org/licenses/LICENSE-2.0

# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import argparse
import os

import numpy as np

if __name__ == "__main__":
    parser = argparse.ArgumentParser(
        prog='Choice of sample pixels for the WaveEq-100 dataset.',
        description='Generates the pixels used for the WaveEqPartial (WaveEq-100 if 100 pixels are drawn) dataset. \
                     Chosen coordinates are save in an npz file, in `rand_w` and `rand_h` fields.',
        formatter_class=argparse.ArgumentDefaultsHelpFormatter
    )
    parser.add_argument('--data_dir', type=str, metavar='DIR', required=True,
                        help='Folder where the data will be saved.')
    parser.add_argument('--number', type=int, metavar='NUM', default=100,
                        help='Number of pixels to generate.')
    parser.add_argument('--frame_size', type=int, metavar='SIZE', default=64,
                        help='Size of frames (bound on pixel values).')
    parser.add_argument('--seed', type=int, metavar='SEED', default=42,
                        help='Fixed NumPy seed to produce the same dataset at each run.')
    args = parser.parse_args()

    # Fix random seed
    np.random.seed(args.seed)

    # Create the directory if needed
    data_dir = os.path.join(args.data_dir, 'pixels')
    if not os.path.isdir(data_dir):
        os.makedirs(data_dir)

    # Generate pixel coordinates
    rand_w = np.random.randint(args.frame_size, size=args.number)
    rand_h = np.random.randint(args.frame_size, size=args.number)

    # Save coordinates
    np.savez_compressed(os.path.join(data_dir, 'pixels.npz'), rand_w=rand_w, rand_h=rand_h)

reason: import numpy


text:
import pandas as pd
import numpy as np
from datetime import datetime

# ~------------------ RESPONSE DATA ------------------~

def process_response(response, kw, ranking, geo):
    """ Utility function for create_response_df() """
    try:
        df = response[kw][ranking]
        df[['keyword', 'ranking', 'geo', 'query_timestamp']] = [
            kw, ranking, geo, datetime.now()]
    except:
        print(f"Append empty dataframe for {ranking}: {kw}")
        return pd.DataFrame(columns=['query', 'value', 'keyword', 'ranking', 'geo', 'query_timestamp'])

    return df

def create_response_df(response, geo='global'):
    """ Unpack response and create one dataframe for each ranking and each keyword """
    assert isinstance(
        response, dict), "Empty response, caught in transform.py. Try again."

    ranking = [*response[[*response][0]]]
    keywords = [*response]

    df_list = []
    for r in ranking:
        for kw in keywords:
            df_list.append(process_response(
                response, kw=kw, ranking=r, geo=geo))

    return pd.concat(df_list)

def clean_data(df, blacklist):
    """ Cleans the data
            1. drops non-english strings
            2. removes entries from blacklist
            3. reset index

    Args
        df: pd.dataframe,
        blacklist: list, contains keywords that should be removed

    Return
        dataframe
    """
    # remove non-ascii strings: select rows where string has ascii format
    df_en = df.loc[df['query'].apply(lambda x: x.isascii()), :]

    # remove blacklisted words
    df_clean = df_en.loc[~df_en['query'].str.contains('|'.join(blacklist)), :]

    df = df_clean.reset_index(drop=True)

    return df

# ~------------------ PLOT DATA ------------------~

def add_features(df):
    """ Create normalized values for even display """

    assert set(["query", "value", "keyword", "ranking", "query_timestamp", "geo"]).issubset(df.columns), "Add features failed. \
    Missing one of [query, value, keyword, ranking, query_timestamp, geo]"

    # feature engineering: totals and normalize
    grouped = df.groupby(['ranking']).value  # group values by ranking
    df['value_total'] = grouped.transform('sum')  # total sum
    df['value_normalized'] = ((df.value - grouped.transform('min')) / (
        grouped.transform('max') - grouped.transform('min'))).astype(float)
    df['value_normalized_total'] = df.groupby(
        ['ranking']).value_normalized.transform('sum')  # total sum of normalized values
    df['date'] = pd.to_datetime(df.query_timestamp).dt.strftime("%d. %B %Y")

    return df

def select_topn(df, top_n):
    """ Select top-n keywords for each ranking ordered by value """
    assert df.columns.str.contains("ranking").any(
    ), "select_topn failed. Missing 'ranking' column."

    df = df.reset_index(drop=True)
    df.value = pd.to_numeric(df.value, errors='coerce')  # avoid object dtype
    topn_idx = df.groupby("ranking")['value'].nlargest(
        top_n).droplevel(0).index

    return df.loc[topn_idx, :]

def sanitize_labels(df, to_uppercase):
    """ Insert linebreaks and create headings """
    # make some labels uppercase
    if to_uppercase:
        for s in to_uppercase:
            df['query'] = df['query'].str.replace(s.lower(), s)
    # create labels
    df['labels'] = df['query'].apply(
        lambda x: x.replace(' ', '<br>'))  # linebreaks
    df['ranking_label'] = df.ranking.replace({'top': f'Evergreens - updated {df.date.to_list()[0]}',
                                              'rising': f'Trending - updated {df.date.to_list()[0]}'})

    return df

def plot_data(df, to_uppercase, top_n=35):
    """ Return 2 dataframes: Newcomer ("rising") and top charts ("top") """
    df = (df.pipe(select_topn, top_n=top_n)
            .pipe(add_features)
            .pipe(sanitize_labels, to_uppercase=to_uppercase)
          )

    # rankings: top and rising
    return df.query('ranking == "rising"'), df.query('ranking == "top"')


text:
from __future__ import division
from __future__ import print_function

import time
import tensorflow as tf

from gcn.utils import *
from scipy import sparse
from gcn.models import GCN, MLP

# Set random seed
# seed = 3
# np.random.seed(seed)
# tf.set_random_seed(seed)

# Settings
flags = tf.app.flags
FLAGS = flags.FLAGS
flags.DEFINE_string('dataset', 'cora', 'Dataset string.')  # 'cora', 'citeseer', 'pubmed'
flags.DEFINE_string('model', 'gcn', 'Model string.')  # 'gcn', 'gcn_cheby', 'dense'
flags.DEFINE_float('learning_rate', 0.01, 'Initial learning rate.')
flags.DEFINE_integer('epochs', 200, 'Number of epochs to train.')
flags.DEFINE_integer('hidden1', 16, 'Number of units in hidden layer 1.')
flags.DEFINE_float('dropout', 0.5, 'Dropout rate (1 - keep probability).')
flags.DEFINE_float('weight_decay', 5e-4, 'Weight for L2 loss on embedding matrix.')
flags.DEFINE_integer('early_stopping', 10, 'Tolerance for early stopping (# of epochs).')
flags.DEFINE_integer('max_degree', 3, 'Maximum Chebyshev polynomial degree.')

all_p_acc = []
all_q_acc = []
for run in range(10):
    print("-----------------Running on #{} of {} dataset------------------".format(run, FLAGS.dataset))
    total_p_acc = []
    total_q_acc = []
    # Load data
    adj, adj_pa, fea, y_train, y_val, y_test, train_mask, val_mask, test_mask = load_data(FLAGS.dataset, run)
    # adj is sparse matrix
    # print("train_mask",len(train_mask))
    # print("true mast", len([e for e in train_mask if e == True]))
    #TODO add self-loop in adj, self-loop may has different value rather than 1
    dense_adj = np.array(adj.todense())
    dense_adj_pa = np.array(adj_pa.todense())
    dense_adj_ch = np.array(dense_adj - dense_adj_pa)
    directed_adj = adj_pa.todense()
    size = dense_adj_pa.shape[0]
    for i in range(size):
        directed_adj[i,i] = 1
    sparse_adj = sparse.csr_matrix(directed_adj)
    directed_adj = sparse_to_tuple(sparse_adj)
    # directed_adj = sparse_to_tuple(adj_pa)

    # Some preprocessing
    dense_features = np.array(fea.todense())
    features = preprocess_features(fea)

    for seed in range(110,120):
        # Set random seed
        np.random.seed(seed)
        tf.set_random_seed(seed)

        if FLAGS.model == 'gcn':
            support = [preprocess_adj(adj)]
            num_supports = 1
            model_func = GCN
        elif FLAGS.model == 'gcn_cheby':
            support = chebyshev_polynomials(adj, FLAGS.max_degree)
            num_supports = 1 + FLAGS.max_degree
            model_func = GCN
        elif FLAGS.model == 'dense':
            support = [preprocess_adj(adj)]  # Not used
            num_supports = 1
            model_func = MLP
        else:
            raise ValueError('Invalid argument for model: ' + str(FLAGS.model))

        # Define placeholders
        placeholders = {
            'support': [tf.sparse_placeholder(tf.float32) for _ in range(num_supports)],
            'features': tf.sparse_placeholder(tf.float32, shape=tf.constant(features[2], dtype=tf.int64)),
            'dense_features': tf.placeholder(tf.float32),
            # 'directed_adj': tf.placeholder(tf.float32),
            'directed_adj': tf.sparse_placeholder(tf.float32),
            'labels': tf.placeholder(tf.float32, shape=(None, y_train.shape[1])),
            'labels_mask': tf.placeholder(tf.int32),
            'dropout': tf.placeholder_with_default(0., shape=()),
            'num_features_nonzero': tf.placeholder(tf.int32)  # helper variable for sparse dropout
        }

        # Create model
        model = model_func(placeholders, input_dim=features[2][1], logging=True)

        session_conf = tf.ConfigProto(allow_soft_placement=True)

        # Initialize session
        sess = tf.Session(config=session_conf)

        # Define model evaluation function
        def evaluate(directed_adj, features, dense_features , support, labels, mask, placeholders):
            t_test = time.time()
            feed_dict_val = construct_feed_dict(directed_adj,
                                                features,
                                                dense_features,
                                                support, labels,
                                                mask,
                                                placeholders)
            outs_val = sess.run([model.loss, model.accuracy], feed_dict=feed_dict_val)
            return outs_val[0], outs_val[1], (time.time() - t_test)

        def get_pi(cur_iter, params=None, pi=None):
            """exponential decay: pi_t = max{1-k^t,lb}"""
            k,lb = params[0], params[1]
            pi = 1.0 - max([k**cur_iter,lb])
            return pi
        # Init variables
        sess.run(tf.global_variables_initializer())

        cost_val = []

        # Train model
        for epoch in range(FLAGS.epochs):
            t = time.time()
            pi = get_pi(cur_iter=epoch*1.0/FLAGS.epochs, params=[0.2,0.0])
            # pi = 0.5
            model.set_pi(pi)
            # Construct feed dictionary
            feed_dict = construct_feed_dict(directed_adj,
                                            features,
                                            dense_features,
                                            support,
                                            y_train,
                                            train_mask,
                                            placeholders)
            feed_dict.update({placeholders['dropout']: FLAGS.dropout})

            # Training step
            #TODO add logic rule in the model.
            outs = sess.run([model.opt_op, model.loss, model.accuracy], feed_dict=feed_dict)

            # Validation
            cost, acc, duration = evaluate(directed_adj, features,
                                           dense_features, support,
                                           y_val, val_mask, placeholders)
            cost_val.append(cost)

            # Print results
            # print("Epoch:", '%04d' % (epoch + 1),
            #       "pi=", "{:.5f}".format(pi),
            #       "train_loss=", "{:.5f}".format(outs[1]),
            #       "[p] train_acc=", "{:.5f}".format(outs[2][0]),
            #       "[q] train_acc=", "{:.5f}".format(outs[2][1]),
            #       "val_loss=", "{:.5f}".format(cost),
            #       "[p] val_acc=", "{:.5f}".format(acc[0]),
            #       "[q] val_acc=", "{:.5f}".format(acc[1]),
            #       "time=", "{:.5f}".format(time.time() - t))

            # test_cost, test_acc, test_duration = evaluate(directed_adj, features, support, y_test, test_mask, placeholders)
            # print("Test set results:", "cost=", "{:.5f}".format(test_cost),
            #       "[p] accuracy=", "{:.5f}".format(test_acc[0]),
            #       "[q] accuracy=", "{:.5f}".format(test_acc[1]),
            #       "time=", "{:.5f}".format(test_duration))

            if epoch > FLAGS.early_stopping and cost_val[-1] > np.mean(cost_val[-(FLAGS.early_stopping+1):-1]):
                print("Early stopping...")
                break

        # print("Optimization Finished!")

        # Testing
        test_cost, test_acc, test_duration = evaluate(directed_adj, features,
                                                      dense_features, support,
                                                      y_test, test_mask, placeholders)
        all_p_acc.append(test_acc[0])
        all_q_acc.append(test_acc[1])
        total_p_acc.append(test_acc[0])
        total_q_acc.append(test_acc[1])
        print("[#{}] Test set results:".format(seed), "cost=", "{:.5f}".format(test_cost),
              "[p] accuracy=", "{:.5f}".format(test_acc[0]),
              "[q] accuracy=", "{:.5f}".format(test_acc[1]),
              "time=", "{:.5f}".format(test_duration))
    print("Run #{} Average Test Accuracy [p]: {:.5f}, [q]: {:.5f} \n".format(run,np.mean(total_p_acc), np.mean(total_q_acc)))

print("Average Test Accuracy [p]: {:.5f}, [q]: {:.5f} \n".format(np.mean(all_p_acc), np.mean(all_q_acc)))

reason: from scipy


text:
try:
    from cv2 import cv2
except:
    import cv2
import numpy as np

def get_corner_points_of_largest_contour(processed_sudoku_board):
    largest_contour = __get_largest_contour(img=processed_sudoku_board)
    quadrangle = largest_contour

    # We will loop through all coordinates and calculate the expressions above and save the result in the variable evals
    evals = np.zeros([3, len(quadrangle)])
    for index, coordinates in enumerate(quadrangle):
        coordinates = coordinates[0]
        # To find upper left, lower right
        evals[0, index] = sum(coordinates)
        # To find upper right
        evals[1, index] = coordinates[0] - coordinates[1]
        # To find lower right
        evals[2, index] = coordinates[1] - coordinates[0]
    upper_left = quadrangle[np.argmin(evals, axis=1)[0]][0]
    lower_right = quadrangle[np.argmax(evals, axis=1)[0]][0]
    upper_right = quadrangle[np.argmax(evals, axis=1)[1]][0]
    lower_left = quadrangle[np.argmax(evals, axis=1)[2]][0]
    return np.array([upper_left, upper_right, lower_right, lower_left])

def crop_and_reshape(original_img, quadrangle):
    # Get coordinates of the square in which the rectangular section should be cropped and warped into.
    destination = __get_dst(quadrangle)
    side_length = np.ceil(__get_distance(destination[0], destination[1]))

    # Gets the transformation matrix for skewing the image to fit a square
    source = np.array(quadrangle, dtype='float32')  # Necessary to explicitly specify the data type to avoid error
    transformation_matrix = cv2.getPerspectiveTransform(source, destination)

    # Performs the transformation on the original image
    return cv2.warpPerspective(original_img, transformation_matrix, (int(side_length), int(side_length)))

def __get_distance(p1, p2):
    difference = np.array([p2[i] - p1[i] for i in range(len(p1))])
    euclidean_distance = np.sqrt(sum(difference ** 2))
    return euclidean_distance

def __get_dst(quadrangle):
    upper_left, upper_right, lower_right, lower_left = [item for item in quadrangle]
    smallest_side = min([
        __get_distance(upper_left, upper_right),
        __get_distance(upper_right, lower_right),
        __get_distance(lower_right, lower_left),
        __get_distance(lower_left, upper_left)
    ])
    return np.array([[0, 0], [smallest_side, 0], [smallest_side, smallest_side], [0, smallest_side]],
                    dtype='float32')

def __get_largest_contour(img):
    contours, hierarchy = cv2.findContours(img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    # Sort the contours by area in the descending order.
    contours = sorted(contours, key=cv2.contourArea, reverse=True)
    return contours[0]

max_stars_repo_name: snehsagarajput/sudoku-solver-app

max_issues_repo_name: snehsagarajput/sudoku-solver-app

max_forks_repo_name: snehsagarajput/sudoku-solver-app


text:
import os
import sys

import numpy as np
import networkx as nx

import graph_partitioning.partitioners.utils as putils
import graph_partitioning.partitioners.scotch.scotch as scotch
import graph_partitioning.partitioners.scotch.scotch_data as sdata

class ScotchPartitioner():

    def __init__(self, lib_path, virtualNodesEnabled = False):
        self.SCOTCH_LIB_PATH = lib_path
        self.virtualNodesEnabled = virtualNodesEnabled
        self.partitionStrategy = 'quality'

    def _generate_prediction_model(self,
                                  graph,
                                  num_iterations,
                                  num_partitions,
                                  assignments,
                                  fixed):
        # STEP 0: sort the graph nodes
        sortedNodes = sorted(graph.nodes())

        # STEP 1: create a mapping of nodes for relabeling
        nodeMapping = {}
        for newID, nodeID in enumerate(sortedNodes):
            # old label as key, new label as value
            nodeMapping[nodeID] = newID

        #print(nodeMapping)

        # Create a new graph with the new mapping
        G = nx.relabel_nodes(graph, nodeMapping, copy=True)

        # Copy over the node and edge weightings: double check this
        for node in sortedNodes:
            newNode = nodeMapping[node]
            try:
                G.node[newNode]['weight'] = graph.node[node]['weight']

                for edge in graph.neighbors(node):
                    newEdge = nodeMapping[edge]
                    try:
                        G.edge[newNode][newEdge]['weight'] = graph.edge[node][edge]['weight']
                    except Exception as err:
                        pass
            except Exception as err:
                pass

        # Determine assignments
        scotch_assignments = np.full(G.number_of_nodes(), -1)
        for nodeID, assignment in enumerate(assignments):
            if nodeID in nodeMapping:
                # this nodeID is part of the mapping
                newNodeID = nodeMapping[nodeID]
                if fixed[nodeID] == 1:
                    scotch_assignments[newNodeID] = assignment

        #print('G.nodes', G.nodes())
        #print('scotch_assignments', scotch_assignments)

        # SCOTCH algorithm
        # Load the graph into the SCOTCH array structures
        scotchArrays = sdata.ScotchData()
        scotchArrays.fromNetworkxGraph(G, parttab=scotch_assignments, baseval=0)

        #scotchArrays.debugPrint()

        # create instance of SCOTCH Library
        mapper = scotch.Scotch(self.SCOTCH_LIB_PATH)

        # set the mapper parameters
        mapper.kbalval = 0.01
        mapper.numPartitions = num_partitions

        ok = mapper.initialize(scotchArrays, verbose=False)
        if ok:
            # we can proceed with graphMap
            print('gmf')
            ok = mapper.graphMapFixed()
            print('gmfend')
            if ok:
                scotch_assignments = mapper.scotchData._parttab
                # update assignments
                for oldNode in list(nodeMapping.keys()):
                    newNode = nodeMapping[oldNode]
                    assignments[oldNode] = scotch_assignments[newNode]
                print('returning')
                return assignments
            else:
                print('Error while running graphMap()')
        else:
            print('Error while setting up SCOTCH for partitioning.')

    def generate_prediction_model(self,
                                  graph,
                                  num_iterations,
                                  num_partitions,
                                  assignments,
                                  fixed):
        # STEP 0: sort the graph nodes
        gSortedNodes = sorted(graph.nodes())

        # STEP 1: map between graph nodes and SCOTCH nodes
        # create a mapping between the graph node ids and those used by SCOTCH
        # ensures that nodes are numbered from 0...n-1 for SCOTCH especially when some nodes in graph have been fixed
        node_indeces = self._createGraphIndeces(gSortedNodes, len(assignments))

        # generate a new graph that only has the new nodes
        G = nx.Graph()
        for node in gSortedNodes:
            # set the new node index used by scotch
            G.add_node(node_indeces[node])
            try:
                # set the node weight
                G.node[node_indeces[node]]['weight'] = graph.node[node]['weight']
            except Exception as err:
                pass

        # STEP 2: add virtual nodes, if enabled and required
        # if there are edgeless nodes, then we need virtual nodes - this may actually not be needed
        requires_virtual = self._requiresVirtualNodes(graph)
        virtual_nodes = []
        if requires_virtual:
            # add virtual nodes to the new graph G
            virtual_nodes = self._createVirtualNodes(G, num_partitions)

        # STEP 3: add edges & weights using the new ID mapping
        # add the edges for each node using the new ids
        for node in gSortedNodes:
            newNodeID = node_indeces[node]
            for edge in graph.neighbors(node):
                newEdgeID = node_indeces[edge]
                G.add_edge(newNodeID, newEdgeID)
                try:
                    weight = graph.edge[node][edge]['weight']
                    G.edge[newNodeID][newEdgeID]['weight'] = weight
                except Exception as err:
                    pass

        # STEP 4: add virtual edges where needed
        virtual_edges = {}
        if requires_virtual:
            virtual_edges = self._virtualEdges(graph, assignments, num_partitions, virtual_nodes)
            for key in list(virtual_edges.keys()):
                newID = node_indeces[key]
                G.add_edge(newID, virtual_edges[key])

        # determine the nodes that are already assigned to their respective partition
        scotch_assignments = []
        for nodeID, assignment in enumerate(assignments):
            if node_indeces[nodeID] >= 0:
                # this nodeID is part of this graph and needs to be partitioned
                # add node's fixed partition, if present
                scotch_assignments.append(assignment)

        #print('lenass', len(scotch_assignments), G.number_of_nodes())
        #print('assignments', assignments)
        # add virtual nodes to assignments
        if requires_virtual:
            for i in range(0, num_partitions):
                scotch_assignments.append(i)

        #node_weights = {n[0]: n[1]['weight'] for n in G.nodes_iter(data=True)}
        #print('scotchnw', node_weights)

        # SCOTCH algorithm
        # Load the graph into the SCOTCH array structures
        scotchArrays = sdata.ScotchData()
        scotchArrays.fromNetworkxGraph(G, parttab=scotch_assignments, baseval=0)

        #scotchArrays.debugPrint()

        # create instance of SCOTCH Library
        mapper = scotch.Scotch(self.SCOTCH_LIB_PATH)

        # set the mapper parameters
        mapper.kbalval = 0.00
        mapper.numPartitions = num_partitions
        mapper.strategyFlag = scotch.strategyFlag(self.partitionStrategy)

        ok = mapper.initialize(scotchArrays, verbose=False)
        if ok:
            # we can proceed with graphMap
            #print('pre_partitioned_Ass', mapper.scotchData._parttab)
            #print('edgewhts', mapper.scotchData._edlotab)
            ok = mapper.graphMapFixed()
            if ok:
                #print('partitioned_Ass', mapper.scotchData._parttab)
                scotch_assignments = mapper.scotchData._parttab
                if requires_virtual:
                    #print('requires_virtual')
                    # remove the virtual nodes from assignments
                    for virtualN in virtual_nodes:
                        G.remove_node(virtualN)

                # update assignments
                for oldNode, newNode in enumerate(node_indeces):
                    if(newNode >= 0):
                        #aold = assignments[oldNode]
                        assignments[oldNode] = scotch_assignments[newNode]
                        #print(oldNode, newNode, aold, scotch_assignments[newNode], assignments[oldNode])
                return assignments
            else:
                print('Error while running graphMap()')
        else:
            print('Error while setting up SCOTCH for partitioning.')

    def _createGraphIndeces(self, graphNodes, originalNodeNum):
        '''
            indeces[old_node_id] = new_node_id
        '''
        indeces = np.repeat(-1, originalNodeNum)
        nodeCount = 0
        for node in graphNodes:
            indeces[node] = nodeCount
            nodeCount += 1
        return indeces

    def _requiresVirtualNodes(self, graph):
        return False
        if (self.virtualNodesEnabled == False):
            # we don't allow virtual nodes
            return False

        for node in graph.nodes():
            if len(graph.neighbors(node)) == 0:
                #print(node, 'has no neighbors')
                return True
        return False

    def _createVirtualNodes(self, graph, num_partitions):
        virtual_nodes = []
        for i in range(0, num_partitions):
            virtualNode = graph.number_of_nodes()
            graph.add_node(virtualNode)
            virtual_nodes.append(virtualNode)
        return virtual_nodes

    def _virtualEdges(self, graph, assignments, num_partitions, virtual_nodes):
        virtual_edges = {}
        tmp, partitions = putils.minPartitionCounts(assignments, num_partitions)
        for node in graph.nodes():
            if len(graph.neighbors(node)) == 0:
                #print(node, ' has no neighbors')
                # this node has no neighbors, choose a node in a partition
                #partition, partitions = putils.minPartitionCounts(assignments, num_partitions)

                #print('partitions', partitions)
                minPart = 1000000
                _partition = -1
                for partition in partitions:
                    if partitions[partition] == 0:
                        # pick this
                        _partition = partition
                        #partitions[partition] += 1
                        break
                    elif partitions[partition] < minPart:
                        minPart = partitions[partition]
                        #partitions[partition] += 1
                        _partition = partition
                partitions[_partition] += 1
                virtualNode = virtual_nodes[_partition]

                #graph.add_edge(virtualNode, node)
                virtual_edges[node] = virtualNode
        return virtual_edges

reason: import numpy,import networkx


text:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Wed Jun 27 09:20:01 2018

@authors: Dan Wendling

Last modified: 2020-02-19

------------------------------------------
 ** Semantic Search Analysis: Start-up **
------------------------------------------

This script: A tool for collecting the type of "training data" that
machine learning requires to make this process more automated. This is the
best way (so far) to classify the many ways your customers search for your
products and product-related terminology, etc.

The script puts your highest frequency terms into buckets/clusters, so
you can use Excel to add 2 levels of aggregation, to match what the UMLS
terminologies are assigning: Preferred Term (preferred version of the term) and
Semantic Type (MID-LEVEL description).

Build a list of terms SPECIFIC TO YOUR SITE, which would be handled poorly by
the processes in later scripts:

1. Your "brands" - Programs, product and service names, in the forms that
    people search for them
2. Person names, whether staff, authors, historical figures, fictional
    characters, etc.
3. Anything else you don't want the later scripts to tag. For example, if
    your organization is using a generic word as an acronym, you probably
    want these occurrences tagged as your product, rather than the generic
    term.

You can re-run the fuzzy-match process until you believe you have categorized
what you need. Over time this will lighten the manual work in later steps with
more accurate assignments and machine learning.

INPUTS:
- data/raw/SearchConsole.csv
- data/raw/SiteSearch.csv

OUTPUTS:
- data/matchFiles/ClusterResults.xlsx

--------------------------------
HOW TO EXPORT SEARCH QUERY DATA
--------------------------------
Script assumes Google Analytics where search logging has been configured. Can
be adapted for other tools.

    1. Go to Acquisition > Search Console > Queries
    2. Set date parameters (Consider 12 months)
    3. Select Export > Unsampled Report as SearchConsole.csv
    4. Copy the result to data/raw folder
    5. Do the same from Behavior > Site Search > Search Terms with file name
        SiteSearch.csv

(You could also use the separate Google Search Console interface, but this
requires more configuration than is covered here.)

----------------
SCRIPT CONTENTS
----------------
1. Start-up / What to put into place, where
2. Create match list, update columns and rows
3. Create buckets of similar character strings
4. Build your custom terminology in Excel
5. Go on to Phase 1; re-run this script later as needed

"""

#%%
# ============================================
# 1. Start-up / What to put into place, where
# ============================================
'''
File locations, etc.
'''

import pandas as pd
import numpy as np
import os
import re
import string
from fuzzywuzzy import fuzz
from fuzzywuzzy import process
import collections
import copy

from pathlib import *
# To be used with str(Path.home())

# Set working directory and directories for read/write
home_folder = str(Path.home()) # os.path.expanduser('~')
os.chdir(home_folder + '/Projects/classifysearches')

SearchConsoleRaw = 'data/raw/SearchConsole.csv' # Put log here before running script
SiteSearchRaw = 'data/raw/SiteSearch.csv' # Put log here before running script

#%%
# ==============================================
# 2. Create match list, update columns and rows
# ==============================================
'''
Default for pilot site, after eyeballing the data, was:
    - SearchConsole: Let's process the top 80% of search terms used
    - SiteSearch: Let's process

Reset the number of terms you want to process based on:
    - Quality of the buckets you're getting below
    - Your available time
    - Percentage of your search traffic you you think is important to cover

Incorporating too many low-frequency searches too soon can waste your time
by reducing the quality of your bucket content.

You could process the terms separately or together.

The pilot site has relatively few organization-specific terms, and the top 40%
of terms by search frequency = 70,000 terms. We decided it would be easier to
only match to our SearchConsole terms, and catch the rest after the generic
terms have been matched by the UMLS vocabularies. This may not be true for
other sites.
'''

# --------------
# SearchConsole
# --------------
'''
Script is expecting:

| Search Query     | Clicks | Impressions | CTR  | Average Position |
| hippocratic oath | 1037   | 19603       | 0.05 | 4.1              |
'''

SearchConsole = pd.read_csv(SearchConsoleRaw, sep=',', index_col=False) # skiprows=7,
SearchConsole.columns
'''
'Search Query', 'Clicks', 'Impressions', 'CTR', 'Average Position'
'''

# Reduce and rename
SearchConsole = SearchConsole[['Search Query', 'Clicks']]
SearchConsole.rename(columns={'Search Query': 'Query'}, inplace=True)

# Total queries represented in file
SearchConsoleTotCnt = SearchConsole['Clicks'].sum()

# Derive cumulative percentage by row; drop terms of lower search frequency
# Pilot site favors looking at the top 80 percent of terms used in the past year,
# Which is around 1100 terms
SearchConsole['CumulativeTotal'] = SearchConsole['Clicks'].cumsum()
SearchConsole['CumulativePercent'] = 100*SearchConsole['CumulativeTotal'] / SearchConsoleTotCnt
# Drop rows of lower frequency
SearchConsole = SearchConsole.loc[(SearchConsole['CumulativePercent'] < 81)]

# Only need 1 col
SearchConsoleResult = SearchConsole[['Query']]

# -----------
# SiteSearch
# -----------
'''
Not used as described at top of this section.
'''

SiteSearch = pd.read_csv(SiteSearchRaw, sep=',', index_col=False) # skiprows=7,
SiteSearch.columns
'''
'Search Term', 'Total Unique Searches', 'Results Pageviews / Search',
       '% Search Exits', '% Search Refinements', 'Time after Search',
       'Avg. Search Depth'
'''

# listToCheck = SiteSearch.iloc[0:1000]

# Reduce and rename
SiteSearch = SiteSearch[['Search Term', 'Total Unique Searches']]
SiteSearch.rename(columns={'Search Term': 'Query', 'Total Unique Searches': 'SearchCnt'}, inplace=True)

# Total queries represented in file
SiteSearchTotCnt = SiteSearch['SearchCnt'].sum()

# Derive cumulative percentage by row; drop terms of lower search frequency
# Pilot site favors looking at the top 80 percent of terms used in the past year,
# Which is around 1100 terms
SiteSearch['CumulativeTotal'] = SiteSearch['SearchCnt'].cumsum()
SiteSearch['CumulativePercent'] = 100*SiteSearch['CumulativeTotal'] / SiteSearchTotCnt
# Drop rows of lower frequency
SiteSearch = SiteSearch.loc[(SiteSearch['CumulativePercent'] < 41)]

# Only need 1 col
SiteSearchResult = SiteSearch[['Query']]

# Concat if needed / rename
# query_df = SearchConsoleResult.append(SiteSearchResult, sort=False)
query_df = SearchConsoleResult

#%%

# Remove unneeded before intensive processing
del [[SiteSearch, SearchConsole, SiteSearchResult, SearchConsoleResult]] # listToCheck

#%%
# ===============================================
# 3. Create buckets of similar character strings
# ===============================================
'''
FuzzyWuzzy aggregates frequently occurring terms and puts them into buckets.
Change the commented numbers based on the quality of the response you are getting.
Depends on how people are searching your site, how many products you have, etc.
For the pilot site we started with 10 buckets; later with 5 buckets, one bucket
would be great and the others not useful at all.

Most of this is adjustable; see:
- https://github.com/seatgeek/fuzzywuzzy (creator site)
- https://www.neudesic.com/blog/fuzzywuzzy-using-python/
- https://www.datacamp.com/community/tutorials/fuzzy-string-python

This script uses "fuzz.ratio."

NOTE: The dataframe index must be sequential from zero or the code will break.

query_df = query_df.iloc[0:1000]
query_df = query_df.loc[(query_df['TotalSearchFreq'] > 5)]

Score of ~70, for pilot site, allows ~1 word to be the same in ~3-word phrases;
this is good for "grants" but bad regarding "medicine."

SMALL BUCKETS = PRECISION IS GOOD BUT REQUIRES ITERATION.
LARGE BUCKETS = PRECISION IS NOT VERY GOOD.
'''

# Iterations after initial build: query_df = UnmatchedAfterJournals # UnmatchedAfterUmlsMesh UnassignedAfterSS
query_df = query_df.loc[(query_df['TotalSearchFreq'] > 15)] # Pilot site: started at 15 and moved down
query_df.rename(columns={'AdjustedQueryTerm': 'Query'}, inplace=True)

rowCnt = len(query_df)
queryColName = 'Query'
n_freq = 200 # Max rows by frequency of occurrence (?) Was 200
n_bucket = 10 # 10 works fine but requires many cycles
pair = []
whole_list = []
bucket_init = [[]  for i in range(n_bucket)]
bucket = bucket_init
#bucket = [[],[], [], [], []]#[[]]*n_bucket
print("bucket = ", bucket)

for i_comp1 in range(rowCnt):
    comp1 = query_df[queryColName][i_comp1]
    for i_comp2 in range(i_comp1+1, rowCnt):
        comp2 = query_df[queryColName][i_comp2]
        score = fuzz.ratio(comp1, comp2)
        if (score > 75):       # Similarity score you want; lower is looser matching. Was 75
            whole_list.extend((i_comp1, i_comp2))
            pair.append((i_comp1,i_comp2))
print("whole pair = ", pair)
whole_counter =  collections.Counter(whole_list)
whole_key = whole_counter.most_common(n_freq)
print(whole_key)
i_end = 0
i_cur = 0
i = 0
range_check = 0
for key, value in (whole_key):
    key_in_pre = False
# check whether key in previous bucket
    for j_check in range(max(range_check, i_end)):
        if key in bucket[j_check]:
            key_in_pre = key in bucket[j_check]
            i_cur = j_check
    if (i_end == 0 and (bucket[0] == [])):
        i = 0
        range_check = 1
    elif ((key_in_pre)):
        i = i_cur
    elif (key_in_pre and i_end != 0):
        i = i_cur
    elif ((~key_in_pre) and (i_end < n_bucket)) :
        i_end = i_end + 1
        i = i_end
    else:
        i = 100
# end check whether key in previous bucket

#    print("i = " , i)
    pair_copy = pair.copy()
    if (i < n_bucket):
      for i_pair in pair_copy:
        if(key == i_pair[0]):
            bucket[i].extend(i_pair)
            index = pair.index((key, i_pair[1]))
            pair.pop(index)
        elif(key == i_pair[1]):
            bucket[i].extend(i_pair)

print( "set ", set(bucket[0]), set(bucket[1]), set(bucket[2]))

# Results: Print to console
for ii in range(n_bucket):
    print("bucket ", ii, " = ", [query_df[queryColName][i_name] for i_name in set(bucket[ii])])

# Results: Append to dataframe
clusterResults = pd.DataFrame()
clusterResults['Bucket'] = ""
clusterResults['Query'] = ""

for ii in range(n_bucket):
    clusterResults = clusterResults.append(pd.DataFrame({'Bucket': ii,
                                                       'Query': [query_df[queryColName][i_name] for i_name in set(bucket[ii])]}), ignore_index=True)

# Dupe off Query column so we can tinker with the dupe
clusterResults['AdjustedQueryTerm'] = clusterResults['Query'].str.lower()

# Replace hyphen with space because the below would replace with nothing
clusterResults['AdjustedQueryTerm'] = clusterResults['AdjustedQueryTerm'].str.replace('-', ' ')
# Remove https:// if used
clusterResults['AdjustedQueryTerm'] = clusterResults['AdjustedQueryTerm'].str.replace('https://', '')

# Remove all chars except a-zA-Z0-9 and leave foreign chars alone
clusterResults['AdjustedQueryTerm'] = clusterResults['AdjustedQueryTerm'].str.replace(r'[^\w\s]+', '')

# Mods look okay, dropping original term for now; check if problems emerge
clusterResults.drop('Query', axis=1, inplace=True)

# Add empty columns that user will type in
clusterResults['PreferredTerm'] = ''
clusterResults['SemanticType'] = ''

# Write out
writer = pd.ExcelWriter('data/matchFiles/ClusterResults.xlsx')
clusterResults.to_excel(writer,'clusterResults', index=False)
# df2.to_excel(writer,'Sheet2')
writer.save()

#%%
# ===============================================
# 4. Build your custom terminology in Excel
# ===============================================
'''
Open data/matchFiles/ClusterResults.xlsx. Sort through the results and for rows
that don't fit, move them to a bucket where it does fit, or delete it. Build a
file matching the below. Delete the bucket column when you are done, and then
append the result to SiteSpecificTerms.xlsx.

|| AdjustedQueryTerm               || PreferredTerm                  || SemanticType     ||
|  yellow wallpaper	               |  The Literature of Prescription | Product-LO-Exhibit |
|  the yellow paper	               |  The Literature of Prescription | Product-LO-Exhibit |
|  the yellow wallpaper online pdf |  The Literature of Prescription | Product-LO-Exhibit |
|  medical subject headings (mesh) |  MeSH                           | Product-MeSH       |
|  medline                         |  PubMed/MEDLINE                 | Product-NCBI       |

'''

#%%
# ========================================================
# 5. Go on to Phase 1; re-run this script later as needed
# ========================================================
'''
Phase 1 will match the logs to SiteSpecificTerms.xlsx and PastMatches.xlsx,
and then you will be invited to re-cluster on the remaining untagged terms.
You can judge then how many cycles would be appropriate for you to build your
SiteSpecificTerms.xlsx file.
'''

#%%
# ========================================================
# To update SiteSpecificMatches.xlsx, such as punctuation
# ========================================================

"""
Run src/data/update_matchFiles.py, section for SiteSpecificMatches.
"""


text:
#=======================================================================
VERSION = 'Bitshares microDEX 0.00000022'
#=======================================================================

# Lightweight UI for Bitshares Decentralized Exchange

' litepresence 2019 '

def WTFPL_v0_March_1765():
    if any([stamps, licenses, taxation, regulation, fiat, etat]):
        try:
            print('no thank you')
        except:
            return [tar, feathers]

' ********** ALPHA RELEASE TO PUBLIC DOMAIN WITH NO WARRANTY ********* '

# Standard Python Modules
import os
import sys
import zlib
import time
import requests
import traceback
import numpy as np
from tkinter import *
from getpass import getpass
from ast import literal_eval as literal # race read
from random import random, shuffle, randint, choice
from json import dumps as json_dumps
from json import loads as json_loads
from decimal import Decimal as decimal

# litepresence/extinction-event modules
from manualSIGNING import broker, prototype_order

DEV = False  # additional feedback
COLOR = True  # black and white only in terminal

# set default currency pair
BitCURRENCY = 'OPEN.BTC'
BitASSET = 'BTS'
BitPAIR = BitASSET + ':' + BitCURRENCY
wif = ''
BEGIN = int(time.time())
SATOSHI = decimal(0.00000001)
SIXSIG = decimal(0.999999)
ANTISAT = 1 / SATOSHI

# bitshares mainnet chain ID
ID = '4018d7844c78f6a6c41c6a552b898022310fc5dec06da467ee7905a8dad512c8'

def red(text):
    return ('\033[91m' + text + '\033[0m') if COLOR else text
def green(text):
    return ('\033[92m' + text + '\033[0m') if COLOR else text
def yellow(text):
    return ('\033[93m' + text + '\033[0m') if COLOR else text
def blue(text):
    return ('\033[94m' + text + '\033[0m') if COLOR else text
def purple(text):
    return ('\033[95m' + text + '\033[0m') if COLOR else text
def cyan(text):
    return ('\033[96m' + text + '\033[0m') if COLOR else text

def colors():

    global red1, red2, blue1, blue2, yellow1, yellow2, green1, green2
    global gray1, gray2, gray3

    red1 = '#ff5858'
    red2 = '#820000'
    blue1 = '#77c5ec'
    blue2 = '#247fab'
    yellow1 = '#dcd900'
    yellow2 = '#989200'
    green1 = '#00d905'
    green2 = '#026500'
    gray1 = '#C0C0C0'
    gray2 = '#3f3f3f'
    gray3 = '#262626'

def cancel_all():

    global edicts
    edicts = [{'op': 'cancel', 'ids': ['1.7.X']}]
    order = json_loads(prototype_order())
    order['header']['wif'] = wif
    order['edicts'] = edicts
    broker(order)
    edicts = []

def log_in():

    global edicts
    edicts = [{'op': 'login'}]
    order = json_loads(prototype_order())
    order['header']['wif'] = wif
    order['edicts'] = edicts
    authenticated = broker(order)
    edicts = []
    return authenticated

def place_order():

    global edicts
    order = json_loads(prototype_order())
    order['header']['wif'] = wif
    order['edicts'] = edicts
    broker(order)
    edicts = []

def elapsed(text=''):
    if DEV:
        global stopwatch
        now = time.time()
        e = now - stopwatch
        stopwatch = now
        print(('%.4f' % e), text)

def msg_(e):  # traceback message
    return (str(type(e).__name__) + str(e.args) + str(e) +
            str(traceback.format_exc()) + str(sys.exc_info()))

def Bitshares_Trustless_Client():  # Your access to the metaNODE
    # Include this definition in your script to access metaNODE.txt
    # Deploy your bot script in the same folder as metaNODE.py
    for i in range(10):
        try:
            with open('metaNODE.txt', 'r') as f:
                ret = f.read()  # .replace("'",'"')
                f.close()
                metaNODE = json_loads(ret)
                return metaNODE
        except Exception as e:
            msg = str(
                time.ctime(
                ) + ' ' + type(
                    e).__name__) + ' ' + str(
                e.args)
            race_condition = ['Unterminated', "Expecting"]
            if any([x in str(e.args) for x in race_condition]):
                print('metaNODE = Bitshares_Trustless_Client() RACE READ')
            elif 'metaNODE is blank' in str(e.args):
                continue
            else:
                print('metaNODE = Bitshares_Trustless_Client() ' + msg)
            try:
                f.close()
            except:
                pass
        finally:
            try:
                f.close()
            except:
                pass
    raise

def race_read(doc=''):
    # Concurrent Read from File Operation
    for i in range(10):
        try:
            with open(doc, 'r') as f:
                # ret = json_loads(f.read())
                ret = literal(f.read())
                return ret
        except Exception as e:
            msg = (time.ctime() + str(type(e).__name__) + str(e.args))
            print('race_read ' + msg)
            pass
    raise

def race_append(doc='', text=''):
    # Concurrent Append to File Operation
    text = '\n' + str(time.ctime()) + ' ' + str(text) + '\n'
    for i in range(10):
        try:
            with open(doc, 'a+') as f:
                f.write(str(text))
                return
        except Exception as e:
                msg = (time.ctime() + str(type(e).__name__) + str(e.args))
                print('race_append' + msg)
                pass
    raise

def race_write(doc='', text=''):
    # Concurrent Write to File Operation
    text = str(text)
    for i in range(10):
        try:
            with open(doc, 'w+') as f:
                f.write(text)
                f.close()
                return
        except Exception as e:
            msg = str(type(e).__name__) + str(e.args)
            if DEV:
                msg += str(traceback.format_exc())
            print(msg)
            try:
                f.close()
            except:
                pass
        finally:
            try:
                f.close()
            except:
                pass
    raise

def dex_buy():

    def buy(price, amount):
        global edicts
        confirm.destroy()
        account_state()
        edicts = [{'op': 'buy',
                   'price': price,
                   'amount': amount,
                   'expiration': 0}]
        place_order()

    print(green('*** BUY ***'))
    metaNODE = Bitshares_Trustless_Client()
    currency = metaNODE['currency']
    currency_balance = decimal(metaNODE['currency_balance'])
    del metaNODE
    # interact with tkinter
    confirm = Tk()
    if authenticated:
        #
        # gather the price and amount from tkinter gui
        price = buy_price.get()
        amount = buy_amount.get()
        try:
            if price == '':
                raise ValueError('No Price Specified')
            if amount == '':
                raise ValueError('No Amount Specified')
            # convert pricing to ultra precision decimal
            price = decimal(price)
            # convert amounts to decimal; should already be
            amount = decimal(amount)
            # do not spend your last bitshare
            if currency == 'BTS':
                currency_balance -= 2
            # limit buy amount to means given currency in hand and price
            means = SIXSIG * currency_balance / decimal(price)
            if amount > means:
                amount = means
            #
            sprice = str(price)[:16]
            samount = str(amount)[:16]
            sorder = str(
                'CONFIRM BUY ' +
                samount +
                ' ' +
                BitASSET +
                ' @ ' +
                sprice)
            if amount > 0:
                confirm.title(sorder)
                print(yellow('CONFIRM BUY?'))
                Button(
                    confirm,
                    text='CONFIRM BUY',
                    command=lambda: buy(price, amount)).grid(
                    row=1,
                    column=0,
                    pady=8)
                Button(
                    confirm,
                    text='INVALIDATE',
                    command=lambda: invalidate(confirm)).grid(
                    row=2,
                    column=0,
                    pady=8)
            else:
                confirm.title('NO CURRENCY TO BUY')
                print(yellow('NO CURRENCY TO BUY'))
                Button(
                    confirm,
                    text='OK',
                    command=confirm.destroy).grid(
                    row=2,
                    column=0,
                    pady=8)
        except Exception as e:
            msg = str(type(e).__name__) + str(e.args)
            print(msg)
            if str(type(e).__name__) == 'NumRetriesReached()':
                confirm.title('LOST CONNECTION, TRY AGAIN')
                print(yellow('LOST CONNECTION, TRY AGAIN'))

            else:
                confirm.title('INVALID BUY ORDER')
                print(yellow('INVALID BUY ORDER'))
            Button(
                confirm,
                text='OK',
                command=confirm.destroy).grid(
                row=2,
                column=0,
                pady=8)

        confirm.geometry('500x100+800+175')
        confirm.lift()
        confirm.call('wm', 'attributes', '.', '-topmost', True)
    else:
        confirm.title('YOUR WALLET IS LOCKED')
        print(yellow('YOUR WALLET IS LOCKED'))
        Button(
            confirm,
            text='OK',
            command=confirm.destroy).grid(
            row=2,
            column=0,
            pady=8)
    confirm.geometry('500x100+800+175')
    confirm.lift()
    confirm.call('wm', 'attributes', '.', '-topmost', True)

def dex_sell():

    def sell(price, amount):
        global edicts
        confirm.destroy()
        account_state()
        edicts = [{'op': 'sell',
                   'price': price,
                   'amount': amount,
                   'expiration': 0}]
        place_order()

    print(red('*** SELL ***'))

    metaNODE = Bitshares_Trustless_Client()
    bts_balance = decimal(metaNODE['bts_balance'])
    asset_balance = decimal(metaNODE['asset_balance'])
    asset = metaNODE['asset']
    del metaNODE

    # interact with tkinter confirm sell widget
    confirm = Tk()
    if authenticated:
        price = sell_price.get()
        amount = sell_amount.get()
        # retain the last bitshare
        try:
            if price == '':
                raise ValueError('No Price Specified')
            if amount == '':
                raise ValueError('No Amount Specified')
            if asset == 'BTS':
                asset_balance -= 2
            price = decimal(price)
            amount = decimal(amount)
            if amount > (SIXSIG * asset_balance):
                amount = SIXSIG * asset_balance
            sprice = str(price)[:16]
            samount = str(amount)[:16]
            sorder = str(
                'CONFIRM SELL ' +
                samount +
                ' ' +
                BitASSET +
                ' @ ' +
                sprice)

            if amount > 0:
                confirm.title(sorder)
                print(yellow('CONFIRM SELL?'))
                Button(
                    confirm,
                    text='CONFIRM SELL',
                    command=lambda: sell(price, amount)).grid(
                    row=1,
                    column=0,
                    pady=8)
                Button(
                    confirm,
                    text='INVALIDATE',
                    command=lambda: invalidate(confirm)).grid(
                    row=2,
                    column=0,
                    pady=8)
            else:
                confirm.title('NO ASSETS TO SELL')
                print(yellow('NO ASSETS TO SELL'))
                Button(
                    confirm,
                    text='OK',
                    command=confirm.destroy).grid(
                    row=2,
                    column=0,
                    pady=8)
        except Exception as e:
            msg = str(type(e).__name__) + str(e.args)
            print(msg)
            if str(type(e).__name__) == 'NumRetriesReached()':
                confirm.title('LOST CONNECTION, TRY AGAIN')
                print(yellow('LOST CONNECTION, TRY AGAIN'))

            confirm.title('INVALID SELL ORDER')
            print(yellow('INVALID SELL ORDER'))

            Button(
                confirm,
                text='OK',
                command=confirm.destroy).grid(
                row=2,
                column=0,
                pady=8)
    else:
        confirm.title('YOUR WALLET IS LOCKED')
        print(yellow('YOUR WALLET IS LOCKED'))
        Button(
            confirm,
            text='OK',
            command=confirm.destroy).grid(
            row=2,
            column=0,
            pady=8)
    confirm.geometry('500x100+800+175')
    confirm.lift()
    confirm.call('wm', 'attributes', '.', '-topmost', True)

def dex_cancel():

    print(blue('*** CANCEL ***'))
    # attempt cancel all 10X or until satisfied
    metaNODE = Bitshares_Trustless_Client()
    orders = metaNODE['orders']
    del metaNODE

    def cancel():
        confirm.destroy()
        account_state()
        cancel_all()

    # interact with tkinter
    confirm = Tk()
    if len(orders):
        if authenticated:
            if len(orders) > 1:
                title = str(len(orders)) + ' ORDERS TO CANCEL'
            else:
                title = str(len(orders)) + ' ORDER TO CANCEL'
            confirm.title(title)
            print(yellow('CONFIRM?'))
            Button(
                confirm,
                text='CONFIRM CANCEL ALL',
                command=cancel).grid( #lambda: cancel(market)).grid(
                row=1,
                column=0,
                pady=8)
            Button(
                confirm,
                text='INVALIDATE',
                command=lambda: invalidate(confirm)).grid(
                row=2,
                column=0,
                pady=8)
            confirm.geometry('500x100+800+175')
            confirm.lift()
            confirm.call('wm', 'attributes', '.', '-topmost', True)
        else:
            confirm.title('YOUR WALLET IS LOCKED')
            print(yellow('YOUR WALLET IS LOCKED'))
            Button(
                confirm,
                text='OK',
                command=confirm.destroy).grid(
                row=2,
                column=0,
                pady=8)
    else:
        confirm.title('NO OUTSTANDING ORDERS')
        print(yellow('NO OUTSTANDING ORDERS'))
        Button(
            confirm,
            text='OK',
            command=confirm.destroy).grid(
            row=2,
            column=0,
            pady=8)
    confirm.geometry('500x100+800+175')
    confirm.lift()
    confirm.call('wm', 'attributes', '.', '-topmost', True)

def dex_auth_gui():

    # unlock wallet from gui
    global lock, wif, authenticated
    wif = str(login.get())
    login.delete(0, END)
    print(blue('LOCK/UNLOCK WALLET'))
    authenticated = False
    if wif:
        try:
            authenticated = log_in()
        except:
            pass
    if authenticated:
        print(red('*****************'))
        print(red('**AUTHENTICATED**'))
        print(red('*****************'))
    else:
        wif = ''
        print(yellow('WALLET IS LOCKED'))

def account_state():

    print( ' ASSETS: ' + (ap % asset_balance).rjust(12, ' ') +
        '         CURRENCY: ' + (cp % currency_balance).rjust(12, ' ') +
        '                BITSHARES: ' + ('%.2f' % bts_balance))

    print( ' ORDERS: ' +
        (ap % sell_orders).rjust(12, ' ') +
        '                   ' +
        (cp % buy_orders).rjust(12, ' '))

    print( '  TOTAL: ' +
        (ap % asset_total).rjust(12, ' ') +
        ' ' + (str(invested) + ' %').ljust(7, ' ') +
        '           ' +
        (cp % currency_total).rjust(12, ' ') +
        ' ' + str(divested).ljust(4, ' '))

    print( '    MAX: ' +
        (ap % asset_value).rjust(12, ' ') + ' ' +
        asset.ljust(10, ' ') +
        '        ' +
        (cp % currency_value).rjust(12, ' ') + ' ' +
        currency.ljust(10, ' '))

def update():

    global ping, update_id, pings, asset, currency
    global asset_total, currency_total, asset_value, currency_value
    global buy_orders, sell_orders, ap, cp, invested, divested
    global asset_balance, currency_balance, bts_balance

    elapsed('begin')
    complete = 0
    if update_id % 4 == 0:
        while not complete:
            try:
                metaNODE = Bitshares_Trustless_Client()
                elapsed('metaNODE')
                # localize metaNODE data
                data_node = choice(metaNODE['whitelist']).replace(
                    'wss://',
                    '').replace('/wss',
                                '').replace('/ws',
                                            '')
                blocktime = metaNODE['blocktime']
                last = metaNODE['last']
                orders = metaNODE['orders']
                currency_balance = metaNODE['currency_balance']
                asset_balance = metaNODE['asset_balance']
                currency_precision = metaNODE['currency_precision']
                asset_precision = metaNODE['asset_precision']
                bts_balance = metaNODE['bts_balance']
                currency = metaNODE['currency']
                asset = metaNODE['asset']
                history = metaNODE['history']
                book = metaNODE['book']
                buy_orders = metaNODE['buy_orders']
                sell_orders = metaNODE['sell_orders']
                invested = metaNODE['invested']
                divested = metaNODE['divested']
                ping = metaNODE['ping']
                # metaNODE dict is large, best to delete object when done
                del metaNODE

                # limit size of orders object to keys needed
                for i in range(len(orders)):
                    orders[i] = {k: v for k, v in orders[
                        i].items() if k in ['price', 'orderType', 'amount']}

                asset_total = (asset_balance + sell_orders)
                currency_total = (currency_balance + buy_orders)
                asset_value = asset_total + currency_total / last
                currency_value = asset_value * last

                # limit history depth
                history = history[:10]

                slast = '%.16f' % last
                latency = '%.3f' % (time.time() - blocktime + time.timezone)
                sbidp = [(' %.16f ' % i).rjust(20, ' ') for i in book['bidp']]
                saskp = [(' %.16f ' % i).ljust(20, ' ') for i in book['askp']]
                sbidv = [(' %.2f ' % i).rjust(12, ' ') for i in book['bidv']]
                saskv = [(' %.2f ' % i).rjust(12, ' ') for i in book['askv']]
                cbidv = list(np.cumsum(book['bidv']))
                caskv = list(np.cumsum(book['askv']))
                cbidv = [(' %.2f ' % i).rjust(12, ' ') for i in cbidv]
                caskv = [(' %.2f ' % i).rjust(12, ' ') for i in caskv]
                del book  # eliminate book after data extraction

                depth = 30
                sbidp = sbidp[:depth]
                saskp = saskp[:depth]
                sbidv = sbidv[:depth]
                saskv = saskv[:depth]
                cbidv = cbidv[:depth]
                caskv = caskv[:depth]
                complete = 1
                elapsed('format data')
            except Exception as e:
                print(e)
                elapsed('reconnect')
                continue

        header_text.delete("1.0", "end")
        header_text.insert(
            END,
            ('     ' + time.ctime() + '    microDEX - Bishares Minimalist UI\n\n'))
        header_text.insert(
            END, ('                    PING %.3f %s \n'% (ping, data_node)))
        header_text.insert(
            END, ('\n'))
        header_text.insert(
            END,
            ('                    LAST ' + slast + '     ' +
             BitPAIR + '   RUNTIME ' + str(int(time.time()) - BEGIN)))
        elapsed('header')

        bid_text.delete("1.0", "end")
        ask_text.delete("1.0", "end")
        for i in range(len(saskp)):
            # askp = ['%.8f' % j for j in book['askp']]
            ask_text.insert(END, (saskp[i] + saskv[i] + caskv[i] + '\n'))
            bid_text.insert(
                END,
                (cbidv[i] + sbidv[i] + sbidp[i] + '\n'),
                'right')
        elapsed('book')

        history_text.delete("1.0", "end")
        history_text.insert(
            END,
            (' ' + str(int(time.time())) + ' LAST TRADE ' +
             str(int(time.time() - history[0][0] + time.timezone)) + '\n'))
        for i in range(len(history)):
            history_text.insert(
                END,
                (' ' + str(history[i][0]) + ' ' +
                 str(history[i][1]) + ' ' +
                 str(history[i][2]) + ' ' + '\n'))
        elapsed('history')

        orders_text.delete("1.0", "end")
        if len(orders):
            orders_text.insert(END, ' OPEN ORDERS\n')
            for i in range(len(orders)):
                orders_text.insert(
                    END,
                    (' ' + str(orders[i]['price']) + ' ' +
                     str(orders[i]['orderType']).ljust(4, ' ') + ' ' +
                     str(orders[i]['amount']) + '\n'))
        else:
            orders_text.insert(END, '\n NO OPEN ORDERS')
        elapsed('orders')

        # create dynamic format styles: "%.4f" etc.
        ap = '%.' + str(int(asset_precision / 2.0)) + 'f'
        cp = '%.' + str(int(currency_precision / 2.0)) + 'f'

        account_text.delete("1.0", "end")
        account_text.insert(END, ' ASSETS: ' + (ap % asset_balance).rjust(12, ' ') +
                            '         CURRENCY: ' + (cp % currency_balance).rjust(12, ' ') +
                            '                BITSHARES: ' + ('%.2f' % bts_balance) + '\n')

        account_text.insert(END, ' ORDERS: ' +
                           (ap % sell_orders).rjust(12, ' ') +
                            '                   ' +
                           (cp % buy_orders).rjust(12, ' ') + '\n')

        account_text.insert(END, '  TOTAL: ' +
                           (ap % asset_total).rjust(12, ' ') +
                            ' ' + (str(invested) + ' %').ljust(7, ' ') +
                            '           ' +
                           (cp % currency_total).rjust(12, ' ') +
                            ' ' + str(divested).ljust(4, ' ') + ' %\n')

        account_text.insert(END, '    MAX: ' +
                           (ap % asset_value).rjust(12, ' ') + ' ' +
                            asset.ljust(10, ' ') +
                            '        ' +
                           (cp % currency_value).rjust(12, ' ') + ' ' +
                            currency.ljust(10, ' '))
        master.update()
        elapsed('account')
        lock = StringVar()

        if authenticated:
            lock.set('AUTHENTICATED')
            lock_color = red1
        else:
            lock.set('WALLET LOCKED')
            lock_color = blue1

        Label(
            master,
            textvariable=lock,
            fg=lock_color,
            bg=gray3).grid(
            row=8,
            column=2,
            sticky=W)
        master.update()
        elapsed('locked')
    update_id += 1

    master.after(200, update)

def invalidate(confirm):
    confirm.destroy()
    print(blue('MANUALLY INVALIDATED'))

def main():

    global stopwatch, USERNAME, BitPAIR, wif
    global master, lock
    global header_text, bid_text, ask_text, history_text, orders_text
    global update_id, ping, pings, account_text
    global nodes, authenticated
    global buy_price, buy_amount, sell_price, sell_amount, login

    colors()
    race_write(doc='microDEX_log.txt', text=time.ctime())
    stopwatch = time.time()

    print("\033c")
    sys.stdout.write(
        '\x1b]2;' +
        'Bitshares microDEX' +
        '\x07')  # terminal #title
    # Encoded Compressed Bitshares ASCII Logo
    b = b'x\x9c\xad\xd4M\n\xc4 \x0c\x05\xe0}O1P\x12B\x10\xbc\x82\xf7?\xd5\xf8\xaf\x83F\xe3\xe0[t\xf9\xf5%\xda>\x9f\x1c\xf7\x7f\x9e\xb9\x01\x17\x0cc\xec\x05\xe3@Y\x18\xc6(\'Z\x1a\xca.\x1bC\xa5l\r\x85\xa20\xb6\x8a\xca\xd8,W0\xec\x05\xc3\xdf\xd4_\xe3\r\x11(q\x16\xec\x95l\x04\x06\x0f\x0c\xc3\xddD\x9dq\xd2#\xa4NT\x0c/\x10\xd1{b\xd4\x89\x92\x91\x84\x11\xd9\x9d-\x87.\xe4\x1cB\x15|\xe0\xc8\x88\x13\xa5\xbc\xd4\xa21\x8e"\x18\xdc\xd2\x0e\xd3\xb6\xa0\xc6h\xa3\xd4\xde\xd0\x19\x9a\x1e\xd8\xddr\x0e\xcf\xf8n\xe0Y\rq\x1fP:p\x92\xf2\xdbaB,v\xda\x84j\xc4.\x03\xb1>\x97\xee{\x99oSa\x00\x0f\xc6\x84\xd8\xdf\x0f\xb4e\xa7$\xfdE\xae\xde\xb1/\x1d\xfc\x96\x8a'
    print(cyan(zlib.decompress(b).decode()))
    print(blue('''
                                       ______   ________  ____  ____
                                      (_   _ `.(_   __  |(_  _)(_  _)
       __  __  ____  ___  ____   ___    | | `. \ | |_ \_|  \ \__/ /
      (  \/  )(_  _)/ __)(  _ \ / _ \   | |  | | |  _) _    ) __ (
       )    (  _||_( (__  )   /( (_) ) _| |_.' /_| |__/ | _/ /  \ \_
      (_/\/\_)(____)\___)(_)\_) \___/ (______.'(________|(____)(____)
    ===================================================================
          '''))
    print(cyan('                                   ' + VERSION))
    print(blue('''
    ===================================================================
          '''))
    time.sleep(0.3)
    print(cyan('GATHERING live curated DEX data from the metaNODE...'))
    time.sleep(0.3)
    try:
        metaNODE = Bitshares_Trustless_Client()
        nodes = metaNODE['whitelist']
        USERNAME = metaNODE['account_name']
        asset = metaNODE['asset']
        currency = metaNODE['currency']
        account_id = metaNODE['account_id']
        del metaNODE
        print('')
        print('      metaNODE = Bitshares_Trustless_Client()')
    except:
        raise ValueError('metaNODE not found')
    print('')
    time.sleep(0.3)
    print(cyan('CHOOSING whitelisted public API...'))
    time.sleep(0.3)
    print('')
    print('      ' + green(nodes[0]))
    print('')
    print(cyan('CONNECTING to DEX account...'))
    print('')
    print('      Welcome Back: ', green(USERNAME), blue(str(account_id)))
    print('')
    print(cyan('CONNECTING to DEX market...'))
    BitPAIR = asset + ':' + currency
    BitASSET = BitPAIR.split(':')[0]
    BitCURRENCY = BitPAIR.split(':')[1]
    print('')
    print('   You are Trading: ', green(BitPAIR))
    print('')
    print(yellow(
        'Enter PASS PHRASE below to AUTHENTICATE or press ENTER to skip'))
    print(red(' YOU SHOULD UNDERSTAND THE SCRIPT BEFORE ENTERING PASS PHRASE'))
    print('')
    valid = 0
    default = ''
    authenticated = False
    while not valid:
        try:
            wif = getpass(prompt='               wif: ') or default
            print(
                "\033[F              wif: " + green(
                    '********************************'))
            if wif:
                print('')
                print(cyan('AUTHENTICATING to DEX wallet...'))
                try:
                    authenticated = log_in()
                except Exception as e:
                    trace(e)
                    pass
                if authenticated:
                    print('')
                    print(red('*****************'))
                    print(red('**AUTHENTICATED**') +
                          yellow(' YOUR WALLET IS UNLOCKED'))
                    print(red('*****************'))
                    valid = 1
                else:
                    wif = ''
                    print(yellow('wif DOES NOT MATCH USERNAME'))
                    valid = 0
            else:
                print('')
                print(yellow('SKIP AUTHENTICATION - YOUR WALLET IS LOCKED'))
                valid = 1
        except Exception as e:
            print(msg_(e))
            pass

    time.sleep(0.3)
    print(cyan('LAUNCHING microDEX user interface...'))

    master = Tk()
    # master.geometry("650x950")
    master['bg'] = '#262626'
    master.title('microDEX - Bitshares Minimalist UI')

    elapsed('master')
    lock = StringVar()
    lock.set('WALLET LOCKED')
    if authenticated:
        lock.set('AUTHENTICATED')
    elapsed('lock')

    header_text = Text(master, height=5, width=90, fg=blue2, bg=gray3, wrap=NONE)
    header_text.insert(END, '')
    header_text.grid(row=0, column=0, columnspan=4)

    bid_text = Text(master, height=30, width=45, fg=green1, bg=gray3, wrap=NONE)
    bid_text.insert(END, '')
    bid_text.grid(row=1, column=0, columnspan=2)
    bid_text.tag_configure("right", justify="right")
    bid_text.tag_configure("left", justify="left")

    ask_text = Text(master, height=30, width=45, fg=red1, bg=gray3, wrap=NONE)
    ask_text.insert(END, '')
    ask_text.grid(row=1, column=2, columnspan=2)

    orders_text = Text(master, height=11, width=45, fg=yellow1, bg=gray3, wrap=NONE)
    orders_text.insert(END, '')
    orders_text.grid(row=2, column=0, columnspan=2)

    history_text = Text(
        master,
        height=11,
        width=45,
        fg=gray1,
        bg=gray3, wrap=NONE)
    history_text.insert(END, '')
    history_text.grid(row=2, column=2, columnspan=2)

    account_text = Text(master, height=4, width=90, fg=blue1, bg=gray3, wrap=NONE)
    account_text.insert(END, '')
    account_text.grid(row=3, columnspan=4)

    elapsed('wireframe')

    Label(
        master,
        text="PRICE:",
        fg=gray1,
        bg=gray3).grid(
        row=4,
        column=0,
        sticky=E)
    Label(
        master,
        text="AMOUNT:",
        fg=gray1,
        bg=gray3).grid(
        row=5,
        column=0,
        sticky=E)
    Label(
        master,
        text="PRICE:",
        fg=gray1,
        bg=gray3).grid(
        row=4,
        column=2,
        sticky=E)
    Label(
        master,
        text="AMOUNT:",
        fg=gray1,
        bg=gray3).grid(
        row=5,
        column=2,
        sticky=E)
    Label(
        master,
        text="litepresence2018",
        fg=gray2,
        bg=gray3).grid(
        row=9,
        column=3,
        sticky=SE)
    Label(master, text=
          "   *ORDERS TAKE A FEW SECONDS TO APPEAR; CLICK ONCE, THEN CONFIRM*", fg='#C0C0C0', bg='#262626'
          ).grid(row=9, column=0, columnspan=4, sticky=W)

    try:
        # add bitshares logo to gui via imgur
        def download_img(imageUrl, localFileName):
            response = requests.get(imageUrl)
            with open(localFileName, 'wb') as fo:
                for chunk in response.iter_content(4096):
                    fo.write(chunk)
        try:
            photo = PhotoImage(file="bitshares_logo.gif")
        except:
            download_img(
                'https://i.imgur.com/fvCE86Z.gif',
                'bitshares_logo.gif')
            photo = PhotoImage(file="bitshares_logo.gif")
        label = Label(image=photo)
        label.image = photo
        label.grid(row=0, column=3, sticky=E)
    except:
        pass

    buy_price = Entry(master, fg=gray1, bg=gray2)
    buy_amount = Entry(master, fg=gray1, bg=gray2)
    sell_price = Entry(master, fg=gray1, bg=gray2)
    sell_amount = Entry(master, fg=gray1, bg=gray2)
    login = Entry(master, fg=gray1, bg=gray2)

    buy_price.grid(row=4, column=1)
    buy_amount.grid(row=5, column=1)
    sell_price.grid(row=4, column=3)
    sell_amount.grid(row=5, column=3)
    login.grid(row=8, column=1)
    elapsed('entry')

    Button(
        master,
        text='BUY',
        command=dex_buy,
        fg=gray1,
        bg=gray3,
        activebackground=green2,
        highlightbackground=green1).grid(
        row=7,
        column=1,
        # sticky=E,
        pady=4)
    Button(
        master,
        text='SELL',
        command=dex_sell,
        fg=gray1,
        bg=gray3,
        activebackground=red2,
        highlightbackground=red1).grid(
        row=7,
        column=3,
        # sticky=E,
        pady=4)
    Button(
        master,
        text='CANCEL ALL',
        command=dex_cancel, fg=gray1, bg=gray3, activebackground=yellow2, highlightbackground=yellow1).grid(
        row=7,
        column=0,
        sticky=E,
        pady=4)
    Button(
        master,
        text='LOCK/UNLOCK',
        command=dex_auth_gui, fg=gray1, bg=gray3, activebackground=blue2, highlightbackground=blue1).grid(
        row=8,
        column=0,
        sticky=E,
        pady=4)
    elapsed('button')

    update_id = 0
    ping = 0
    pings = [0]
    print(blue('''
    ===================================================================
          '''))
    print(cyan('           ' + time.ctime()))
    print(blue('''
    ===================================================================
          '''))
    print('')

    master.geometry('+9999+9999')
    master.after(0, update)
    master.mainloop()

if __name__ == "__main__":

    main()

max_stars_repo_name: nomeycoin/extinction-event-

max_issues_repo_name: nomeycoin/extinction-event-

max_forks_repo_name: nomeycoin/extinction-event-