from boltons.iterutils import split
with open('input_day22', 'r') as f:
    lines = [x.strip() for x in f.readlines()]

p1_raw, p2_raw = split(lines, '')
p1 = tuple(map(int, p1_raw[1:]))
p2 = tuple(map(int, p2_raw[1:]))

def play_game(p1, p2):
    previous_iteration = set()
    while p1 and p2:
        if (p1, p2) in previous_iteration:
            return 'p1', (p1, p2)

        previous_iteration.add((p1, p2))

        (p1c, p1), (p2c, p2) = (p1[0], p1[1:]), (p2[0], p2[1:])
        if p1c <= len(p1) and p2c <= len(p2):
            winner, _ = play_game(p1[:p1c], p2[:p2c])
            if winner == 'p1':
                p1 = p1 + (p1c, p2c)
            else:
                assert winner == 'p2'
                p2 = p2 + (p2c, p1c)
        else:
            if p1c > p2c:
                p1 = p1 + (p1c, p2c)
            else:
                p2 = p2 + (p2c, p1c)

    if p1:
        return 'p1', (p1, p2)
    else:
        return 'p2', (p1, p2)

#print(play_game((43, 19), (2, 29, 14)))
_, (r1, r2) = play_game(p1, p2)
print(sum(a * b for a, b in zip(r1 + r2, reversed(range(1, len(r1 + r2)+1)))))


class Solution(object):
    def letterCombinations(self, digits):
        """
        :type digits: str
        :rtype: List[str]
        """
        v = ["","","abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"]
        if digits == "":
            return []
        elif len(digits) == 1:
            ans = [x for x in v[int(digits[0])]]
            return ans
        a = v[int(digits[0])]
        for i in range(len(digits)-1):
            a = self.get_permutations(a, v[int(digits[i+1])])
        return a

    def get_permutations(self, a, b):
        ans = []
        for i in range(len(a)):
            for j in range(len(b)):
                ans.append(a[i]+b[j])
        return ans

17. Letter Combinations of a Phone Number.py


from datetime import datetime
from pymarc import MARCReader
from random import randint
import sys

if sys.argv[1]:
	file_name = sys.argv[1]
else:
	file_name = '/home/obib/default.mrc'

previous_tag = '000'
previous_subfield = '0'

with open(file_name, 'rb') as fh:
	out = open(file_name+'.sql', 'wb')
	reader = MARCReader(fh)
	for record in reader:
		bibid = str(randint(1, 10000))
		now = str(datetime.now());
		out.write('INSERT INTO biblio (bibid, create_dt, last_change_dt) VALUES (' + bibid + ", '" + now + "', '" + now + "');\n")
		for f in record.get_fields():
			if (previous_tag == f.tag):
				fieldseq = fieldseq + 1
			else:
				fieldseq = 1
			fieldid = str(randint(1, 1000000))
			if (f.is_control_field()):
				out.write('INSERT INTO biblio_field (bibid, fieldid, seq, tag, field_data) VALUES (' + bibid + ', ' + fieldid + ', ' + str(fieldseq) + ', '
					+ f.tag + ", '" + f.data + "');\n")
			else:
				out.write('INSERT INTO biblio_field (bibid, fieldid, seq, tag, ind1_cd, ind2_cd) VALUES (' + bibid + ', ' + fieldid + ', ' + str(fieldseq) + ', '
					+ f.tag + ", '" + f.indicators[0] + "', '" + f.indicators[1] + "');\n")
				for subfield in f:
					if (previous_subfield == subfield[0]):
						subfieldseq = subfieldseq + 1
					else:
						subfieldseq = 1
					subfieldid = str(randint(1, 10000000))
					out.write('INSERT INTO biblio_subfield (bibid, fieldid, subfieldid, seq, subfield_cd, subfield_data) VALUES (' + bibid + ', ' + fieldid + ', ' + subfieldid + ', '
						+ str(subfieldseq) + ", '"
						+ subfield[0] + "', '" + subfield[1].replace("'", "''") + "');\n")
			previous_tag = f.tag;

out.close()


import os
import sys
import json
import pandas as pd
from sacremoses import MosesTokenizer
from sklearn.feature_extraction.text import TfidfVectorizer

STOP_WORDS = 'datasets/czech_sw.txt' # Extracted from https://countwordsfree.com/stopwords/czech
DATA_PATH = 'datasets/many-czech-references/'
CONSTRAINT_PATH = os.path.join(DATA_PATH, 'constraint_split/') # Output folder.
LEMMA = True # If True, create lemmatized constraints.
ID_SPLIT = False # If True, save translation input per sentid. If False, save all inputs to the same file.

if LEMMA:
    tail = '_lemmatized'
else:
    tail = ''

if not ID_SPLIT:
    # Out files.
    dataset_path = '/home/aires/personal_work_troja/constrained_decoding/datasets/many-czech-references/constraint_split'
    source = os.path.join(dataset_path, 'source'+tail+'.txt')
    w_source = open(source, 'w')
    constraints = os.path.join(dataset_path, 'constraints'+tail+'.txt')
    w_constraints = open(constraints, 'w')
    translation = os.path.join(dataset_path, 'translation'+tail+'.txt')
    w_translation = open(translation, 'w')

# Read sentences.
en_path = os.path.join(DATA_PATH, 'en.txt')
en = pd.read_csv(en_path, sep='\t')
# Instantiate tokenizer.
mt = MosesTokenizer(lang='en')
# Read stop words.
sw = open(STOP_WORDS, 'r').read().split('\n')

def select_tokens(tfidf_sents, feature_names, ind):
    # Get sorterd tfidf words for constraint application.
    # Take indexes for words.
    feature_index = tfidf_sents[ind, :].nonzero()[1]
    # Take scores.
    tfidf_scores = zip(feature_index, [tfidf_sents[ind, x] for x in feature_index])
    # Sort them.
    tfidf_scores = sorted(tfidf_scores, key=lambda x: x[1], reverse=True)
    # Take words.
    words = [feature_names[i] for (i, s) in tfidf_scores]

    return words

# Take sentids.
end_id = 'constraints.txt'
if LEMMA:
    end_id += '.lemmatized'

sentids = [int(f.split('_')[0]) for f in os.listdir(CONSTRAINT_PATH) if f.endswith(end_id)]

# Read constraint providers.
for sentid in sentids:

    if ID_SPLIT:
        if LEMMA:
            file_name = f"{sentid}_constraints.txt.lemmatized"
        else:
            file_name = f"{sentid}_constraints.txt"

    file_path = os.path.join(CONSTRAINT_PATH, file_name)
    # Get the English sentence.
    eng_sent = en[en['sentid'] == sentid]['sent'].values[0]#.lower()
    # Tokenize English sentence.
    eng_sent = mt.tokenize(eng_sent, return_str=True)
    # Read constraint providers for sentid.
    providers = open(file_path, 'r').readlines()
    # Calculate TF-IDF over constraint providers. We sort constraints by its importance to the sentence.
    tfidf = TfidfVectorizer(stop_words=sw, token_pattern=u'(?ui)\\b\\w*[a-z]+\\w*\\b') # Avoid numbers.
    tfidf_sents = tfidf.fit_transform(providers) # TFIDF over constraint providers
    feature_names = tfidf.get_feature_names()

    if ID_SPLIT:
        # Set out_file.
        if LEMMA:
            out_name = f"{sentid}_constrained.txt.lemmatized"
        else:
            out_name = f"{sentid}_constrained.txt"
        out_path = os.path.join(CONSTRAINT_PATH, out_name)
        out_file = open(out_path, 'w')
        out_file.write(eng_sent+'\n') # No constraint example.

    for i in range(len(providers)):
        # For each constraint provider, calculate TF-IDF for it.
        tokens = select_tokens(tfidf_sents, feature_names, i)
        #n_tokens += len(tokens)
        # For each token, create a translating example. (eng_sentence + list_of_constraints)
        for t in range(len(tokens)):
            # Select current constraint with the previous ones.
            const = tokens[:t] + [tokens[t]]
            # Save to a file with the name corresponding to the source sentence (sentid).
            if ID_SPLIT:
                out_file.write(eng_sent+'\t'+'\t'.join(const)+'\n')
            else:
                w_source.write(eng_sent + '\n')
                w_constraints.write('\t'.join(const) + '\n')
                w_translation.write(eng_sent+'\t'+'\t'.join(const)+'\n')
    if ID_SPLIT:
        out_file.close()


 # Helper functions for running CCLF QC pipeline
import pandas as pd
import numpy as np
import dalmatian as dm
from gsheets import Sheets
import sys
pathtoJK_parent = "../"
sys.path.append(pathtoJK_parent)
from JKBio import terra

sheets = Sheets.from_files('~/.client_secret.json', '~/.storage.json')

def getCohortAbbreviations(df, cohorts2id_url="https://docs.google.com/spreadsheets/d/1R97pgzoX0YClGDr5nmQYQwimnKXxDBGnGzg7YPlhZJU"):
    # mapping abbreviations to full names/descriptions
    cohorts = sheets.get(cohorts2id_url).sheets[0].to_frame()
    # match collection data and error out
    cohortlist = []
    no_cohort_match = set()
    for k, val in df['Collection'].iteritems():
        res = cohorts[cohorts['Name'] == val]
        if len(res) == 0:
            print(res)
            no_cohort_match.add(str(val))
            cohortlist.append('nan')
        else:
            cohortlist.append(res['ID'].values[0])
    print("we do not have a corresponding cohort abbreviation for these cohorts: [{0}]".format(", ".join(str(i) for i in no_cohort_match)))

    df['cohorts'] = cohortlist
    return df

def regenerate_variables(wm, samplesetnames, cohorts2id_url):
    # Run function when need to re-generate key variables: sample_info, all_pairsets, the cohorts_per_batch dictionary, cohort_pairsets
    # Inputs:
    # - wm: Dalmation workspace manager for the data processing workspace

    # wm = dm.WorkspaceManager(workspace)
    # will use "cohort_pairsets" to create cohort-specific SNV tsv and CN heat map
    cohorts = sheets.get(cohorts2id_url).sheets[0].to_frame()
    sample_info = wm.get_samples() # TODO: check whether to use this or not
    cohorts_per_batch = {} # will be dict of cohorts in each batch
    all_changed_cohorts = set()
    for i in range(len(samplesetnames)):
        # get appropriate subset of the samples for each batch
        batch_sample_info = sample_info[sample_info['batch'] == samplesetnames[i][:-4]]
        cohorts_in_batch = set()
        cohorts_with_pairs = [] # check: currently not used.
        # for each batch, make pairsets by cohort
        for val in cohorts['ID'].values:
            cohortsamples = batch_sample_info[batch_sample_info["cohorts"] == val].index.tolist()
            tumorsamplesincohort = batch_sample_info[batch_sample_info["cohorts"] == val][batch_sample_info['sample_type']=="Tumor"].index.tolist()
            if len(cohortsamples)>0:
                cohorts_in_batch.update([val])
        batch_name = samplesetnames[i]
        cohorts_per_batch[batch_name] = cohorts_in_batch
        all_changed_cohorts.update(cohorts_in_batch) # add all the new cohorts in this batch to the full list

    # list of the cohort pairsets affected by the new samples we added
    all_pairsets = wm.get_pair_sets().index.tolist()
    cohort_pairsets = set(all_changed_cohorts) - (set(all_changed_cohorts) - set(all_pairsets))

    return sample_info, all_pairsets, cohorts_per_batch, cohort_pairsets, all_changed_cohorts

def check_cohort_abbrev_availability(df, cohorts2id_url):
    _, no_cohort_match = get_list_of_cohort_abbrevs_in_df(df, cohorts2id_url)
    return no_cohort_match

def get_list_of_cohort_abbrevs_in_df(df, cohorts2id_url):
    # the df must contain the columns: `Collection` (this is found in the External ID sheet)

    # cohorts and cohort abbreviations
    cohorts = sheets.get(cohorts2id_url).sheets[0].to_frame()

    # match collection data and error out
    cohortlist = []
    no_cohort_match = set()
    for k, val in df['Collection'].iteritems():
        res = cohorts[cohorts['Name'] == val]
        if len(res) == 0:
            no_cohort_match.add(str(val))
            cohortlist.append('nan')
        else:
            cohortlist.append(res['ID'].values[0])

    assert len(no_cohort_match) == 0,\
        "We do not have a corresponding cohort abbreviation for these cohorts: [{0}]".format(", ".join(str(i) for i in no_cohort_match)) + \
        "\nStop running the pipeline and have the CCLF team fix the missing cohort information."
    return cohortlist, no_cohort_match

def create_preliminary_sample_and_metadata_tables(wto, wfrom, samplesetnames, external_sheets_url_list, cohorts2id_url, forcekeep=[]):
    # Inputs:
    # - wto: Dalmation workspace manager for the data processing workspace
    # - wfrom: Dalmation workspace manager for the data delivery workspace

    # we look at all the samples we already have in the CCLF QC processing workspace
    refsamples = wto.get_samples()
    refids = refsamples.index

    # get the External sheet data from google sheets
    gsheets = [sheets.get(url).sheets[0].to_frame() for url in external_sheets_url_list]

    # add a column with batch information (e.g. CCLF_TWIST1 vs CCLF_TWIST2)
    metadata = pd.concat(gsheets,sort=False, keys = samplesetnames)
    metadata = metadata.reset_index().rename(columns = {'level_0':'batch', "External ID":'external_id_validation'}).drop(['level_1'], axis = 'columns')

    print('Number of rows from the external ID gsheets: {}'.format(len(metadata)))

    # we use this gsheet package to get all the sheets into one dataframe
    # cohorts
    cohorts = sheets.get(cohorts2id_url).sheets[0].to_frame()

    # we look at all the samples we already have in Terra
    # we do some corrections just in case
    samples1 = wfrom.get_samples().replace(np.nan, '', regex=True)

    # creating sample_id (like in processing wm) for metadata and samples1
    newmetadata = metadata.dropna(0, subset=['Collaborator Sample ID','Sample Type','Exported DNA SM-ID'])
    # print("Dropped indices: "+str(set(metadata.index.tolist())-set(newmetadata.index.tolist())))
    print("Dropped samples: "+str(set(metadata['Exported DNA SM-ID'].tolist())-set(newmetadata['Exported DNA SM-ID'].tolist())))
    print("Note that we expect to drop one per batch, the technical sequencing control.")

    print('New length after dropping any samples with no value for the Collaborator Sample ID, Sample Type, or Exported DNA SM-ID: '+str(len(newmetadata)))
    metadata=newmetadata

    ttype = [i for i in metadata["Sample Type"]]
    metadata['sample_id'] = [str(val['Collaborator Sample ID'][:-1]) + '-' + str(val['Sample Type']) + '-' + str(val['Exported DNA SM-ID']) for i, val in metadata.iterrows()]

    samples1.index = [i.split('_')[2] for i, val in samples1.iterrows()]

    samples1['sample_id'] = [str(val["individual_alias"]) + '-' + str(val['sample_type']) + '-' + i for i, val in samples1.iterrows()]

    print("Number of samples already in Terra: ", samples1.index.isin(refids).tolist().count(False))

    metadata.index = metadata['Exported DNA SM-ID']
    # print("Number of samples in the input External ID metadata: ",len(metadata.index.tolist()))

    # filtering on what already exists in the processing wm (refids)
    newsamples = samples1[(~samples1.index.isin(refids)) | samples1.index.isin(forcekeep)]
    post_filter_len = len(metadata.index.tolist())
    print('Number of samples remaining after filtering out samples already in the processing wm: '+ str(post_filter_len))

    # keep the new samples that we have metadata for
    tokeep = set(metadata.index) & set(newsamples.index)
    if len(tokeep) != post_filter_len:
        print("\nThe data delivery workspace (which is used to create `newsamples`) doesn't contain all the samples specified in the External Sheet(s) (which are used to create `metadata`). \nThe",len(set(metadata.index) - set(newsamples.index)),"samples we couldn't find are:", set(metadata.index) - set(newsamples.index), "\nThis can occur if a line is blacklisted due to too few reads, for example.")

    # useful to merge the two df, sm-id is one of the only unique id here
    num_newsamples = len(newsamples[~newsamples.index.isin(tokeep)])
    if num_newsamples > 0:
        print('We could not add these ' + str(num_newsamples) + ' samples from the data delivery wm as we don\'t have metadata for them: ' + '\n'
              + str(newsamples[~newsamples.index.isin(tokeep)].index))
    newsamples = newsamples[newsamples.index.isin(tokeep)]
    newmetadata = metadata[metadata.index.isin(tokeep)].sort_index().drop_duplicates("Exported DNA SM-ID")
    print("Final dimensions of the newsamples table: ", newsamples.shape)
    print("Final dimensions of the newmetadata table: ", newmetadata.shape)

    return newsamples, newmetadata

def check_required_metadata_columns(df, required_metadata_cols, cohorts2id_url, drop=False):
    # check collection (cohort) data and raise warning if missing
    check_cohort_abbrev_availability(df, cohorts2id_url)

    # If samples in the df are lacking any of the required metadata columns, flag these samples.
    samplesMissingMetadata = df.iloc[[j for j,i in enumerate(df[required_metadata_cols].isna().values.sum(1)) if i !=0]].index.tolist()
    nMissing = len(samplesMissingMetadata)

    # Return if no samples are missing metadata
    if nMissing == 0:
        print("No samples are missing any required metadata. Continue running the pipeline.")
        return df

    print("Since they do not have full data, we will be dropping " + str(nMissing) + " samples: \n" +  str(samplesMissingMetadata))

    # examine which columns in the External Sheet had missing information
    print('\nNumber of NAs for each required column:')
    print(df[required_metadata_cols].isna().sum())

    assert drop, '\nStop running the pipeline. Ask the CCLF team to fill out the missing values in the External Sheet.'

    if drop:
        # only keep samples that have all the appropriate information
        df = df.iloc[[j for j,i in enumerate(df[required_metadata_cols].isna().values.sum(1)) if i == 0]]
        print('We have now dropped the samples for which we didn\'t have all the required metadata columns.')

    return df

def create_sample_df_for_terra(wm, df, cohorts2id_url, picard_aggregation_type_validation='PCR', source='CCLF'):
    # Create sample df to upload to Terra
    # Inputs: df containing filtered set of samples plus metadata, cohorts and abbreviations gsheet url
    # - wm: Dalmation workspace manager for the data processing workspace
    # Output: sample_info table

    # cohorts and cohort abbreviations
    cohorts = sheets.get(cohorts2id_url).sheets[0].to_frame()
    cohortlist, _ = get_list_of_cohort_abbrevs_in_df(df, cohorts2id_url)

    # we look at all the samples we already have in the data processing workspace
    refsamples = wm.get_samples()

    print('creating new sample information df')
    # from this filtered set of samples (df) we create a dataframe which will get uploaded to terra
    sample_info = df[['crai_or_bai_path', 'cram_or_bam_path']].copy()
    sample_info['batch'] = df['batch'].astype(str)
    sample_info['individual_id'] = df['Collaborator Participant ID'].astype(str)
    sample_info['reference_id'] = df['Exported DNA SM-ID'].astype(str)
    sample_info['patient_id'] = df['Participant ID'].astype(str)
    sample_info['participant'] = df['Collaborator Participant ID'].astype(str)
    sample_info['aggregation_product_name_validation'] = df['bait_set'].astype(str)
    # here we add this number as the reference id might be present many times already for different samples
    # in the processing workspace

    # start building external_id_validation column
    sample_info['external_id_validation'] = 'nan'
    # for each SM-ID:
    for i in range(len(sample_info['reference_id'])):
        # get the external id for the sample
        ext_id_for_sample = df[df.index == sample_info['reference_id'][i]]['external_id_validation'].values[0]
        # replace any "/" that exist with "_"; otherwise get errors because looks like new directory when try to build file paths
        ext_id_for_sample = ext_id_for_sample.replace('/', '_') #[ext_id_for_sample.replace('/', '_') for ext_id in ext_id_for_sample]

        # tack on a number to distinguish external IDs that we have run more than once
        # using str.contains because we want to ignore the tacked on numbers we've added to the ext_id (e.g. _1, _2)
        # num of samples with this ext_id already in the workspace
        num_in_workspace = refsamples[refsamples.external_id_validation.str.contains(ext_id_for_sample)].shape[0]
        # num of samples with this ext_id that we've already seen in the data we're adding
        try:
            num_already_seen_here = sample_info[sample_info.external_id_validation.str.contains(ext_id_for_sample)].shape[0]
            num_to_add = num_in_workspace + num_already_seen_here + 1
        except:
            num_to_add = num_in_workspace + 1
        sample_info['external_id_validation'][i] = ext_id_for_sample + '_' + str(num_to_add)

    sample_info['bsp_sample_id_validation'] = df.index.str.strip()
    sample_info['stock_sample_id_validation'] = df['Stock DNA SM-ID'].str.strip()
    sample_info['sample_type'] = df['Sample Type'].str.strip()
    # TODO: I don't know what the "picard_aggregation_type_validation" is used for. Right now, the value is completely meaningless.
    sample_info['picard_aggregation_type_validation'] = [picard_aggregation_type_validation] * sample_info.shape[0]
    sample_info['tumor_subtype'] = df['Tumor Type'].str.strip()
    sample_info['squid_sample_id_validation'] = sample_info['external_id_validation']
    sample_info['source_subtype_validation'] = df['Original Material Type'].str.strip()
    sample_info['processed_subtype_validation'] = df['Material Type'].str.strip()
    sample_info['primary_disease'] = df['Primary Disease'].str.strip()
    sample_info['media'] = df['Media on Tube'].str.strip()
    sample_info['Collection'] = df['Collection'].str.strip()
    sample_info['cohorts'] = cohortlist
    sample_info['tissue_site'] = df['Tissue Site'].astype(str)
    sample_info['source'] = [source] * sample_info.shape[0]
    sample_info['sample_id'] = df.index.astype(str)

    sample_info = sample_info.set_index('sample_id')

    return sample_info

######## Functions for creating the pairs, pairsets, samplesets

def create_pairs_table(sample_info, wm):
    # Function to create the pairs table to upload to Terra.
    # Inputs:
    # - sample_info: the sample info table for the new samples that will be uploaded to Terra
    # - wm: Dalmation workspace manager for the data processing workspace
    refsamples = wm.get_samples()

    normals = [r["participant"] for i, r in sample_info.iterrows() if r['sample_type'] == "Normal"]
    normalsid = [i for i, r in sample_info.iterrows() if r['sample_type'] == "Normal"]
    tumors = [r["participant"] for i, r in sample_info.iterrows() if r['sample_type'] == "Tumor"]
    tumorsid = [i for i, r in sample_info.iterrows() if r['sample_type'] == "Tumor"]
    prevtumors = [val["participant"] for k, val in refsamples.iterrows() if val.sample_type == "Tumor"]
    prevnormals = [val["participant"] for k, val in refsamples.iterrows() if val.sample_type == "Normal"]

    print("creating new pairs...")
    # do we have new tumors/normals for our previous ones
    newpairs = {'pair_id': [], 'case_sample': [], 'control_sample': [], 'participant': [], 'match_type':[]}

    toreprocess_normals = set(tumors) & set(prevnormals)
    for val in toreprocess_normals:
        if val != 'nan':
            for tumor_id in sample_info[sample_info['participant'] == val][sample_info[
                    'sample_type'] == 'Tumor'].index.tolist():
                normal_id = refsamples[refsamples['participant'] == val][refsamples[
                  'sample_type'] == 'Normal'].index.tolist()[0]
                newpairs['pair_id'].append(tumor_id + '_' + normal_id)
                newpairs['case_sample'].append(tumor_id)
                newpairs['control_sample'].append(normal_id)
                newpairs['participant'].append(val)
                newpairs['match_type'].append("Tumor_Normal")

    paired = set(tumors) & set(normals)
    for val in set(tumors) - toreprocess_normals:
        if val != 'nan':
            for tumor_id in sample_info[sample_info['participant'] == val][sample_info[
                    'sample_type'] == 'Tumor'].index.tolist():
                normal_id = sample_info[(sample_info['participant'] == val) & (sample_info[
                  'sample_type'] == 'Normal')].index.tolist()[0] if val in paired else 'NA'
                newpairs['pair_id'].append(tumor_id + "_" + normal_id)
                newpairs['case_sample'].append(tumor_id)
                newpairs['control_sample'].append(normal_id)
                newpairs['participant'].append(val)
                newpairs['match_type'].append("Tumor_Normal" if val in paired else 'Tumor_NA')

    newpairs = pd.DataFrame(newpairs).set_index('pair_id')
    print("Done")
    return newpairs

def create_dict_of_pairs_per_sampleset(pairs, sample_info, samplesetnames, save=True, filename='dict_pairs_per_batch.npy'):
    # Pair => case_sample => look into samples => retrieve the batch, assign to the key
    dict_pairs_per_batch = {}
    for samplesetname in samplesetnames:
        dict_pairs_per_batch[samplesetname] = []

    for pair_id, pair in pairs.iterrows():
        case_sample = pair['case_sample']
        # Retrieve the batch which sample belongs to
        pair_s_batch = sample_info.loc[case_sample]['batch']
        dict_pairs_per_batch[pair_s_batch].append(pair_id)

    if save:
        print('Saving dictionary of pairs per sampleset to %s' % filename)
        np.save(filename, dict_pairs_per_batch)

    return dict_pairs_per_batch

def create_dict_of_samples_per_sampleset(sample_info, samplesetnames, save=False, filename='dict_samples_per_batch.npy'):
    # Samples => retrieve the batch, assign to the key
    dict_samples_per_batch = {}
    for samplesetname in samplesetnames:
        dict_samples_per_batch[samplesetname] = []

    # Retrieve the batch which sample belongs to
    for sample_id, sample in sample_info.iterrows():
        batch = sample_info.loc[sample_id]['batch']
        dict_samples_per_batch[batch].append(sample_id)

    if save:
        print('Saving dictionary of samples per sampleset to %s' % filename)
        np.save(filename, dict_samples_per_batch)

    return dict_samples_per_batch

# TODO: WIP
# def create_dict_of_cohorts_per_sampleset(sample_info, samplesetnames, save=False, filename='dict_cohorts_per_batch.npy'):
#     # Samples => retrieve the batch, assign to the key
#     dict_samples_per_batch = {}
#     for samplesetname in samplesetnames:
#         dict_samples_per_batch[samplesetname] = []
#
#     # Retrieve the batch which sample belongs to
#     for sample_id, sample in sample_info.iterrows():
#         batch = sample_info.loc[sample_id]['batch']
#         dict_samples_per_batch[batch].append(sample_id)
#
#     if save:
#         print('Saving dictionary of samples per sampleset to %s' % filename)
#         np.save(filename, dict_samples_per_batch)
#
#     return dict_samples_per_batch

def create_aggregate_samplesets(normalsid, proc_workspace, wto):
    print("Creating and uploading sample sets for all samples in workspace, and all normals in workspace...")
    all_samples = wto.get_samples().index.tolist()
    all_samples.remove('NA')

    # remove duplicates
    normalsid = list(set(normalsid))

    # create sample set for all normals in workspace (will use all combined normals in PoN for mutation calling)
    terra.addToSampleSet(proc_workspace, samplesetid="All_normals_TWIST", samples=normalsid)
    terra.addToSampleSet(proc_workspace, samplesetid="All_samples_TWIST", samples=all_samples)
    return

def create_sample_sets_per_batch(sample_info, samplesetnames, samplesetnames_all, samplesetnames_tumors, samplesetnames_normals, proc_workspace):
    print("Creating and uploading sample sets for each batch...")
    # want to create a sample set for each batch
    for i, current_batch in enumerate(samplesetnames):
        # get appropriate subset of the samples
        batch_sample_info = sample_info[sample_info['batch'] == current_batch]
        # define batch-specific tumors and normals
        batch_normals = [r["participant"] for _, r in batch_sample_info.iterrows() if r['sample_type'] == "Normal"]
        batch_normalsid = [k for k, _ in batch_sample_info.iterrows() if _['sample_type'] == "Normal"]
        batch_tumors = [r["participant"] for _, r in batch_sample_info.iterrows() if r['sample_type'] == "Tumor"]
        batch_tumorsid = [k for k,_ in batch_sample_info.iterrows() if _['sample_type'] == "Tumor"]
        # create 3 batch-level sample sets: all, tumors, normals
        terra.addToSampleSet(proc_workspace, samplesetid=samplesetnames_all[i], samples=batch_sample_info.index.tolist())
        terra.addToSampleSet(proc_workspace, samplesetid=samplesetnames_tumors[i], samples=batch_tumorsid)
        terra.addToSampleSet(proc_workspace, samplesetid=samplesetnames_normals[i], samples=batch_normalsid)
    return

def create_pair_sets_per_batch(samplesetnames, samplesetnames_pairs, proc_workspace, dict_pairs_per_batch):
    print("Uploading a pair set for each batch...")
    for i, current_batch in enumerate(samplesetnames):
        terra.addToPairSet(proc_workspace, samplesetnames_pairs[i], dict_pairs_per_batch[current_batch])
    return

def create_samplesets_and_pairsets_per_cohort(sample_info, samplesetnames, proc_workspace, cohorts2id_url, newpairs):
    print("Creating and uploading pairsets and samplesets by cohort (iterating over each batch)...")
    cohorts = sheets.get(cohorts2id_url).sheets[0].to_frame()
    cohorts_per_batch = {}
    for i, current_batch in enumerate(samplesetnames):

        # get appropriate subset of the samples for each batch
        batch_sample_info = sample_info[sample_info['batch'] == samplesetnames[i]]
        cohorts_in_batch = []
        # for each batch, make pairsets and samplesets by cohort
        for val in cohorts['ID'].values:
            cohortsamples = batch_sample_info[batch_sample_info["cohorts"] == val].index.tolist()
            tumorsamplesincohort = batch_sample_info[batch_sample_info["cohorts"] == val][batch_sample_info['sample_type']=="Tumor"].index.tolist()
            pairsamples = newpairs[newpairs['case_sample'].isin(tumorsamplesincohort)].index.tolist()
            if len(cohortsamples)>0:
                cohorts_in_batch.append(val)
                terra.addToSampleSet(proc_workspace, val, cohortsamples)

            if len(pairsamples)>0:
                terra.addToPairSet(proc_workspace,val, pairsamples)

        batch_name = samplesetnames[i]
        cohorts_per_batch.update(batch_name = cohorts_in_batch)
    return

# old aggregate function to generate all the cohort and batch specific sammple sets and pair sets
def create_pairsets_and_samplesets(wto, samplesetnames, proc_workspace, sample_info, dict_pairs_per_batch, samplesetnames_all, samplesetnames_tumors, samplesetnames_normals):
    # TODO: Uploading to Terra takes time. Right now, I iterate over cohorts and upload during the iteration. This means that if 2 batches have samples belonging to the same cohort, I upload to that cohort's sample set in Terra 2 times. This is inefficient. We could greatly speed this up (if we run multiple batches at once) by only uploading the cohort-level pairsets and samplesets at the end. That would mean tracking for each cohort all of the new samples (across each batch), then updating Terra at the end.
    # create a pair set for each batch.
    cohorts_per_batch = {}
    for i, current_batch in enumerate(samplesetnames):
        # upload a pair set for each batch
        terra.addToPairSet(proc_workspace, samplesetnames_pairs[i], dict_pairs_per_batch[current_batch])

        # get appropriate subset of the samples for each batch
        batch_sample_info = sample_info[sample_info['batch'] == samplesetnames[i]]
        cohorts_in_batch = []
        cohorts_with_pairs = [] # check: currently not used.
        # for each batch, make pairsets by cohort
        for val in cohorts['ID'].values:
            cohortsamples = batch_sample_info[batch_sample_info["cohorts"] == val].index.tolist()
            tumorsamplesincohort = batch_sample_info[batch_sample_info["cohorts"] == val][batch_sample_info['sample_type']=="Tumor"].index.tolist()
            pairsamples = newpairs[newpairs['case_sample'].isin(tumorsamplesincohort)].index.tolist()
            if len(cohortsamples)>0:
                cohorts_in_batch.append(val)
                terra.addToSampleSet(proc_workspace, val, cohortsamples)

            if len(pairsamples)>0:
                cohorts_with_pairs.append(val)
                terra.addToPairSet(proc_workspace,val, pairsamples)

        batch_name = samplesetnames[i]
        cohorts_per_batch.update(batch_name = cohorts_in_batch)

    print("creating sample sets for each batch...")
    # want to create a sample set for each batch
    for i, current_batch in enumerate(samplesetnames):
        # get appropriate subset of the samples
        batch_sample_info = sample_info[sample_info['batch'] == current_batch]
        # define batch-specific tumors and normals
        batch_normals = [r["participant"] for _, r in batch_sample_info.iterrows() if r['sample_type'] == "Normal"]
        batch_normalsid = [k for k, _ in batch_sample_info.iterrows() if _['sample_type'] == "Normal"]
        batch_tumors = [r["participant"] for _, r in batch_sample_info.iterrows() if r['sample_type'] == "Tumor"]
        batch_tumorsid = [k for k,_ in batch_sample_info.iterrows() if _['sample_type'] == "Tumor"]
        # create 3 batch-level sample sets: all, tumors, normals
        terra.addToSampleSet(proc_workspace, samplesetid=samplesetnames_all[i], samples=batch_sample_info.index.tolist())
        terra.addToSampleSet(proc_workspace, samplesetid=samplesetnames_tumors[i], samples=batch_tumorsid)
        terra.addToSampleSet(proc_workspace, samplesetid=samplesetnames_normals[i], samples=batch_normalsid)

    print("creating sample sets for all samples in workspace, and all normals in workspace...")
    # create sample set for all normals in workspace (will use all combined normals in PoN for mutation calling)
    normalsid.extend([k for k, _ in refsamples.iterrows() if _.sample_type == "Normal"])
    terra.addToSampleSet(proc_workspace, samplesetid="All_normals_TWIST", samples=normalsid)

    # create sample sets for all samples in workspace
    all_samples = wto.get_samples().index.tolist()
    all_samples.remove('NA')
    terra.addToSampleSet(proc_workspace, samplesetid="All_samples_TWIST", samples=all_samples)


from typing import TextIO, List

def parser_values(file: TextIO) -> List:
    """A function that parser value from a txt file"""
    with open("values.txt") as file:
        lines = file.readlines()
    lines = [
                {
                    "type_": line[0],
                    "date": line[1:9],
                    "value": line[9:19],
                    "cpf": line[19:30],
                    "card": line[30:42],
                    "hour": line[42:48],
                    "store_onwer": line[48:62],
                    "store_name": line[62:]
                }
                for line in lines
            ]
    return lines


import pandas as pd

HANDLES_DB = "db/handles.csv"

def set_or_update_handle(handle: str, uid: int):
    """Update handle if uid exists. Otherwise, add new handle"""
    df = pd.read_csv(HANDLES_DB)
    if (df["uid"] == uid).any():
        df.loc[df["uid"] == uid, "handle"] = handle
    else:
        new_handle_df = pd.DataFrame([{"uid": uid, "handle": handle}])
        df = pd.concat([df, new_handle_df])
    df.to_csv(HANDLES_DB, index=False)

def uid_exists(uid: int) -> bool:
    """Returns true if uid exists. Otherwise, false"""
    df = pd.read_csv(HANDLES_DB)
    return (df["uid"] == uid).any()

def uid2handle(uid: int) -> str:
    """Returns the handle from uid if exists"""
    df = pd.read_csv(HANDLES_DB)
    s = df.loc[df["uid"] == uid, "handle"].to_list()
    if len(s) != 0:
        return s[0]
    raise UidDoesNotExist

def get_all_uid_handle():
    """Returns a list of all uid's and handles"""
    df = pd.read_csv(HANDLES_DB)
    return df["uid"].to_list(), df["handle"].to_list()

class UidDoesNotExist(Exception):
    ...

if __name__ == "__main__":
    print("Does uid 1234 exist?", uid_exists(1234))
    print("Does uid 693265856305692764 exist?", uid_exists(693265856305692764))
    print()
    print("Handle of 693265856305692764:", uid2handle(693265856305692764))
    print()
    print("All uids and handles: ", get_all_uid_handle())


num_epochs = 15
batch_size = 100
tensor_shape = 784
dense1 = 64
dense2 = 32
output = 10

train_path = 'mnist_train.csv'
test_path = 'mnist_test.csv'
saved_model = 'mnist_classifier.json'
saved_weights = 'mnist_classifier.h5'
data_dir = 'E:\My Projects\Tensorflow 2.0  Basics\Data'


import numpy as np
from abc import ABCMeta, abstractmethod
from ezclimate.damage_simulation import DamageSimulation
from ezclimate.forcing import Forcing

class Damage(object, metaclass=ABCMeta):
	"""Abstract damage class for the EZ-Climate model.

	Parameters
	----------
	tree : `TreeModel` object
		provides the tree structure used
	bau : `BusinessAsUsual` object
		business-as-usual scenario of emissions

	Attributes
	----------
	tree : `TreeModel` object
		provides the tree structure used
	bau : `BusinessAsUsual` object
		business-as-usual scenario of emissions

	"""
	def __init__(self, tree, bau):
		self.tree = tree
		self.bau = bau

	@abstractmethod
	def average_mitigation(self):
		"""The average_mitigation function should return a 1D array of the
		average mitigation for every node in the period.
		"""
		pass

	@abstractmethod
	def damage_function(self):
		"""The damage_function should return a 1D array of the damages for
		every node in the period.
		"""
		pass

class DLWDamage(Damage):
	"""Damage class for the EZ-Climate model. Provides the damages from emissions and mitigation outcomes.

	Parameters
	----------
	tree : `TreeModel` object
		provides the tree structure used
	bau : `BusinessAsUsual` object
		business-as-usual scenario of emissions
	cons_growth : float
		constant consumption growth rate
	ghg_levels : ndarray or list
		end GHG levels for each end scenario

	Attributes
	----------
	tree : `TreeModel` object
		provides the tree structure used
	bau : `BusinessAsUsual` object
		business-as-usual scenario of emissions
	cons_growth : float
		constant consumption growth rate
	ghg_levels : ndarray or list
		end GHG levels for each end scenario
	dnum : int
		number of simulated damage paths
	d : ndarray
		simulated damages
	d_rcomb : ndarray
		adjusted simulated damages for recombining tree
	cum_forcings : ndarray
		cumulative forcing interpolation coeffiecients, used to calculate forcing based mitigation
	forcing : `Forcing` object
		class for calculating cumulative forcing and GHG levels
	damage_coefs : ndarray
		interpolation coefficients used to calculate damages

	"""

	def __init__(self, tree, bau, cons_growth, ghg_levels, subinterval_len):
		super(DLWDamage, self).__init__(tree, bau)
		self.ghg_levels = ghg_levels
		if isinstance(self.ghg_levels, list):
			self.ghg_levels = np.array(self.ghg_levels)
		self.cons_growth = cons_growth
		self.dnum = len(ghg_levels)
		self.subinterval_len = subinterval_len
		self.cum_forcings = None
		self.d = None
		self.d_rcomb = None
		self.emit_pct = None
		self.damage_coefs = None

	def _recombine_nodes(self):
		"""Creating damage coefficients for recombining tree. The state reached by an up-down move is
		separate from a down-up move because in general the two paths will lead to different degrees of
		mitigation and therefore of GHG level. A 'recombining' tree is one in which the movement from
		one state to the next through time is nonetheless such that an up move followed by a down move
		leads to the same fragility.
		"""
		nperiods = self.tree.num_periods
		sum_class = np.zeros(nperiods, dtype=int)
		new_state = np.zeros([nperiods, self.tree.num_final_states], dtype=int)
		temp_prob = self.tree.final_states_prob.copy()
		self.d_rcomb = self.d.copy()

		for old_state in range(self.tree.num_final_states):
			temp = old_state
			n = nperiods-2
			d_class = 0
			while n >= 0:
				if temp >= 2**n:
					temp -= 2**n
					d_class += 1
				n -= 1
			sum_class[d_class] += 1
			new_state[d_class, sum_class[d_class]-1] = old_state

		sum_nodes = np.append(0, sum_class.cumsum())
		prob_sum = np.array([self.tree.final_states_prob[sum_nodes[i]:sum_nodes[i+1]].sum() for i in range(len(sum_nodes)-1)])
		for period in range(nperiods):
			for k in range(self.dnum):
				d_sum = np.zeros(nperiods)
				old_state = 0
				for d_class in range(nperiods):
					d_sum[d_class] = (self.tree.final_states_prob[old_state:old_state+sum_class[d_class]] * self.d_rcomb[k, old_state:old_state+sum_class[d_class], period]).sum()
					old_state += sum_class[d_class]
					self.tree.final_states_prob[new_state[d_class, 0:sum_class[d_class]]] = temp_prob[0]
				for d_class in range(nperiods):
					self.d_rcomb[k, new_state[d_class, 0:sum_class[d_class]], period] = d_sum[d_class] / prob_sum[d_class]

		self.tree.node_prob[-len(self.tree.final_states_prob):] = self.tree.final_states_prob
		for p in range(1,nperiods-1):
			nodes = self.tree.get_nodes_in_period(p)
			for node in range(nodes[0], nodes[1]+1):
				worst_end_state, best_end_state = self.tree.reachable_end_states(node, period=p)
				self.tree.node_prob[node] = self.tree.final_states_prob[worst_end_state:best_end_state+1].sum()

	def _damage_interpolation(self):
		"""Create the interpolation coefficients used in `damage_function`."""
		if self.d is None:
			print("Importing stored damage simulation")
			self.import_damages()

		self._recombine_nodes()
		if self.emit_pct is None:
			bau_emission = self.bau.ghg_end - self.bau.ghg_start
			self.emit_pct = 1.0 - (self.ghg_levels-self.bau.ghg_start) / bau_emission

		self.damage_coefs = np.zeros((self.tree.num_final_states, self.tree.num_periods, self.dnum-1, self.dnum))
		amat = np.ones((self.tree.num_periods, self.dnum, self.dnum))
		bmat = np.ones((self.tree.num_periods, self.dnum))

		self.damage_coefs[:, :, -1,  -1] = self.d_rcomb[-1, :, :]
		self.damage_coefs[:, :, -1,  -2] = (self.d_rcomb[-2, :, :] - self.d_rcomb[-1, :, :]) / self.emit_pct[-2]
		amat[:, 0, 0] = 2.0 * self.emit_pct[-2]
		amat[:, 1:, 0] = self.emit_pct[:-1]**2
		amat[:, 1:, 1] = self.emit_pct[:-1]
		amat[:, 0, -1] = 0.0

		for state in range(0, self.tree.num_final_states):
			bmat[:, 0] = self.damage_coefs[state, :, -1,  -2] * self.emit_pct[-2]
			bmat[:, 1:] = self.d_rcomb[:-1, state, :].T
			self.damage_coefs[state, :, 0] = np.linalg.solve(amat, bmat)

	def import_damages(self, file_name="simulated_damages"):
		"""Import saved simulated damages. File must be saved in 'data' directory
		inside current working directory. Save imported values in `d`.

		Parameters
		----------
		file_name : str, optional
			name of file of saved simulated damages

		Raises
		------
		IOError
			If file does not exist.

		"""
		from ezclimate.tools import import_csv
		try:
			d = import_csv(file_name, ignore="#", header=False)
		except IOError as e:
			import sys
			print(("Could not import simulated damages:\n\t{}".format(e)))
			sys.exit(0)

		n = self.tree.num_final_states
		self.d = np.array([d[n*i:n*(i+1)] for i in range(0, self.dnum)])
		self._damage_interpolation()

	def damage_simulation(self, draws, peak_temp=9.0, disaster_tail=12.0, tip_on=True,
		multi_tips=False, temp_map=1, temp_dist_params=None, maxh=100.0, save_simulation=True):
		"""Initialization and simulation of damages, given by :mod:`ez_climate.DamageSimulation`.

		Parameters
		----------
		draws : int
			number of Monte Carlo draws
		peak_temp : float, optional
			tipping point parameter
		disaster_tail : float, optional
			curvature of tipping point
		tip_on : bool, optional
			flag that turns tipping points on or off
		multi_tips : bool, optional
			if to allow multiple tipping points in simulation
		temp_map : int, optional
			mapping from GHG to temperature
		        * 0: implies Pindyck displace gamma
		        * 1: implies Wagner-Weitzman normal
		        * 2: implies Roe-Baker
		        * 3: implies user-defined normal
		        * 4: implies user-defined gamma
		temp_dist_params : ndarray or list, optional
			if temp_map is either 3 or 4, user needs to define the distribution parameters
		maxh : float, optional
			time parameter from Pindyck which indicates the time it takes for temp to get half
		        way to its max value for a given level of ghg
		cons_growth : float, optional
			yearly growth in consumption
		save_simulation : bool, optional
			True if simulated values should be save, False otherwise

		Returns
		-------
		ndarray
			simulated damages

		"""
		ds = DamageSimulation(tree=self.tree, ghg_levels=self.ghg_levels, peak_temp=peak_temp,
					disaster_tail=disaster_tail, tip_on=tip_on, temp_map=temp_map,
					temp_dist_params=temp_dist_params, maxh=maxh, cons_growth=self.cons_growth)
		self.ds = ds
		print("Starting damage simulation..")
		self.d = ds.simulate(draws, write_to_file=save_simulation, multiple_tipping_points=multi_tips)
		print("Done!")
		self._damage_interpolation()
		return self.d

	def _forcing_based_mitigation(self, forcing, period):
		"""Calculation of mitigation based on forcing up to period. Interpolating between the forcing associated
		with the constant degree of mitigation consistent with the damage simulation scenarios.
		"""
		p = period - 1
		if forcing > self.cum_forcings[p][1]:
			weight_on_sim2 = (self.cum_forcings[p][2] - forcing) / (self.cum_forcings[p][2] - self.cum_forcings[p][1])
			weight_on_sim3 = 0
		elif forcing > self.cum_forcings[p][0]:
			weight_on_sim2 = (forcing - self.cum_forcings[p][0]) / (self.cum_forcings[p][1] - self.cum_forcings[p][0])
			weight_on_sim3 = (self.cum_forcings[p][1] - forcing) / (self.cum_forcings[p][1] - self.cum_forcings[p][0])
		else:
			weight_on_sim2 = 0
			weight_on_sim3 = 1.0 + (self.cum_forcings[p][0] - forcing) / self.cum_forcings[p][0]

		return weight_on_sim2 * self.emit_pct[1] + weight_on_sim3*self.emit_pct[0]

	def _forcing_init(self):
		"""Initialize `Forcing` object and cum_forcings used in calculating the force mitigation up to a node."""
		if self.emit_pct is None:
			bau_emission = self.bau.ghg_end - self.bau.ghg_start
			self.emit_pct = 1.0 - (self.ghg_levels-self.bau.ghg_start) / bau_emission

		self.cum_forcings = np.zeros((self.tree.num_periods, self.dnum))
		mitigation = np.ones((self.dnum, self.tree.num_decision_nodes)) * self.emit_pct[:, np.newaxis]

		for i in range(0, self.dnum):
			for n in range(1, self.tree.num_periods+1):
				node = self.tree.get_node(n, 0)
				self.cum_forcings[n-1, i] = Forcing.forcing_at_node(mitigation[i], node, self.tree,
																	self.bau, self.subinterval_len)

	def average_mitigation_node(self, m, node, period=None):
		"""Calculate the average mitigation until node.

		Parameters
		----------
		m : ndarray or list
			array of mitigation
		node : int
			node for which average mitigation is to be calculated for
		period : int, optional
			the period the node is in

		Returns
		-------
		float
			average mitigation

		"""
		if period == 0:
			return 0
		if period is None:
			period = self.tree.get_period(node)
		state = self.tree.get_state(node, period)
		path = self.tree.get_path(node, period)
		new_m = m[path[:-1]]

		period_len = self.tree.decision_times[1:period+1] - self.tree.decision_times[:period]
		bau_emissions = self.bau.emission_by_decisions[:period]
		total_emission = np.dot(bau_emissions, period_len)
		ave_mitigation = np.dot(new_m, bau_emissions*period_len)
		return ave_mitigation / total_emission

	def average_mitigation(self, m, period):
		"""Calculate the average mitigation for all node in a period.

		m : ndarray or list
			array of mitigation
		period : int
			period to calculate average mitigation for

		Returns
		-------
		ndarray
			average mitigations

		"""
		nodes = self.tree.get_num_nodes_period(period)
		ave_mitigation = np.zeros(nodes)
		for i in range(nodes):
			node = self.tree.get_node(period, i)
			ave_mitigation[i] = self.average_mitigation_node(m, node, period)
		return ave_mitigation

	def _ghg_level_node(self, m, node):
		return Forcing.ghg_level_at_node(m, node, self.tree, self.bau, self.subinterval_len)

	def ghg_level_period(self, m, period=None, nodes=None):
		"""Calculate the GHG levels corresponding to the given mitigation.
		Need to provide either `period` or `nodes`.

		Parameters
		----------
		m : ndarray or list
			array of mitigation
		period : int, optional
			what period to calculate GHG levels for
		nodes : ndarray or list, optional
			the nodes to calculate GHG levels for

		Returns
		-------
		ndarray
			GHG levels

		"""
		if nodes is None and period is not None:
			start_node, end_node = self.tree.get_nodes_in_period(period)
			if period >= self.tree.num_periods:
				add = end_node-start_node+1
				start_node += add
				end_node += add
			nodes = np.array(list(range(start_node, end_node+1)))
		if period is None and nodes is None:
			raise ValueError("Need to give function either nodes or the period")

		ghg_level = np.zeros(len(nodes))
		for i in range(len(nodes)):
			ghg_level[i] = self._ghg_level_node(m, nodes[i])
		return ghg_level

	def ghg_level(self, m, periods=None):
		"""Calculate the GHG levels for more than one period.

		Parameters
		----------
		m : ndarray or list
			array of mitigation
		periods : int, optional
			number of periods to calculate GHG levels for

		Returns
		-------
		ndarray
			GHG levels

		"""
		if periods is None:
			periods = self.tree.num_periods-1
		if periods >= self.tree.num_periods:
			ghg_level = np.zeros(self.tree.num_decision_nodes+self.tree.num_final_states)
		else:
			ghg_level = np.zeros(self.tree.num_decision_nodes)
		for period in range(periods+1):
			start_node, end_node = self.tree.get_nodes_in_period(period)
			if period >= self.tree.num_periods:
				add = end_node-start_node+1
				start_node += add
				end_node += add
			nodes = np.array(list(range(start_node, end_node+1)))
			ghg_level[nodes] = self.ghg_level_period(m, nodes=nodes)
		return ghg_level

	def _damage_function_node(self, m, node):
		"""Calculate the damage at any given node, based on mitigation actions in `m`."""
		if self.damage_coefs is None:
			self._damage_interpolation()
		if self.cum_forcings is None:
			self._forcing_init()
		if node == 0:
			return 0.0

		period = self.tree.get_period(node)
		forcing, ghg_level = Forcing.forcing_and_ghg_at_node(m, node, self.tree, self.bau, self.subinterval_len, "both")
		force_mitigation = self._forcing_based_mitigation(forcing, period)
		ghg_extension = 1.0 / (1 + np.exp(0.05*(ghg_level-200)))

		worst_end_state, best_end_state = self.tree.reachable_end_states(node, period=period)
		probs = self.tree.final_states_prob[worst_end_state:best_end_state+1]

		if force_mitigation < self.emit_pct[1]:
			damage = (probs *(self.damage_coefs[worst_end_state:best_end_state+1, period-1, 1, 1] * force_mitigation \
					 + self.damage_coefs[worst_end_state:best_end_state+1, period-1, 1, 2])).sum()

		elif force_mitigation < self.emit_pct[0]:
			damage = (probs * (self.damage_coefs[worst_end_state:best_end_state+1, period-1, 0, 0] * force_mitigation**2 \
					  + self.damage_coefs[worst_end_state:best_end_state+1, period-1, 0, 1] * force_mitigation \
					  + self.damage_coefs[worst_end_state:best_end_state+1, period-1, 0, 2])).sum()
		else:
			damage = 0.0
			i = 0
			for state in range(worst_end_state, best_end_state+1):
				if self.d_rcomb[0, state, period-1] > 1e-5:
					deriv = 2.0 * self.damage_coefs[state, period-1, 0, 0]*self.emit_pct[0] \
							+ self.damage_coefs[state, period-1, 0, 1]
					decay_scale = deriv / (self.d_rcomb[0, state, period-1]*np.log(0.5))
					dist = force_mitigation - self.emit_pct[0] + np.log(self.d_rcomb[0, state, period-1]) \
						   / (np.log(0.5) * decay_scale)
					damage += probs[i] * (0.5**(decay_scale*dist) * np.exp(-np.square(force_mitigation-self.emit_pct[0])/60.0))
				i += 1

		return (damage / probs.sum()) + ghg_extension

	def damage_function(self, m, period):
		"""Calculate the damage for every node in a period, based on mitigation actions `m`.

		Parameters
		----------
		m : ndarray or list
			array of mitigation
		period : int
			period to calculate damages for

		Returns
		-------
		ndarray
			damages

		"""
		nodes = self.tree.get_num_nodes_period(period)
		damages = np.zeros(nodes)
		for i in range(nodes):
			node = self.tree.get_node(period, i)
			damages[i] = self._damage_function_node(m, node)
		return damages


QNTD_NUMS = 3

def volumeEsfera(raio):
    pi = 3.1416
    volume = (4*pi*(raio**3))/3
    return volume

for i in range(QNTD_NUMS):
    raio = float(input())
    print("{:.2f}".format(volumeEsfera(raio)))


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

###---Quicksort---###

x = [11,16,2,8,1,9,4,7]
pivot = x[-1]
wall = 0
current = 0
middle = int( (len(x)/2) - 1)

print(x)

for y in x:
    if x[current] < pivot:
        x[wall], x[current] = x[current], x[wall]
        wall = wall + 1

    current = current + 1

x[middle], x[pivot] = x[pivot], x[middle]

subX1 = x[:middle]
subX2 = x[middle+1:]
print(x)
print(subX1)
print(subX2)

pivot = subX1[-1]
wall = 0
current = 0
for y in subX1:
    if subX1[current] < pivot:
        subX1[wall], subX1[current] = subX1[current], subX1[wall]
        wall = wall + 1

    current = current + 1

pivot = subX2[-1]
wall = 0
current = 0
for y in subX2:
    if subX2[current] < pivot:
        subX2[wall], subX2[current] = subX2[current], subX2[wall]
        wall = wall + 1

    current = current + 1

print(subX1)
print(subX2)


#! /usr/bin/env python
# encoding: utf-8
# Thomas Nagy, 2007-2010 (ita)

"""
Debugging helper for parallel compilation, outputs
a file named pdebug.svg in the source directory::

	def options(opt):
		opt.load('parallel_debug')
	def configure(conf):
		conf.load('parallel_debug')
	def build(bld):
   	 ...
"""

import os, time, sys
from queue import Queue
from waflib import Runner, Options, Utils, Task, Logs, Errors

#import random
#random.seed(100)

def options(opt):
	opt.add_option('--dtitle', action='store', default='Parallel build representation for %r' % ' '.join(sys.argv),
		help='title for the svg diagram', dest='dtitle')
	opt.add_option('--dwidth', action='store', type='int', help='diagram width', default=800, dest='dwidth')
	opt.add_option('--dtime', action='store', type='float', help='recording interval in seconds', default=0.009, dest='dtime')
	opt.add_option('--dband', action='store', type='int', help='band width', default=22, dest='dband')
	opt.add_option('--dmaxtime', action='store', type='float', help='maximum time, for drawing fair comparisons', default=0, dest='dmaxtime')

def configure(conf):
	conf.find_program('convert', var='CONVERT_BIN')

# red   #ff4d4d
# green #4da74d
# lila  #a751ff

color2code = {
	'GREEN'  : '#4da74d',
	'YELLOW' : '#fefe44',
	'PINK'   : '#a751ff',
	'RED'    : '#cc1d1d',
	'BLUE'   : '#6687bb',
	'CYAN'   : '#34e2e2',
}

mp = {}
info = [] # list of (text,color)

def map_to_color(name):
	if name in mp:
		return mp[name]
	try:
		cls = Task.classes[name]
	except KeyError:
		return color2code['RED']
	if cls.color in mp:
		return mp[cls.color]
	if cls.color in color2code:
		return color2code[cls.color]
	return color2code['RED']

def process(self):
	m = self.master
	if m.stop:
		m.out.put(self)
		return

	self.master.set_running(1, id(Utils.threading.currentThread()), self)

	# remove the task signature immediately before it is executed
	# in case of failure the task will be executed again
	try:
		del self.generator.bld.task_sigs[self.uid()]
	except:
		pass

	try:
		self.generator.bld.returned_tasks.append(self)
		self.log_display(self.generator.bld)
		ret = self.run()
	except Exception:
		self.err_msg = Utils.ex_stack()
		self.hasrun = Task.EXCEPTION

		# TODO cleanup
		m.error_handler(self)
		m.out.put(self)
		return

	if ret:
		self.err_code = ret
		self.hasrun = Task.CRASHED
	else:
		try:
			self.post_run()
		except Errors.WafError:
			pass
		except Exception:
			self.err_msg = Utils.ex_stack()
			self.hasrun = Task.EXCEPTION
		else:
			self.hasrun = Task.SUCCESS
	if self.hasrun != Task.SUCCESS:
		m.error_handler(self)

	self.master.set_running(-1, id(Utils.threading.currentThread()), self)
	m.out.put(self)
Task.TaskBase.process_back = Task.TaskBase.process
Task.TaskBase.process = process

old_start = Runner.Parallel.start
def do_start(self):
	try:
		Options.options.dband
	except AttributeError:
		self.bld.fatal('use def options(opt): opt.load("parallel_debug")!')

	self.taskinfo = Queue()
	old_start(self)
	if self.dirty:
		process_colors(self)
Runner.Parallel.start = do_start

def set_running(self, by, i, tsk):
	self.taskinfo.put( (i, id(tsk), time.time(), tsk.__class__.__name__, self.processed, self.count, by)  )
Runner.Parallel.set_running = set_running

def name2class(name):
	return name.replace(' ', '_').replace('.', '_')

def process_colors(producer):
	# first, cast the parameters
	if not hasattr(producer.bld, 'path'):
		return

	tmp = []
	try:
		while True:
			tup = producer.taskinfo.get(False)
			tmp.append(list(tup))
	except:
		pass

	try:
		ini = float(tmp[0][2])
	except:
		return

	if not info:
		seen = []
		for x in tmp:
			name = x[3]
			if not name in seen:
				seen.append(name)
			else:
				continue

			info.append((name, map_to_color(name)))
		info.sort(key=lambda x: x[0])

	thread_count = 0
	acc = []
	for x in tmp:
		thread_count += x[6]
		acc.append("%d %d %f %r %d %d %d" % (x[0], x[1], x[2] - ini, x[3], x[4], x[5], thread_count))

	data_node = producer.bld.path.make_node('pdebug.dat')
	data_node.write('\n'.join(acc))

	tmp = [lst[:2] + [float(lst[2]) - ini] + lst[3:] for lst in tmp]

	st = {}
	for l in tmp:
		if not l[0] in st:
			st[l[0]] = len(list(st.keys()))
	tmp = [  [st[lst[0]]] + lst[1:] for lst in tmp ]
	THREAD_AMOUNT = len(list(st.keys()))

	st = {}
	for l in tmp:
		if not l[1] in st:
			st[l[1]] = len(list(st.keys()))
	tmp = [  [lst[0]] + [st[lst[1]]] + lst[2:] for lst in tmp ]

	BAND = Options.options.dband

	seen = {}
	acc = []
	for x in range(len(tmp)):
		line = tmp[x]
		id = line[1]

		if id in seen:
			continue
		seen[id] = True

		begin = line[2]
		thread_id = line[0]
		for y in range(x + 1, len(tmp)):
			line = tmp[y]
			if line[1] == id:
				end = line[2]
				#print id, thread_id, begin, end
				#acc.append(  ( 10*thread_id, 10*(thread_id+1), 10*begin, 10*end ) )
				acc.append( (BAND * begin, BAND*thread_id, BAND*end - BAND*begin, BAND, line[3]) )
				break

	if Options.options.dmaxtime < 0.1:
		gwidth = 1
		for x in tmp:
			m = BAND * x[2]
			if m > gwidth:
				gwidth = m
	else:
		gwidth = BAND * Options.options.dmaxtime

	ratio = float(Options.options.dwidth) / gwidth
	gwidth = Options.options.dwidth

	gheight = BAND * (THREAD_AMOUNT + len(info) + 1.5)

	out = []

	out.append("""<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>
<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.0//EN\"
\"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd\">
<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" version=\"1.0\"
   x=\"%r\" y=\"%r\" width=\"%r\" height=\"%r\"
   id=\"svg602\" xml:space=\"preserve\">

<style type='text/css' media='screen'>
	g.over rect  { stroke:#FF0000; fill-opacity:0.4 }
</style>

<script type='text/javascript'><![CDATA[
var svg  = document.getElementsByTagName('svg')[0];

svg.addEventListener('mouseover', function(e) {
	var g = e.target.parentNode;
	var x = document.getElementById('r_' + g.id);
	if (x) {
		g.setAttribute('class', g.getAttribute('class') + ' over');
		x.setAttribute('class', x.getAttribute('class') + ' over');
		showInfo(e, g.id);
	}
}, false);

svg.addEventListener('mouseout', function(e) {
		var g = e.target.parentNode;
		var x = document.getElementById('r_' + g.id);
		if (x) {
			g.setAttribute('class', g.getAttribute('class').replace(' over', ''));
			x.setAttribute('class', x.getAttribute('class').replace(' over', ''));
			hideInfo(e);
		}
}, false);

function showInfo(evt, txt) {
	tooltip = document.getElementById('tooltip');

	var t = document.getElementById('tooltiptext');
	t.firstChild.data = txt;

	var x = evt.clientX + 9;
	if (x > 250) { x -= t.getComputedTextLength() + 16; }
	var y = evt.clientY + 20;
	tooltip.setAttribute("transform", "translate(" + x + "," + y + ")");
	tooltip.setAttributeNS(null, "visibility", "visible");

	var r = document.getElementById('tooltiprect');
	r.setAttribute('width', t.getComputedTextLength() + 6);
}

function hideInfo(evt) {
	var tooltip = document.getElementById('tooltip');
	tooltip.setAttributeNS(null,"visibility","hidden");
}
]]></script>

<!-- inkscape requires a big rectangle or it will not export the pictures properly -->
<rect
   x='%r' y='%r'
   width='%r' height='%r'
   style=\"font-size:10;fill:#ffffff;fill-opacity:0.01;fill-rule:evenodd;stroke:#ffffff;\"
   />\n

""" % (0, 0, gwidth + 4, gheight + 4,   0, 0, gwidth + 4, gheight + 4))

	# main title
	if Options.options.dtitle:
		out.append("""<text x="%d" y="%d" style="font-size:15px; text-anchor:middle; font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans">%s</text>
""" % (gwidth/2, gheight - 5, Options.options.dtitle))

	# the rectangles

	groups = {}
	for (x, y, w, h, clsname) in acc:
		try:
			groups[clsname].append((x, y, w, h))
		except:
			groups[clsname] = [(x, y, w, h)]
	for cls in groups:
		out.append("<g id='%s'>\n" % name2class(cls))

		for (x, y, w, h) in groups[cls]:
			out.append("""<rect
   x='%r' y='%r'
   width='%r' height='%r'
   style=\"font-size:10;fill:%s;fill-rule:evenodd;stroke:#000000;stroke-width:0.4;\"
   />\n""" % (2 + x*ratio, 2 + y, w*ratio, h, map_to_color(cls)))
		out.append("</g>\n")

	# output the caption
	cnt = THREAD_AMOUNT

	for (text, color) in info:
		# caption box
		b = BAND/2
		out.append("""<g id='r_%s'><rect
		x='%r' y='%r'
		width='%r' height='%r'
		style=\"font-size:10;fill:%s;fill-rule:evenodd;stroke:#000000;stroke-width:0.4;\"
  />\n""" %                       (name2class(text), 2 + BAND,     5 + (cnt + 0.5) * BAND, b, b, color))

		# caption text
		out.append("""<text
   style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
   x="%r" y="%d">%s</text></g>\n""" % (2 + 2 * BAND, 5 + (cnt + 0.5) * BAND + 10, text))
		cnt += 1

	out.append("""
<g transform="translate(0,0)" visibility="hidden" id="tooltip">
  <rect id="tooltiprect" y="-15" x="-3" width="1" height="20" style="stroke:black;fill:#edefc2;stroke-width:1"/>
  <text id="tooltiptext" style="font-family:Arial; font-size:12;fill:black;"> </text>
</g>""")

	out.append("\n</svg>")

	node = producer.bld.path.make_node('pdebug.svg')
	node.write("".join(out))
	Logs.warn('Created the diagram %r' % node.abspath())

	p = node.parent.abspath()
	producer.bld.exec_command([producer.bld.env.CONVERT_BIN or 'convert', p + os.sep + 'pdebug.svg', p + os.sep + 'pdebug.png'])


# -*- encoding: utf-8 -*-
from odoo import api, fields, models
from ast import literal_eval

class SettingsInherit(models.TransientModel):
    _inherit = 'res.config.settings'

    ns_erp_url = fields.Char(string="Digital Edge ERP Address")
    ns_portal_url = fields.Char(string="Digital Edge Portal Address")
    ns_chuanjun_portal_url = fields.Char(string="Chuanjun Portal Address")

    @api.model
    def get_values(self):
        res = super(SettingsInherit, self).get_values()
        get_param = self.env['ir.config_parameter'].sudo().get_param
        res.update(ns_erp_url=get_param('nrs_de_portal.ns_erp_url'))
        res.update(ns_portal_url=get_param('nrs_de_portal.ns_portal_url'))
        res.update(ns_chuanjun_portal_url=get_param('nrs_de_portal.ns_chuanjun_portal_url'))
        return res

    def set_values(self):
        super(SettingsInherit, self).set_values()
        set_param = self.env['ir.config_parameter'].sudo().set_param
        set_param('nrs_de_portal.ns_erp_url', self.ns_erp_url)
        set_param('nrs_de_portal.ns_portal_url', self.ns_portal_url)
        set_param('nrs_de_portal.ns_chuanjun_portal_url', self.ns_chuanjun_portal_url)


from PricingForClicks.Learner import Learner
import math
import numpy as np

class UCB1_Learner(Learner):
    def __init__(self, arms):
        n_arms = len(arms)
        super().__init__(n_arms)
        self.results_per_arm = [(0, 0, arms[i]) for i in range(n_arms)]
        self.arms_history = []

    def pull_arm(self):
        self.t += 1
        if self.t <= self.n_arms:
            return self.t-1
        else:
            upper_bounds = list(map(self.calc_upper_bound, self.results_per_arm))
            return np.argmax(upper_bounds)

    def calc_upper_bound(self, params):
        (avg, n, price) = params
        return price * (avg + math.sqrt(2 * math.log10(self.t) / n))

    def update(self, pulled_arm, successes, failures):
        (avg, n, p) = self.results_per_arm[pulled_arm]
        new_avg = (avg * n + successes) / (n+successes + failures)
        self.results_per_arm[pulled_arm] = (new_avg, n + successes + failures, p)
        self.arms_history.append(pulled_arm)


from flask import Flask, render_template, request, jsonify

import simple_queries

import simple_queries

app = Flask(__name__)

@app.route("/")
def index():
    simple_queries.get_eg_data(simple_queries.create_session())
    return "hello world"

@app.route("/queries", methods=["GET", "POST"])
def queries():
    if request.method == "GET":
        return render_template("queries.html")

    if request.method == "POST":
        simple_queries.get_data(
            request.form.getlist('country'),
            request.form.getlist('role'),
            request.form.get('experience')
        )
        return request.form

@app.route("/simple-chart")
def simple_chart():
    data = [
        ("01-01-2020", 1597),
        ("02-01-2020", 934),
        ("03-01-2020", 456),
        ("04-01-2020", 2873),
        ("05-01-2020", 1597),
        ("06-01-2020", 934),
        ("07-01-2020", 456),
        ("08-01-2020", 2873),
        ("09-01-2020", 1597),
        ("10-01-2020", 934),
        ("11-01-2020", 456),
        ("12-01-2020", 2873),
    ]

    labels = [row[0] for row in data]
    values = [row[1] for row in data]

    return render_template("chart.html", labels=labels, values=values)

if __name__=='__main__':
    app.run(debug=True)


from functions import *

class Sentence_:
    """
    A class which holds the attributes of the single sentence
    """

    def __init__(self, params=None):

        self.text=None
        self.text_tokens=None
        self.text_entities=None
        self.text_emb=None
        self.text_actions=None
        self.text_imperative=None
        self.text_allen_result=None
        self.text_depparse=None

        if params is not None:
            for key in params:
                setattr(self, key, params[key])

    def preprocess_text(self, pipeline=None, tokenizer_func=None):

        if pipeline is None:
            pipeline = [to_lower_func, punctuation_removal_func, remove_spaces_func]

        for func in pipeline:
            self.text = func(self.text)

        if tokenizer_func is not None:
            self.tokenize_sentence(tokenizer_func)

    def tokenize_sentence(self, tokenize_func):
        if self.text_tokens is None:
            self.text_tokens = tokenize_func(self.text)

    def compute_embedding(self, compute_sentence_embedding_func, model):
        if self.text_tokens is None:
            raise ValueError("Error: Text Tokens have not been generated")

        self.text_emb = compute_sentence_embedding_func(self.text_tokens, model)

    def compute_entities(self, compute_entities_func):
        if self.text_entities is None:
            self.text_entities = compute_entities_func(self.text)

    def compute_text_actions(self, action_extractor_func):

        self.text_actions = list(itertools.chain(*(action_extractor_func(self.text))))


#!/usr/bin/env python

#SENDER PART OF AZP -> Abdullah Zahid Protocol
#this builds a TCP like protocol on top of UDP

import socket
import sys
import os
import socket
import signal
import time
import datetime
import functs #functs.py in the package which has necessary functions like ones to make a packet

windowSize = 1 #tested on this window size

if __name__ == '__main__':
    # See if all the arguments are there if not then raise error
    try:
        fileToSend, logFile = sys.argv[1], sys.argv[5]
        receiverIP, receiverPort, ackPort = socket.gethostbyname(sys.argv[2]), int(sys.argv[3]), int(sys.argv[4])
    except IndexError as TypeError:
        exit('All arguments were not provided, please refer to the explanation to see correct usage')

    try:
        # Init UDP sockets for sending packets
        sendSocket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        sendSocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        sendSocket.bind(("", ackPort))
        # Init socket for getting acknowledgements
        ackSocket = socket.socket()
        ackSocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        ackSocket.bind(("", ackPort))
        ackSocket.listen(1)
    except socket.error:
        exit('Error creating sockets')

    #init variables
    sequenceNumber, ackNumber, SentNum, retransmittedNum = 0,0,0,0
    timeout = 1
    lastPacket, connectionEstablished= False, False
     #connectionEstablished will turn true after first packet makes it

    try:
        sendFile = open(fileToSend, 'rb')
    except:
        exit("Error opening file: " + fileToSend)

    try:
        logF = open(logFile, 'wb')
    except IOError:
        exit("Unable to open " + logFile)

    currText = sendFile.read(556)

    # keeps sending initial packet until connection is made
    while not connectionEstablished:
        try:
            packet = functs.makePacket(ackPort, receiverPort,sequenceNumber, ackNumber, False, False, windowSize, currText)
            sendSocket.sendto(packet, (receiverIP, receiverPort))
            SentNum += 1
            sendTime = time.time()

            signal.signal(signal.SIGALRM, functs.timeout)
            signal.alarm(1)

            receiverSocket, addr = ackSocket.accept()

            signal.alarm(0)
            connectionEstablished = True
            receivalTime = time.time()
            estimatedRoundTripTime = receivalTime - sendTime
            devRTT = 0
            receiverSocket.settimeout(timeout)
        except socket.timeout:
            retransmittedNum += 1
            continue

    #after connection is established, send all other packets
    while True:
        try:
            ack = receiverSocket.recv(20)
            receivalTime = time.time()

            # unpack packet info
            ackSourcePort, ackDest, ackSequenceNumber,\
                ack_ackNumber, ackHeaderLength, ackValid,\
                ackLastPacket, ackWindowSize, ackContents = functs.unpackPacket(ack)

            log = str(datetime.datetime.now()) + " " + \
                  str(ackSourcePort) + " " + \
                  str(ackDest) + " " + \
                  str(ackSequenceNumber) + " " + \
                  str(ack_ackNumber) + "\n"

            # flags each packet in logFile
            if ackValid:
                log = log.strip("\n") + " ACK\n"
            if ackLastPacket:
                log = log.strip("\n") + " FIN\n"

            # If all is good and ack is valid, we continue
            if ack_ackNumber == ackNumber and ackValid:
                sampleRoundTripTime = receivalTime - sendTime
                estimatedRoundTripTime = estimatedRoundTripTime * 0.875 + sampleRoundTripTime * 0.125
                devRTT = 0.75 * devRTT + 0.25 * abs(sampleRoundTripTime - estimatedRoundTripTime)
                receiverSocket.settimeout(estimatedRoundTripTime + 4 * devRTT)

                #write log
                log = log.strip() + " " + str(estimatedRoundTripTime) + "\n"
                logF.write(log)
                if ackLastPacket:
                    break

                currText = sendFile.read(556)  # 576-20(for header)
                if currText == "":
                    lastPacket = True

                #update sequence Number and ackNumber
                sequenceNumber += 1
                ackNumber += 1

                #make and send next packet
                packet = functs.makePacket(ackPort, receiverPort,sequenceNumber, ackNumber, False,lastPacket, windowSize,currText)
                sendSocket.sendto(packet, (receiverIP, receiverPort))
                SentNum += 1
                sendTime = time.time()

            else:
                logF.write(log)
                raise socket.timeout

        except socket.timeout: #need to retransmit
            packet = functs.makePacket(ackPort, receiverPort,sequenceNumber, ackNumber, False,lastPacket, windowSize,currText)
            sendSocket.sendto(packet, (receiverIP, receiverPort))
            SentNum += 1
            retransmittedNum += 1

    print("\n------------------Successfully Sent, AZP WORKS-----------------------")
    print("Total Num of Segments Sent = {} \n Number of Segments retransmitted= {}\n".format(str(SentNum),str(retransmittedNum)))


import requests                     as req
import urllib.parse                 as url
import json                         as json
import subprocess                   as subprocess
import netifaces                    as netifaces
import pprint                       as pp
import signal                       as signal
import pathlib                      as path
import operator                     as operator

import nw_control.params            as cfg
import virtual_hosts.params         as vhost_cfg

from functools                      import reduce

class VirtualHost:
    def __init__( self
                , actual_host_mac
                , actual_host_ip
                , virtual_host_mac
                , virtual_host_ip
                , ingress_node_device_id
                , token):
        self._actual_host_mac           = actual_host_mac
        self._actual_host_ip            = actual_host_ip
        self._virtual_host_mac          = virtual_host_mac
        self._virtual_host_ip           = virtual_host_ip
        self._ingress_node_device_id    = ingress_node_device_id
        self._token                     = token

    @staticmethod
    def _install_virtual_host( actual_host_mac
                             , actual_host_ip
                             , virtual_host_mac
                             , virtual_host_ip
                             , ingress_node_device_id):
        request_json = { "ingressNode"              : ingress_node_device_id
                       , "virtualHostMacAddress"    : virtual_host_mac
                       , "actualHostMacAddress"     : actual_host_mac
                       , "virtualHostIpAddress"     : virtual_host_ip
                       , "actualHostIpAddress"      : actual_host_ip
                       }
        pp.pprint(request_json)

        request_url = url.urljoin(vhost_cfg.onos_url.geturl(),
                "virtual-hosts/v1/create-virtual-host")
        create_virtual_host_request = req.post(request_url, json=request_json,
                auth=cfg.ONOS_API_CREDENTIALS)
        if not create_virtual_host_request:
            raise ValueError("Failed to create virtual host with IP Address %s. Status %d %s" %
                    (virtual_host_ip, create_virtual_host_request.status_code,
                        create_virtual_host_request.reason))
        response_json = create_virtual_host_request.json()
        return response_json["virtual-host-id"]

    @staticmethod
    def _initialize_local_network_interface(iface_name, actual_host_ip_address):
        def build_ip_addr_add_cmd(password, actual_host_ip_address, mask_length, iface_name):
            ip_addr_add_cmd = ("ip addr add %s/%d dev %s" %
                    (actual_host_ip_address, mask_length, iface_name)).split(" ")
            return ip_addr_add_cmd

        ip_addr_add_cmd = build_ip_addr_add_cmd(vhost_cfg.password, actual_host_ip_address,
                24, iface_name)
        proc_result = subprocess.run(ip_addr_add_cmd, stdout=subprocess.PIPE,
                stderr=subprocess.STDOUT)
        if proc_result.returncode != 0:
            print(proc_result.stdout.decode("utf-8"))
            raise ValueError("Failed to initialize local network interface with command: %s" %
                    (ip_addr_add_cmd))
        interface_mac_address = netifaces.ifaddresses(iface_name)[netifaces.AF_LINK][0]
        return interface_mac_address["addr"]

    @staticmethod
    def _remove_local_network_interface(iface_name, actual_host_ip_address):
        def build_del_ip_addr_cmd(password, actual_host_ip_address, mask_length, iface_name):
            ip_addr_del_cmd = ("ip addr del %s/%d dev %s" %
                    (actual_host_ip_address, mask_length, iface_name)).split(" ")
            return ip_addr_del_cmd

        ip_addr_del_cmd = build_del_ip_addr_cmd(vhost_cfg.password, actual_host_ip_address,
                24, iface_name)
        proc_result = subprocess.run(ip_addr_del_cmd, stdout=subprocess.PIPE,
                stderr=subprocess.STDOUT)
        if proc_result.returncode != 0:
            raise ValueError("Failed to remove local network interface with command: %s" %
                    (ip_addr_del_cmd))

    @staticmethod
    def _uninstall_virtual_host(virtual_host_token):
        request_url = url.urljoin(vhost_cfg.onos_url.geturl(),
                "virtual-hosts/v1/destroy-virtual-host?virtual-host-id=%s" % virtual_host_token)
        destroy_host_request = req.post(request_url, auth=cfg.ONOS_API_CREDENTIALS)
        if not destroy_host_request:
            raise ValueError("Failed to destroy virtual host with token %s. %d %s" %
                    (virtual_host_token,
                        destroy_host_request.status_code, destroy_host_request.reason))

    @staticmethod
    def initialize_virtual_host_persistent_state( virtual_host_mac
                                                , virtual_host_ip
                                                , actual_host_ip
                                                , ingress_node_device_id):
        actual_host_mac     = None
        virtual_host_token  = None
        try:
            actual_host_mac = VirtualHost._initialize_local_network_interface(vhost_cfg.iface_name,
                    actual_host_ip)
            virtual_host_token = VirtualHost._install_virtual_host(actual_host_mac, actual_host_ip,
                    virtual_host_mac, virtual_host_ip, ingress_node_device_id)
        except Exception as ex:
            if actual_host_mac != None:
                VirtualHost._remove_local_network_interface(vhost_cfg.iface_name,
                        actual_host_ip)
            if virtual_host_token != None:
                VirtualHost._uninstall_virtual_host(virtual_host_token)
            raise ex

        return actual_host_mac, virtual_host_token

    def destroy_virtual_host(self):
        VirtualHost._uninstall_virtual_host(self.token)
        VirtualHost._remove_local_network_interface(vhost_cfg.iface_name, self.actual_host_ip)

    @property
    def actual_host_mac(self):
        return self._actual_host_mac

    @property
    def actual_host_ip(self):
        return self._actual_host_ip

    @property
    def virtual_host_mac(self):
        return self._virtual_host_mac

    @property
    def virtual_host_ip(self):
        return self._virtual_host_ip

    @property
    def ingress_node_device_id(self):
        return self._ingress_node_device_id

    @property
    def token(self):
        return self._token

    def __str__(self):
        s = "Virtual Host %s" % self.token
        s += "\tActual Host MAC     | %s" % self.actual_host_mac
        s += "\tActual Host IP      | %s" % self.actual_host_ip
        s += "\tVirtual Host MAC    | %s" % self.virtual_host_mac
        s += "\tVirtual Host IP     | %s" % self.virtual_host_ip
        return s

class TrafficGenerationVirtualHost(VirtualHost):
    BIN_DIR = path.Path("/home/cpsc-net-user/repos/cpsc_of_testbed/traffic_generation/")

    def __init__(self, host_id, *args):
        super(TrafficGenerationVirtualHost, self).__init__(*args)
        self._host_id                       = host_id
        self._traffic_gen_server_process    = None
        self._traffic_gen_client_process    = None
        self._configured_flows              = []

    @property
    def host_id(self):
        return self._host_id

    @property
    def configured_flows(self):
        return self._configured_flows

    @staticmethod
    def create_virtual_host( host_id
                           , virtual_host_mac
                           , virtual_host_ip
                           , actual_host_ip
                           , ingress_node_device_id):
        actual_host_mac, virtual_host_token = \
                VirtualHost.initialize_virtual_host_persistent_state(virtual_host_mac,
                        virtual_host_ip, actual_host_ip, ingress_node_device_id)
        the_virtual_host = TrafficGenerationVirtualHost(host_id, actual_host_mac, actual_host_ip,
                virtual_host_mac, virtual_host_ip, ingress_node_device_id, virtual_host_token)
        return the_virtual_host

    def start_traffic_generation_server(self):
        traffic_gen_server_path = TrafficGenerationVirtualHost.BIN_DIR / "traffic_server.py"
        args = [ str(traffic_gen_server_path)
               , "-host"            , str(self.host_id)
               , "-source_addr"     , self.actual_host_ip
               ]
        traffic_gen_server_process = subprocess.Popen(args,
                stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
        self._traffic_gen_server_process = traffic_gen_server_process

    def stop_traffic_generation_server(self):
        if self._traffic_gen_server_process == None:
            raise ValueError("Attempting to stop traffic generation server before starting it.")
        self._traffic_gen_server_process.send_signal(signal.SIGINT)

    def configure_flow( self
                      , tx_rate
                      , tx_rate_std_dev
                      , traffic_model
                      , dest_ip
                      , port_num
                      , k_mat
                      , time_slice
                      , tag_values
                      , pkt_len=1066):

        client_args = { "dest_port"         : port_num
                      , "dest_addr"         : dest_ip
                      , "prob_mat"          : k_mat
                      , "tx_rate"           : tx_rate
                      , "variance"          : tx_rate_std_dev**2
                      , "traffic_model"     : traffic_model
                      , "packet_len"        : pkt_len
                      , "src_host"          : self.host_id
                      , "time_slice"        : time_slice
                      , "tag_value"         : tag_values
                      , "source_addr"       : self.actual_host_ip
                      }
        self._configured_flows.append(client_args)

    def start_traffic_generation_client(self):
        # If no flows have been configured, starting the traffic generation client does
        # nothing.
        if len(self.configured_flows) > 0:
            traffic_gen_client_path = TrafficGenerationVirtualHost.BIN_DIR / "traffic_gen.py"
            args = [ str(traffic_gen_client_path)
                   , json.dumps(self.configured_flows)
                   ]
            # print(reduce(lambda v1, v2: " " + v1 + " " + v2, args))
            traffic_gen_client_process = subprocess.Popen(args,
                    stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
            self._traffic_gen_client_process = traffic_gen_client_process

    def stop_traffic_generation_client(self):
        # If no flows were configured, stopping the client does nothing.
        if len(self.configured_flows) == 0:
            return

        # Can't stop the client if it was never started.
        if self._traffic_gen_client_process == None:
            raise ValueError("Attempting to stop traffic generation client before starting it.")

        self._traffic_gen_client_process.send_signal(signal.SIGINT)
        if self._traffic_gen_client_process.returncode != 0:
            std_out, std_err = self._traffic_gen_client_process.communicate()
            print("Host %d traffic generation failed with error: " % self.host_id)
            print(std_out.decode("utf-8"))
            print("")

    def destroy_virtual_host(self):
        super().destroy_virtual_host()
        if self._traffic_gen_client_process != None:
            self.stop_traffic_generation_client()

        if self._traffic_gen_server_process != None:
            self.stop_traffic_generation_server()

class PathHoppingSender(VirtualHost):
    BIN_DIR = path.Path("/home/cpsc-net-user/repos/mtd-crypto-impl/endpoint/sender")

    def __init__(self, host_id, *args):
        super(PathHoppingSender, self).__init__(*args)
        self._host_id               = host_id
        self._sender_process        = None

    @property
    def host_id(self):
        return self._host_id

    @staticmethod
    def create_virtual_host( host_id
                           , virtual_host_mac
                           , virtual_host_ip
                           , actual_host_ip
                           , ingress_node_device_id):
        actual_host_mac, virtual_host_token = \
                VirtualHost.initialize_virtual_host_persistent_state(virtual_host_mac,
                        virtual_host_ip, actual_host_ip, ingress_node_device_id)
        the_virtual_host = PathHoppingSender(host_id, actual_host_mac, actual_host_ip,
                virtual_host_mac, virtual_host_ip, ingress_node_device_id, virtual_host_token)
        return the_virtual_host

    def start_path_hopping_sender( self
                                 , port                 = None
                                 , K                    = None
                                 , N                    = None
                                 , data_file            = None
                                 , message_size         = None
                                 , timestep             = None
                                 , hop_probability      = None
                                 , reliable             = None
                                 , hop_method           = None):

        print("Using data file %s" % data_file)
        sender_args = [ str(PathHoppingSender.BIN_DIR)
                      , "-h"           , self.actual_host_ip
                      , "-p"           , port
                      , "-k"           , K
                      , "-n"           , N
                      , "-file"        , data_file
                      , "-m"           , message_size
                      , "-timestep"    , timestep
                      , "-lambda"      , hop_probability
                      , "-reliable"    , reliable
                      , "-hop"         , hop_method
                      ]

        if self._sender_process != None:
            raise ValueError("Attempting to start sender host after already being started.")

        self._sender_process = subprocess.Popen(sender_args, stderr=subprocess.PIPE,
                stdout=subprocess.DEVNULL)

    def stop_path_hopping_sender(self):
        if self._sender_process == None:
            raise ValueError("Attempting to stop path hopping sender without starting it.")

        self._sender_process.terminate()
        _, std_err = self._sender_process.communicate()
        if self._sender_process.returncode != 0:
            print("PathHoppingSender %d failed with error: " % self.host_id)
            print(std_err.decode("utf-8"))
            print("")

    def destroy_virtual_host(self):
        super().destroy_virtual_host()
        if self._sender_process != None:
            self.stop_path_hopping_sender()

class PathHoppingReceiver(VirtualHost):
    BIN_DIR = path.Path("/home/cpsc-net-user/repos/mtd-crypto-impl/endpoint/receiver")

    def __init__(self, host_id, *args):
        super(PathHoppingReceiver, self).__init__(*args)
        self._host_id           = host_id
        self._receiver_process  = None

    @property
    def host_id(self):
        return self._host_id

    @staticmethod
    def create_virtual_host( host_id
                           , virtual_host_mac
                           , virtual_host_ip
                           , actual_host_ip
                           , ingress_node_device_id):
        actual_host_mac, virtual_host_token = \
                VirtualHost.initialize_virtual_host_persistent_state(virtual_host_mac,
                        virtual_host_ip, actual_host_ip, ingress_node_device_id)
        the_virtual_host = PathHoppingReceiver(host_id, actual_host_mac, actual_host_ip,
                virtual_host_mac, virtual_host_ip, ingress_node_device_id, virtual_host_token)
        return the_virtual_host

    def start_path_hopping_receiver( self
                                   , sender_ip              = None
                                   , port                   = None
                                   , data_file              = None
                                   , timestep               = None
                                   , hopping_probability    = None):
        receiver_args = [ str(PathHoppingReceiver.BIN_DIR)
                        , "-h"          , sender_ip
                        , "-p"          , port
                        , "-file"       , data_file
                        , "-timestep"   , timestep
                        , "-lambda"     , hopping_probability
                        , "-local_addr" , self.actual_host_ip
                        ]
        if self._receiver_process != None:
            raise ValueError("Attempting to start receiver host after already being started.")

        self._receiver_process = subprocess.Popen(receiver_args, stderr=subprocess.PIPE,
                stdout=subprocess.DEVNULL)

    def stop_path_hopping_receiver(self):
        if self._receiver_process == None:
            raise ValueError("Attempting to stop path hopping receiver without starting it.")
        self._receiver_process.terminate()
        _, std_err = self._receiver_process.communicate()
        if self._receiver_process.returncode != 0:
            print("PathHoppingReceiver %d failed with error: " % self.host_id)
            print(std_err.decode("utf-8"))
            print("")

    def destroy_virtual_host(self):
        super().destroy_virtual_host()
        if self._receiver_process != None:
            self.stop_path_hopping_receiver()

    def wait_until_done(self):
        if self._receiver_process == None:
            raise ValueError("Attempting to wait on path hopping receiver without starting it.")
        return self._receiver_process.wait()


class Parent1:
    def __init__(self, base1):
        self.base1 = base1

class Parent2:
    def __init__(self, base2):
        self.base2 = base2

class Child(Parent1,  Parent2):
    def __init__(self, base1, base2, base3):

        Parent1.__init__(self, base1)
        Parent2.__init__(self, base2)

        self.base3 = base3

    def format(self):
        self.base3 = "base 3"
        self.base2 = "base 2"

if __name__ == "__main__":

    c = Child("base1", "base2", "base3")

    print(c.base1)
    print(c.base2)
    print(c.base3)

    c.format()

    print(c.base1)
    print(c.base2)
    print(c.base3)


#!/usr/bin/python
'''
	IP Location and Mass IP Location
	Date: 12 NOV 2017 - 15:17
	Respect:  YC - HighTech - EOF Club - Brian - d3m0l1d0r - Cater - Strike - rCent
             Kodo - pr0s3x - CrazyDuck - xin0x - mmxm - CriptonKing - d3z3n0v3 - c0de_universal - All Friends
'''

import requests
import json
import argparse as arg
import sys
import os as sistema

sistema.system("cls" if sistema.name == "nt" else "reset")

parser = arg.ArgumentParser()
parser.add_argument("-i", "--ip", action="store", help="Select target IP")
parser.add_argument("-l", "--list", action="store",  help="Select target IP list")
parser.add_argument("-s", "--save", action="store", help="Select where the tested ips will be saved")
param = parser.parse_args()

save_ = param.save
mass_ = param.list

menu = """
       *                  ((((        *       *
*            *        *  (((
       *    Coded       (((      *
  *   / \      *   by  *(((           *
   __/___\__  *          (((
    | (O) |    v4p0r *    ((((                  *
* __| :-: |__ ... .. .             *.     ... .
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
 # IP Location and Mass IP Location v1
 # Coder: v4p0r
 # Team: Yunkers Crew
 # Skype: drx.priv
 # Twitter: 0x777null
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
 # [+] Usage:
 # python ip_location.py --help
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::"""

banner_single = """
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
 # Search IP
 # I hope this helps you
 # By v4p0r
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::"""

banner_mass = """
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
 # Search IP List
 # I hope this helps you
 # By v4p0r
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::"""

if len(sys.argv) == 1:
	print(menu)
	exit()

def main():

	try:
		single_api = "http://ip-api.com/json/{}" . format(param.ip)
		req = requests.get(single_api)
		single_info = json.loads(req.text)
	except:
		print('[!] Error in connection')
		exit()

	if mass_:
		print(banner_mass)
		ips_ = mass_
		arquivo = open(ips_)
		lines = arquivo.readlines()
		lines = [ip.replace("\n", "") for ip in lines]

		for ip in lines:
			try:
				mass_search(ip)
			except:
				print('[-] Invalid IP Adress')
	else:
		print(banner_single)
		single_search(single_info)

def single_search(single_info):

	try:
		lista_ = []
		print("\n[+] IP: {} \n[+] ORG: {}\n[+] ISP: {}\n[+] AS: {}\n[+] COUNTRY CODE: {}\n[+] COUNTRY: {}\n[+] REGION: {}\n[+] REGION NAME: {}\n[+] CITY: {}\n[+] TIME ZONE: {}\n[+] LATITUDE: {}\n[+] LONGITUDE: {}\n".format(single_info["query"], single_info["org"], single_info["isp"], single_info["as"], single_info["countryCode"], single_info["country"], single_info["region"], single_info["regionName"], single_info["city"], single_info["timezone"], single_info["lat"], single_info["lon"]))
		lista_.append("\n[+] IP: {} \n[+] ORG: {}\n[+] ISP: {}\n[+] AS: {}\n[+] COUNTRY CODE: {}\n[+] COUNTRY: {}\n[+] REGION: {}\n[+] REGION NAME: {}\n[+] CITY: {}\n[+] TIME ZONE: {}\n[+] LATITUDE: {}\n[+] LONGITUDE: {}\n".format(single_info["query"], single_info["org"], single_info["isp"], single_info["as"], single_info["countryCode"], single_info["country"], single_info["region"], single_info["regionName"], single_info["city"], single_info["timezone"], single_info["lat"], single_info["lon"]))
	except:
		print('[-] Invalid IP Adress')

	if save_:
		save_resultados(lista_)

def mass_search(ip):

	lista_ = []
	mass_api = "http://ip-api.com/json/" + ip
	mass_req = requests.get(mass_api)
	mass_info = json.loads(mass_req.text)
	print("\n[+] IP: {} \n[+] ORG: {}\n[+] ISP: {}\n[+] AS: {}\n[+] COUNTRY CODE: {}\n[+] COUNTRY: {}\n[+] REGION: {}\n[+] REGION NAME: {}\n[+] CITY: {}\n[+] TIME ZONE: {}\n[+] LATITUDE: {}\n[+] LONGITUDE: {}\n".format(mass_info["query"], mass_info["org"], mass_info["isp"], mass_info["as"], mass_info["countryCode"], mass_info["country"], mass_info["region"], mass_info["regionName"], mass_info["city"], mass_info["timezone"], mass_info["lat"], mass_info["lon"]))
	lista_.append("\n[+] IP: {} \n[+] ORG: {}\n[+] ISP: {}\n[+] AS: {}\n[+] COUNTRY CODE: {}\n[+] COUNTRY: {}\n[+] REGION: {}\n[+] REGION NAME: {}\n[+] CITY: {}\n[+] TIME ZONE: {}\n[+] LATITUDE: {}\n[+] LONGITUDE: {}\n".format(mass_info["query"], mass_info["org"], mass_info["isp"], mass_info["as"], mass_info["countryCode"], mass_info["country"], mass_info["region"], mass_info["regionName"], mass_info["city"], mass_info["timezone"], mass_info["lat"], mass_info["lon"]))

	if save_:
		save_resultados(lista_)

def save_resultados(list_ip):

	print("[*] Save results...")
	print("[*] =========================================== [*]")
	file = open(save_, "a")
	file = [file.write(str(x_ip) + "\n") for x_ip in list_ip]

try:
	main()
except KeyboardInterrupt:
	exit()


import elasticREST
import logging
import json

def resolveAllocation(endpoint: str, force: bool):
    """Fix Allocation problems"""
    logging.basicConfig(level=logging.INFO)

    allocation_status = elasticREST.allocationExplain(endpoint)
    allocated_indexes = 0

    while 'error' not in allocation_status:
        index = allocation_status['index']
        shard = allocation_status['shard']

        node_id_found = allocation_status['node_allocation_decisions'][0]['node_id']

        for val in allocation_status['node_allocation_decisions']:
            if ('store' in val) and ('allocation_id' in val['store']):
                node_id_found = val['node_id']
                break

        allocation_result = elasticREST.forceAllocation(endpoint, allocation_status, node_id_found)

        if 'acknowledged' in allocation_result:
            logging.info("Index: {}, shard: {} allocation FORCED SUCCESFULLY".format(index, shard))
        else:
            logging.warning("Index {}, shard: {} forced allocation failed!!".format(index, shard), allocation_result)
            if force:
                result = elasticREST.deleteIndex(endpoint, index)
                logging.info(f"FORCE ERASE {index}: {result}")

        allocation_status = elasticREST.allocationExplain(endpoint)
        allocated_indexes += 1

    logging.info('Forced allocation over {} indexes'.format(allocated_indexes))
    return allocated_indexes


# Lab Project by Sarang Dev Saha

# LAB_02 QUE_09
#Read a single digit number from the keyboard and print its corresponding day of week. If number other than 1-7 is entered, print “Invalid Number".

# Forming list of all the days in a week
list=[" " ,'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday']
# Taking a number from the user
a=int(input("Enter a single digit number:"))
# If number is less than or equal to 7
if a<=7:
	print("The day of the week is",list[a])
else:
# Else error message is displayed
	print("Invalid Number")


"""Time Plot Applet"""

from toolbox import *

class TimePlot(Frame):
    def __init__(self, parent):
        Frame.__init__(self, parent)
        self.label = Label(self, text="Time Plot")
        self.label.pack()

if __name__ == "__main__":

    root = Tk()
    TimePlot(root).pack()
    root.mainloop()


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

from mytree import BinaryTree

root = BinaryTree.BinaryTree('root')
b = root.insertRightChild('B')
a = root.insertLeftChild('A')
c = a.insertLeftChild('C')
e = c.insertLeftChild('E')
d = b.insertRightChild('D')
f = d.insertRightChild('F')

root.inOrder()
print()
root.preOrder()
print()
root.postOrder()
print()