import numpy as np
import subprocess
import os
import sys
from Bio import SeqIO
from Bio import PDB
from Bio.PDB.PDBParser import PDBParser
from Bio.PDB.Polypeptide import PPBuilder
from joblib import Parallel, delayed
import multiprocessing as mp
import time
import re
from joblib import Parallel, delayed
import concurrent.futures

class energy_calculation:

    def __init__(self, model_filename, model_dir):
        self.model_filename = model_filename
        self.model_dir = model_dir
        self.model_ID = model_filename.replace("_model.pdb","")
        self.model_path = model_dir + model_filename
        self.origin = "positives"
        self.partition = "1"
        self.model_output_dir = f"/home/projects/ht3_aim/people/idamei/results/energy_calc_full_output/{self.partition}/{self.origin}/{self.model_ID}/"
        #self.model_output_dir = f"/home/projects/ht3_aim/people/idamei/full_output_test/"
        self.numpy_output_dir = f"/home/projects/ht3_aim/people/idamei/results/energy_output_arrays/{self.partition}/{self.origin}/"
        #self.numpy_output_dir = f"/home/projects/ht3_aim/people/idamei/numpy_output_test/"
        if self.origin == "positives":
            self.binder = 1
        else:
            self.binder = 0

    def pipeline(self):
        startstart_time = time.time()
        print("Start " + self.model_filename)

        # Make output directory
        os.makedirs(self.model_output_dir, exist_ok = True)
        os.chdir(self.model_output_dir)

        # Get PDB features
        self.extract_pdb_features()

        # Split pdb
        try:
            self.splitPDB()
        except Exception as err:
            print("Splitting PDB failed for: " + self.model_ID, file=sys.stderr)
            print(err, file=sys.stderr)

        # Run FoldX
        try:
            start_time = time.time()
            self.run_foldx()
            runtime = (time.time() - start_time) / 60
            print("FoldX took {} min".format(runtime))
        except Exception as err:
            print("FoldX failed for: " + self.model_ID, file=sys.stderr)
            print(err, file=sys.stderr)

        # Extract foldX energies
        try:
            self.extract_foldx_energies()
        except Exception as err:
            print("Extracting foldX energies failed for: " + self.model_ID, file=sys.stderr)
            print(err, file=sys.stderr)

        # Run Rosetta
        try:
            start_time = time.time()
            self.rosetta_scorefile_path_complex, self.rosetta_per_res_scorefile_path_complex = self.run_rosetta(self.model_path)
            runtime = (time.time() - start_time) / 60
            print("Rosetta for complex took {} min".format(runtime))
            start_time = time.time()
            self.rosetta_scorefile_path_tcr, self.rosetta_per_res_scorefile_path_tcr = self.run_rosetta(self.tcr_path)
            runtime = (time.time() - start_time) / 60
            print("Rosetta for TCR took {} min".format(runtime))
            start_time = time.time()
            self.rosetta_scorefile_path_pmhc, self.rosetta_per_res_scorefile_path_pmhc = self.run_rosetta(self.pmhc_path)
            runtime = (time.time() - start_time) / 60
            print("Rosetta for pMHC took {} min".format(runtime))
        except Exception as err:
            print("Rosetta failed for: " + self.model_ID, file=sys.stderr)
            print(err, file=sys.stderr)

        # Extract Rosetta energies
        try:
            self.rosetta_overall_scores_complex, self.rosetta_per_res_scores_complex = self.extract_rosetta_energies(
                self.rosetta_scorefile_path_complex,
                self.rosetta_per_res_scorefile_path_complex)
            self.rosetta_overall_scores_tcr, self.rosetta_per_res_scores_tcr = self.extract_rosetta_energies(
                self.rosetta_scorefile_path_tcr,
                self.rosetta_per_res_scorefile_path_tcr)
            self.rosetta_overall_scores_pmhc, self.rosetta_per_res_scores_pmhc = self.extract_rosetta_energies(
                self.rosetta_scorefile_path_pmhc,
                self.rosetta_per_res_scorefile_path_pmhc)
        except Exception as err:
            print("Extracting Rosetta energies failed for: " + self.model_ID, file=sys.stderr)
            print(err, file=sys.stderr)

        # Create output
        try:
            self.create_output()
        except Exception as err:
            print("Creating output failed for: " + self.model_ID, file=sys.stderr)
            print(err, file=sys.stderr)

        runtime = (time.time() - startstart_time) / 60
        print("{} took {} min".format(self.model_ID, runtime))

    def run_foldx(self):

        # RepairPDB
        if not os.path.exists(self.model_filename.replace(".pdb", "_Repair.pdb")):
            repair_command = "foldx --command=RepairPDB --pdb={} --ionStrength=0.05 --pH=7 --water=CRYSTAL --vdwDesign=2 --out-pdb=1 --pdbHydrogens=false --output-dir={}".format(self.model_filename, self.model_output_dir)
            subprocess.run(repair_command.split(), universal_newlines=True, stdout=subprocess.PIPE, cwd=self.model_dir)

        # AnalyseComplex
        repaired_pdb_path = self.model_filename.replace(".pdb", "_Repair.pdb")
        analyse_command = "foldx --command=AnalyseComplex --pdb={} --output-dir={}".format(repaired_pdb_path,
                                                                                self.model_output_dir)
        subprocess.run(analyse_command.split(), universal_newlines=True, stdout=subprocess.PIPE, cwd=self.model_output_dir)

    def extract_foldx_energies(self):
        self.interaction_file_path = self.model_output_dir + "Interaction_" + self.model_filename.replace(".pdb",
                                                                                "_Repair_AC.fxout")
        foldx_output = open(self.interaction_file_path, "r")
        foldx_interaction_energies = dict()
        for line in foldx_output:
            if line.startswith("./"):
                splitted_line = line.split("\t")
                group1 = splitted_line[1]
                group2 = splitted_line[2]
                interaction_energy = splitted_line[6]
                foldx_interaction_energies[group1 + group2] = float(interaction_energy)
        foldx_output.close()
        self.foldx_interaction_energies = foldx_interaction_energies

    def run_rosetta(self, infile):

        # Relaxation
        rosetta_relax_command = "relax.default.linuxgccrelease \
                                -ignore_unrecognized_res \
                                -nstruct 1 \
                                -s {} \
                                -out:path:pdb {}".format(infile, self.model_output_dir)
        subprocess.run(rosetta_relax_command.split(), universal_newlines=True, stdout=subprocess.PIPE, cwd=self.model_output_dir)

        # Scoring
        result = re.search(r'/([^/]+)$', infile)
        infilename = result.group(1)
        relaxed_pdb_path = self.model_output_dir + infilename.replace(".pdb", "_0001.pdb")
        rosetta_scorefile_path = self.model_output_dir + infilename + "_score.sc"
        rosetta_score_command = "score_jd2.linuxgccrelease \
                                -in:file:s {} \
                                -out:file:scorefile {}".format(relaxed_pdb_path, rosetta_scorefile_path)
        subprocess.run(rosetta_score_command.split(), universal_newlines=True, stdout=subprocess.PIPE, cwd=self.model_output_dir)

        # Per residue scoring
        rosetta_per_res_scorefile_path = self.model_output_dir + infilename + "_per_residue_score.sc"
        rosetta_per_res_score_command = "per_residue_energies.linuxgccrelease \
                                        -in:file:s {} \
                                        -out:file:silent {}".format(relaxed_pdb_path, rosetta_per_res_scorefile_path)
        subprocess.run(rosetta_per_res_score_command.split(), universal_newlines=True, stdout=subprocess.PIPE, cwd=self.model_output_dir)

        return rosetta_scorefile_path, rosetta_per_res_scorefile_path

    def extract_rosetta_energies(self, rosetta_scorefile_path, rosetta_per_res_scorefile_path):
        # Rosetta overall energies
        rosetta_scorefile = open(rosetta_scorefile_path, "r")
        rosetta_scorefile.readline()
        rosetta_scorefile.readline()
        # SCORE: total_score       score dslf_fa13    fa_atr    fa_dun   fa_elec fa_intra_rep fa_intra_sol_xover4              fa_rep              fa_sol hbond_bb_sc hbond_lr_bb    hbond_sc hbond_sr_bb linear_chainbreak lk_ball_wtd       omega overlap_chainbreak            p_aa_pp pro_close rama_prepro         ref        time yhh_planarity description
        line = rosetta_scorefile.readline()
        splitted_line = line.strip().split()
        rosetta_overall_scores = splitted_line[1:-1]  # 24 elements
        rosetta_overall_scores = [float(x) for x in rosetta_overall_scores]
        rosetta_scorefile.close()

        # Rosetta per residue energies
        rosetta_per_res_scorefile = open(rosetta_per_res_scorefile_path, "r")
        rosetta_per_res_scores = {"M": {}, "P": {}, "A": {}, "B": {}}
        # SCORE:     pose_id     pdb_id     fa_atr     fa_rep     fa_sol    fa_intra_rep    fa_intra_sol_xover4    lk_ball_wtd    fa_elec    pro_close    hbond_sr_bb    hbond_lr_bb    hbond_bb_sc    hbond_sc    dslf_fa13      omega     fa_dun    p_aa_pp    yhh_planarity        ref    rama_prepro      score description
        for line in rosetta_per_res_scorefile:
            splitted_line = line.strip().split()
            if splitted_line[1] == "pose_id":
                continue
            pdb_id = splitted_line[2]
            chain = pdb_id[-1]
            position = int(pdb_id[:-1])
            rosetta_per_res_scores[chain][position] = [float(x) for x in splitted_line[3:-1]]  # 20 elements
        rosetta_scorefile.close()

        return rosetta_overall_scores, rosetta_per_res_scores

    def create_output(self):
        # Output array:
        # one-hot AA (20), M (1), P (1), TCRA (1), TCRB (1)
        # Rosetta_per_res_indiv_energies_complex (20), Rosetta_per_res_indiv_energies_pmhc/Rosetta_per_res_indiv_energies_tcr (20)
        # foldx_MP (1), foldx_MA (1), foldx_MB (1), foldx_PA (1), foldx_PB (1), foldx_AB (1),
        # Rosetta_total_energy_complex (24), Rosetta_total_energy_tcr (24), Rosetta_total_energy_pmhc (24),
        # Positive/negative (1), origin (10X, swapped, posi) (3) WAS REMOVED LATER
        # Total: 142

        output_array = np.zeros(shape=(self.total_length, 146))
        k1 = 0  # chain
        k2 = 0  # residue number total
        for chain in self.sequences:
            sequence = self.sequences[chain]
            k1 += 1
            k3 = 0  # chain residue number
            for aminoacid in sequence:
                number = self.numbering[chain][k3]
                output_array[k2, 0:20] = self.oneHot(aminoacid)
                if chain == "M":
                    output_array[k2, 20:24] = np.array([1, 0, 0, 0])
                    output_array[k2, 24:44] = self.rosetta_per_res_scores_complex["M"][number]
                    output_array[k2, 44:64] = self.rosetta_per_res_scores_pmhc["M"][number]
                if chain == "P":
                    output_array[k2, 20:24] = np.array([0, 1, 0, 0])
                    output_array[k2, 24:44] = self.rosetta_per_res_scores_complex["P"][number]
                    output_array[k2, 44:64] = self.rosetta_per_res_scores_pmhc["P"][number]
                if chain == "A":
                    output_array[k2, 20:24] = np.array([0, 0, 1, 0])
                    output_array[k2, 24:44] = self.rosetta_per_res_scores_complex["A"][number]
                    output_array[k2, 44:64] = self.rosetta_per_res_scores_tcr["A"][number]
                if chain == "B":
                    output_array[k2, 20:24] = np.array([0, 0, 0, 1])
                    output_array[k2, 24:44] = self.rosetta_per_res_scores_complex["B"][number]
                    output_array[k2, 44:64] = self.rosetta_per_res_scores_tcr["B"][number]
                output_array[k2, 64:70] = list(self.foldx_interaction_energies.values())
                output_array[k2, 70:94] = self.rosetta_overall_scores_complex
                output_array[k2, 94:118] = self.rosetta_overall_scores_tcr
                output_array[k2, 118:142] = self.rosetta_overall_scores_pmhc
                output_array[k2, 142] = self.binder
                if self.origin == "tenx_negatives":
                    output_array[k2, 143:146] = np.array([1, 0, 0])
                elif self.origin == "swapped_negatives":
                    output_array[k2, 143:146] = np.array([0, 0, 1])
                else:
                    output_array[k2, 143:146] = np.array([0, 0, 1])
                k2 += 1
                k3 += 1
        np.save(file=self.numpy_output_dir + self.model_ID + ".npy", arr=output_array)

    def extract_pdb_features(self):

        # Get chain names and sequence numbering
        pdb_file = open(self.model_path, "r")
        numbering = {"M": [], "P": [], "A": [], "B": []}
        chain_names = []
        old_number = 0
        old_chain = ""
        for line in pdb_file:
            splitted_line = line.split()
            if splitted_line[0] != "ATOM":
                continue
            chain = splitted_line[4]
            if chain != old_chain:
                chain_names.append(chain)
                old_chain = chain
            new_number = splitted_line[5]
            if new_number != old_number:
                numbering[chain].append(int(new_number))
                old_number = new_number

        # Get sequences
        structure = PDBParser().get_structure('', self.model_path)
        ppb = PPBuilder()
        chain_sequences = {}
        i = 0
        for pp in ppb.build_peptides(structure):
            chain_name = chain_names[i]
            chain_sequences[chain_name] = str(pp.get_sequence())
            i += 1

        self.chain_names = chain_names
        self.sequences = chain_sequences
        self.numbering = numbering
        self.length_A = len(chain_sequences["A"])
        self.length_B = len(chain_sequences["B"])
        self.length_M = len(chain_sequences["M"])
        self.length_P = len(chain_sequences["P"])
        self.total_length = self.length_P + self.length_M + self.length_B + self.length_A

    @staticmethod
    def oneHot(residue):
        mapping = dict(zip("ACDEFGHIKLMNPQRSTVWY", range(20)))
        if residue in "ACDEFGHIKLMNPQRSTVWY":
            return np.eye(20)[mapping[residue]]
        else:
            return np.zeros(20)

    @staticmethod
    def selectChain(ifn, ofn, chainID):
        """Saves selected chains from PDB in a new PDB"""
        parser = PDB.PDBParser()
        structure = parser.get_structure('x', ifn)

        class ChainSelector():
            def __init__(self, chainID=chainID):
                self.chainID = chainID

            def accept_chain(self, chain):
                if chain.get_id() in self.chainID:
                    return 1
                return 0

            def accept_model(self, model):
                return 1

            def accept_residue(self, residue):
                return 1

            def accept_atom(self, atom):
                return 1

        sel = ChainSelector(chainID)
        io = PDB.PDBIO()
        io.set_structure(structure)
        io.save(ofn, sel)

    def splitPDB(self):

        self.tcr_path = self.model_output_dir + "TCR.pdb"
        self.pmhc_path = self.model_output_dir + "pMHC.pdb"
        self.selectChain(ifn=self.model_path, ofn=self.tcr_path, chainID=["A", "B"])
        self.selectChain(ifn=self.model_path, ofn=self.pmhc_path, chainID=["M", "P"])

def worker(model_filename):

    instance = energy_calculation(model_filename, model_dir)
    instance.pipeline()

origin = "positives"
partition = "1"
model_dir = f"/home/projects/ht3_aim/people/idamei/results/models/{partition}/{origin}/"
p = subprocess.Popen(["ls", model_dir],
                     stdout=subprocess.PIPE, universal_newlines=True)
models = p.communicate()[0].split()
if "molecules" in models:
    models.remove("molecules")
if "rotabase.txt" in models:
    models.remove("rotabase.txt")

#pool = mp.Pool(40)
#pool.map(worker, [model for model in models])
#pool.close()

#models_slice = models[108:118]
#print(len(models[118:]))
#models_slice = models[118:]

models_slice = ["12528_model.pdb"]

Parallel(n_jobs=20)(delayed(worker)(model) for model in models_slice)


def get_square():
    l1=[x**2 for x in range(0,21) if ((x%2 == 0) and (x%3 != 0 ))]
    return l1

print(get_square())

def list_of_even_odds():
    l1 = [x for x in range(0,21) if x%2 == 0]
    l2 = [y for y in range(0,21) if y%2 != 0]
    return [l1, l2]

print(list_of_even_odds())

# write an entire expression in a list. This is called List Comprehension
print([x*x for x in range(2, 5, 2) if x % 2 == 0])
print([x**3 for x in range(1,21)])
g = [2, 3]
i = [1, 2, 3, 4]
avg = sum(i)/len(i)

print(avg)

for elem in g:
    i.remove(elem)

print(i)

m = ['mango']
l = ['w', 1, 'r', 3.5]
print(l + m)
l.append(m)
print(l)
# print(str(l))
# print(l)
#first index val is inclusive and the last value is exclusive
print(l[1:2])

def change_case(s):
    lower_s = s.lower()
    upper_s = s.upper()
    return [lower_s, upper_s]

print(change_case('aaBBccDFg'))

def find_occurence(s):
    end = (len(s) - 1)
    start = 0
    a = s.find('a')
    b = s.find('b')
    # a = s.find('a', start, end)
    # b = s.find('b', start, end)
    return [a, b]

print(find_occurence('aaacccbbbddd'))

def get_str(s):
    s2 = ''
    for c in s:
        s2 += c*3
    strlen = len(s2)
    return [s, strlen, s2]

print(get_str('acbd'))

# the return statement evaluates the function to true or false
def in_range_again(x,y):
    return (x < 1/3 < y)

print(in_range_again(0.1,0.2))

def in_range(x,y):
    if(x < 1/3 < y):
        return True
    else:
        return False

print(in_range(0.2,0.3))

def parity(n):
    return n%2

print(str(parity(5)))

def math_op():
    division = 3 / 2
    floor_division = 3 // 2
    modulus = 3 % 2
    power = 3 ** 2
    p = pow(3, 2)
    return [division, floor_division, modulus, power, p]

[div, fl, md, pwer, w] = math_op()

print(div)
print(fl)
print(md)
print(pwer)
print(w)


import requests

class YaDisk:

    base_url = 'https://cloud-api.yandex.net/v1/disk/'

    def __init__(self, token):
        self.token = token

    def get_headers(self):
        return {
            'Content-Type': 'application/json',
            'Authorization': f'OAuth {self.token}'
        }

    def create_folder(self, folder_name):
        yandex_api_url = f'{self.base_url}resources'
        headers = self.get_headers()
        params = {
            'path': folder_name
        }

        response = requests.put(yandex_api_url, headers=headers, params=params)
        if response.status_code == 201:
            return True
        elif response.status_code == 409:
            print('The folder already exists on Yandex.Disk.')
            return True
        else:
            print('Failed to create folder on Yandex.Disk.')

    def upload_photo(self, folder_name, file_name, file_url):
        yandex_api_url = f'{self.base_url}resources/upload'
        headers = self.get_headers()
        params = {
            'path': f'{folder_name}/{file_name}',
            'url': file_url,
            'overwrite': False
        }

        response = requests.post(yandex_api_url, headers=headers, params=params)
        data = response.json()

        if 'href' in data:
            return True
        elif response.status_code == 409:
            print(f'The file {file_name} already exists on Yandex.Disk.')
        else:
            print(f'Failed to upload photo to Yandex.Disk: {data}')


import random
import time
import tweepy
import pandas
import logging
from config import consumer_key, consumer_secret, access_token, access_token_secret

#Declare variables
timer = 10800 # three hours
df = pandas.read_csv('quotes.csv', delimiter='*')
index = df.index
number_of_rows = len(index)

logger = logging.getLogger('MotivatorBot')
hdlr = logging.FileHandler('./motivatorbot.log')
formatter = logging.Formatter('%(asctime)s %(levelname)s %(message)s')
hdlr.setFormatter(formatter)
logger.addHandler(hdlr)
# logger.setLevel(logging.info)

# authenticate the consumer key and secret
auth = tweepy.OAuthHandler(consumer_key,consumer_secret)

# authentication of access token and secret
auth.set_access_token(access_token,access_token_secret)
api = tweepy.API(auth)

# Get a follower and add return their tag to add to the string to be sent
def getUser():
    follows = []
    for follower in tweepy.Cursor(api.followers).items():
        follows.append(follower.screen_name)
    # Random number to choose user
    follow_rand = random.randint(0,(len(follows)-1))
    followName = follows[follow_rand]
    preString = "Hey @{f} ".format(f=followName)

    return preString

# Get a quote from th CSV
def getQuote():
    quote_picker = random.randint(0,(number_of_rows - 1))
    quote = df['quote'][quote_picker]
    author = df['author'][quote_picker]
    quoteFormat = "{quote} -{author} ".format(quote=quote, author=author)

    return quoteFormat

# This is the main loop.
while True:
    print('starting Loop')
    quoteString = ''
    userChoose = random.randint(0,3)
    if userChoose <1:
        quoteString += getUser()

    quoteString +=  getQuote()
    sleepSecs = random.randint(600,timer)
    print(quoteString)
    print(sleepSecs)
    #Try the API Call. One possible error is 187, which is an error coming from Twitter that limits tweeting the same tweet out multiple times.
    # I can't find any documentation from Twitter on the timeframe tht they're looking for, so what I'm doing is going back to the start of
    # the loop if I see an error, because the liklihood that it will come back with another quote that will violate Twitter's policies is slim
    # to none, and even if it does it will just keep trying quotes until it gets something that works.
    try:
        api.update_status(status = quoteString)
        logging.info('SUCCESS! - %s', quoteString)
    except tweepy.TweepError as e:
        logging.error(e.reason)
        print('Error Code', e.api_code)
        print('Reason ', e.reason)
        continue

    time.sleep(sleepSecs)


"""

problem 15

Starting in the top left corner of a  grid and
moving only down and right, there are 6 routes to the bottom right corner.

How many routes are there through a 20x20 grid?
"""

def route_num(cube_size):
    L = [1] * cube_size
    for i in range(cube_size):
        for j in range(i):
            L[j] = L[j]+L[j-1]
        L[i] = 2 * L[i - 1]
    return L[cube_size - 1]


# -*- coding: utf-8 -*-
import json
import requests
def get_proxy():
    response = requests.get('')
    res = json.loads(response.text)
    if res['code'] == 0:
        try:
            ip = res['data']['IP']
            port = res['data']['PORT']
            proxy = {}
            proxy['http'] = ip+":"+port
            return proxy
        except Exception as e:
            return None


# -*- coding: utf-8 -*-
from instrument import Instrument
import instruments
import numpy
import types
import logging

class virtual_period(Instrument):
    '''
    This is the driver to handle period.
    '''

    def __init__(self, name, pulser):
        '''
            Initialize the virtual instruments

                Input:
                    name            : Name of the virtual instruments
                    pulser          : Name given to the pulser

                Output:
                    None
        '''

        Instrument.__init__(self, name, tags=['virtual'])

        self.add_parameter('period', units='ns',  flags=Instrument.FLAG_GETSET | Instrument.FLAG_GET_AFTER_SET, type=types.FloatType)
        self.add_parameter('cooling_time', units='ns', flags=Instrument.FLAG_GETSET, type=types.FloatType)
        self.add_parameter('origin', units='ns', flags=Instrument.FLAG_GETSET, type=types.FloatType)

        # Defining some stuff
        self._instruments = instruments.get_instruments()
        self._pulser = self._instruments.get(pulser)

        self._cooling_time = 1e3 #in [ns]
        self._origin = 0. #in [ns]

        self.get_all()

    def get_all(self):
        '''
            Get all parameters of the virtual device

            Input:
                None

            Output:
                None
        '''
        self.get_period()

#########################################################
#
#
#                Period
#
#
#########################################################

    def do_set_period(self, period):
        '''
            set the period of the instrument

            Input:
                period (float): period of the pulser[ns]

            Output:
                None
        '''

        logging.info(__name__+' : set the period of the pulser')
        self._pulser.set_period(period)

    def do_get_period(self):
        '''
            Get the period of the instrument

            Input:
                None

            Output:
                period (float): period of the pulser[ns]
        '''

        logging.info(__name__+' : Get the period of the pulser')
        return float(self._pulser.get_period())

#########################################################
#
#
#                cooling time
#
#
#########################################################

    def do_set_cooling_time(self, cooling_time=1e3):
        '''
            Set the cooling_time of the pulser

            Input:
                cooling_time (float): cooling_time of the pulser [ns]

            Output:
                None
        '''

        logging.info(__name__+' : Set the cooling_time of the pulser')

        self._cooling_time = cooling_time
        period1 = self.get_period()
        period = self.get_origin() + self._pulser.get_chA_width()
        period = max(period, period1) #added by Remy
        self.set_period(period + cooling_time)

    def do_get_cooling_time(self):
        '''
            Get the cooling time

            Input:
                None

            Output:
                period (float): cooling time [ns]
        '''

        logging.info(__name__+' : Get the cooling time')
        return float(self._cooling_time)

#########################################################
#
#
#                Origin
#
#
#########################################################

    def do_set_origin(self, origin=1e3):
        '''
            Set the origin of the pulses

            Input:
                origin (float): origin of the pulses [ns]

            Output:
                None
        '''

        logging.info(__name__+' : Set the origin of the pulses')

        self._origin = origin
        oldPeriod = self.get_period()

        cooling_time = self.get_cooling_time()
        periodA = origin                       + self._pulser.get_chA_width() + cooling_time
        periodC = self._pulser.get_chC_delay() + self._pulser.get_chC_width() + cooling_time
        periodD = self._pulser.get_chD_delay() + self._pulser.get_chD_width() + cooling_time
        newPeriod = max(periodA, periodC, periodD)

        #If the new period is longer than the old,
        #We set first the period and next we change the delaies
        if newPeriod > oldPeriod:

            self.set_period(newPeriod)
            boardDelay = self._pulser.get_chB_delay() - self._pulser.get_chA_delay()
            self._pulser.set_chA_delay(origin)
            self._pulser.set_chB_delay(origin + boardDelay)
        else:

            boardDelay = self._pulser.get_chB_delay() - self._pulser.get_chA_delay()
            self._pulser.set_chA_delay(origin)
            self._pulser.set_chB_delay(origin + boardDelay)
            self.set_period(newPeriod)

    def do_get_origin(self):
        '''
            Get the origin of the pulses

            Input:
                None

            Output:
                period (float): origin of the pulses [ns]
        '''

        logging.info(__name__+' : Get the origin of the pulses')
        return float(self._origin)


# Copyright (c) Meta Platforms, Inc. and affiliates.

# All rights reserved.

# This source code is licensed under the license found in the
# LICENSE file in the root directory of this source tree.

import torch, numpy as np, os
import torch.nn as nn
import torch.nn.functional as F
from timm.models.layers import trunc_normal_, DropPath

PAD_TOKEN = 50256

# Constants that should not be changed due to some hard-coded values in the original ConvNext-base model
VOCAB_SIZE, N_EMDB, N_POSITIONS = 50257, 768, 1024

class GRN(nn.Module):
    """ GRN (Global Response Normalization) layer
    """
    def __init__(self, dim):
        super().__init__()
        self.gamma = nn.Parameter(torch.zeros(1, 1, 1, dim))
        self.beta = nn.Parameter(torch.zeros(1, 1, 1, dim))

    def forward(self, x):
        Gx = torch.norm(x, p=2, dim=(1,2), keepdim=True)
        Nx = Gx / (Gx.mean(dim=-1, keepdim=True) + 1e-6)
        return self.gamma * (x * Nx) + self.beta + x

class LayerNorm(nn.Module):
    """ LayerNorm that supports two data formats: channels_last (default) or channels_first.
    The ordering of the dimensions in the inputs. channels_last corresponds to inputs with
    shape (batch_size, height, width, channels) while channels_first corresponds to inputs
    with shape (batch_size, channels, height, width).
    """
    def __init__(self, normalized_shape, eps=1e-6, data_format="channels_last"):
        super().__init__()
        self.weight = nn.Parameter(torch.ones(normalized_shape))
        self.bias = nn.Parameter(torch.zeros(normalized_shape))
        self.eps = eps
        self.data_format = data_format
        if self.data_format not in ["channels_last", "channels_first"]:
            raise NotImplementedError
        self.normalized_shape = (normalized_shape, )

    def forward(self, x):
        if self.data_format == "channels_last":
            return F.layer_norm(x, self.normalized_shape, self.weight, self.bias, self.eps)
        elif self.data_format == "channels_first":
            u = x.mean(1, keepdim=True)
            s = (x - u).pow(2).mean(1, keepdim=True)
            x = (x - u) / torch.sqrt(s + self.eps)
            x = self.weight[:, None, None] * x + self.bias[:, None, None]
            return x

class Block(nn.Module):
    """ Generator Block.

    Args:
        dim (int): Number of input channels.
        drop_path (float): Stochastic depth rate. Default: 0.0
    """
    def __init__(self, dim, drop_path=0.):
        super().__init__()
        self.dwconv = nn.Conv2d(dim, dim, kernel_size=7, padding=3, groups=dim) # depthwise conv
        self.norm = LayerNorm(dim, eps=1e-6)
        self.pwconv1 = nn.Linear(dim, 4 * dim) # pointwise/1x1 convs, implemented with linear layers
        self.act = nn.GELU()
        self.grn = GRN(4 * dim)
        self.pwconv2 = nn.Linear(4 * dim, dim)
        self.drop_path = DropPath(drop_path) if drop_path > 0. else nn.Identity()

    def forward(self, x):
        input = x
        x = self.dwconv(x)
        x = x.permute(0, 2, 3, 1) # (N, C, H, W) -> (N, H, W, C)
        x = self.norm(x)
        x = self.pwconv1(x)
        x = self.act(x)
        x = self.grn(x)
        x = self.pwconv2(x)
        x = x.permute(0, 3, 1, 2) # (N, H, W, C) -> (N, C, H, W)

        x = input + self.drop_path(x)
        return x

class Generator(nn.Module):
    """ ConvNeXt V2

    Args:
        in_chans (int): Number of input image channels. Default: 3
        num_classes (int): Number of classes for classification head. Default: 1000
        depths (tuple(int)): Number of blocks at each stage. Default: [3, 3, 9, 3]
        dims (int): Feature dimension at each stage. Default: [96, 192, 384, 768]
        drop_path_rate (float): Stochastic depth rate. Default: 0.
        head_init_scale (float): Init scaling value for classifier weights and biases. Default: 1.
    """
    def __init__(self, in_chans=3, depths=[3, 3, 20, 3], dims=[128, 256, 512, 1024], drop_path_rate=0., head_init_scale=1.):
        super().__init__()

        # Stem and 3 intermediate downsampling conv layers
        self.downsample_layers = nn.ModuleList()
        stem = nn.Sequential(
            nn.Conv2d(in_chans, dims[0], kernel_size=4, stride=4),
            LayerNorm(dims[0], eps=1e-6, data_format="channels_first")
        )
        self.downsample_layers.append(stem)
        for i in range(3):
            downsample_layer = nn.Sequential(
                    LayerNorm(dims[i], eps=1e-6, data_format="channels_first"),
                    nn.Conv2d(dims[i], dims[i+1], kernel_size=2, stride=2),
            )
            self.downsample_layers.append(downsample_layer)

        # 4 feature resolution stages, each consisting of multiple residual blocks
        self.stages = nn.ModuleList()
        dp_rates=[x.item() for x in torch.linspace(0, drop_path_rate, sum(depths))]
        cur = 0
        for i in range(4):
            stage = nn.Sequential(
                *[Block(dim=dims[i], drop_path=dp_rates[cur + j]) for j in range(depths[i])]
            )
            self.stages.append(stage)
            cur += depths[i]

        self.wte = nn.Embedding(VOCAB_SIZE, N_EMDB)
        self.wpe = nn.Embedding(N_POSITIONS, N_EMDB)

        # Final norm layer (not used in this implementation)
        # self.norm = nn.LayerNorm(dims[-1], eps=1e-6)

        self.pre_head = nn.ConvTranspose1d(dims[-1], 1024, kernel_size=12, stride=12)

        self.head = nn.Linear(self.wte.weight.shape[1], self.wte.weight.shape[0], bias=False)
        self.head.weight = self.wte.weight

        self.softmax = nn.Softmax(dim=1)

        self.apply(self._init_weights)

    def pad_indices(self, indices):

        if indices.shape[1] < N_POSITIONS:
            indices = torch.nn.functional.pad(indices, (0, N_POSITIONS - indices.shape[1]), value=50256)
        else:
            indices = indices[-N_POSITIONS:]
        return indices

    def build_image(self, patches):
        # patches: (B, 1024, 3, 16, 16)
        image = torch.zeros((patches.shape[0], 3, 256, 256)).cuda()
        for i in range(16):
            for j in range(16):
                image[:, :, i*16:(i+1)*16, j*16:(j+1)*16] = patches[:, i*16+j, :, :, :]

        return image

    def _init_weights(self, m):
        if isinstance(m, (nn.Conv2d, nn.Linear)):
            # Check if bias is present (ignore final logit output layer)
            if m.bias is not None:
                trunc_normal_(m.weight, std=.02)
                nn.init.constant_(m.bias, 0)

    def forward_features(self, x):
        for i in range(4):
            x = self.downsample_layers[i](x)
            x = self.stages[i](x)

        # global average pooling, (N, C, H, W) -> (N, C) (not used in this implementation)
        # return self.norm(x.mean([-2, -1]))

        # [B, 1024, 8, 8] -> [B, 1024, 64]
        x = x.view(x.shape[0], x.shape[1], -1)
        x = self.pre_head(x)
        return x

    def forward(self, input_ids):
        # Reverse the order of the tokens
        input_ids = torch.flip(input_ids, [1])

        # Padd with 50256
        input_ids = self.pad_indices(input_ids)

        # Prepare the position ids / embeddings
        position_ids = torch.arange(0, input_ids.size(-1) + 0, dtype=torch.long, device=input_ids.device)
        position_ids = position_ids.unsqueeze(0).expand_as(input_ids)

        input_ids = input_ids.view(-1, input_ids.size(-1))
        position_ids = position_ids.view(-1, position_ids.size(-1))

        # Embeddings and position encoding
        x = self.wte(input_ids) + self.wpe(position_ids)

        # Reshape to (B, 1024, 3, 16, 16)
        x = torch.reshape(x, (x.shape[0], x.shape[1], 3, 16, 16))

        # Build an image from the patches
        x = self.build_image(x)

        # Run though the convnet
        x = self.forward_features(x)

        # Output logits
        x = self.head(x)

        return x[:, -1]


kaas1 = input ("Is de kaas geel? ")
if kaas1 == "ja":
        ask1 = input ("Zitten er gaten in? ")
        if ask1 == "ja":
                ask2 = input("Is de kaas belachelijk duur? ")
                if ask2 == "ja":
                    print("Emmenthaler")
                elif ask2 == "nee":
                    print ("Leerdammer")

        if ask1 == "nee":
            ask3 = input ("Is de kaas hard als steen? ")
            if ask3 == "ja":
                print ("Parmigiano Reggiano ")
            elif ask3 == "nee":
                print ("Goudse kaas")

if kaas1 =="nee":
    ask4 = input ("Heeft de kaas blauwe schimmels? ")
    if ask4 == "ja":
        ask5 = input ("Heeft de kaas een korst? ")
        if ask5 == "ja":
            print ("Blue de Rochbaron")
        elif ask6 == "nee":
            print ("Foume d'Ambert")

    if ask4 == "nee":
        ask6 = input ("Heeft de kaas een korst? ")
        if ask6 == "ja":
            print("Camembert")
        elif ask6 == "nee":
            print("Mozzarella")

else:
    print ("invalid option")


import turtle
import numpy as np

m = int(input())
turtle.shape('turtle')
turtle.penup()
turtle.forward(200)
turtle.pendown()
turtle.left(90)
def hcircle (n, r):
    for i in range(n//2):
        turtle.forward(2*np.pi*r/n)
        turtle.left(360/n)
for i in range (m):
    hcircle (100,50)
    hcircle(50,10)


from collections import namedtuple

from dagster import check
from dagster.core.definitions.logger import LoggerDefinition
from dagster.core.definitions.pipeline import PipelineDefinition

class InitLoggerContext(
    namedtuple('InitLoggerContext', 'logger_config pipeline_def logger_def run_id')
):
    '''Logger-specific initialization context.

    An instance of this class is made available as the first argument to the ``logger_fn`` decorated
    by :py:func:`@logger <logger>` or set on a :py:class:`LoggerDefinition`.

    Users should not instantiate this class.

    Attributes:
        logger_config (Any): The configuration data provided by the environment config. The
            schema for this data is defined by ``config_field`` on the :py:class:`LoggerDefinition`
        pipeline_def (PipelineDefinition): The pipeline definition currently being executed.
        logger_def (LoggerDefinition): The logger definition for the logger being constructed.
        run_id (str): The ID for this run of the pipeline.
    '''

    def __new__(cls, logger_config, pipeline_def, logger_def, run_id):
        return super(InitLoggerContext, cls).__new__(
            cls,
            logger_config,
            check.inst_param(pipeline_def, 'pipeline_def', PipelineDefinition),
            check.inst_param(logger_def, 'logger_def', LoggerDefinition),
            check.str_param(run_id, 'run_id'),
        )


import sys
import bleAdapter
from bleAdapter import bleAdapter
import time
import testutils
import dbus.mainloop.glib
try:
    from gi.repository import GObject
except ImportError:
    import gobject as GObject

# Config for enable/disable test case
ENABLE_TC_AFQP_SECONDARY_SERVICE = 0

class runTest:
    mainloop = GObject.MainLoop()

    DUT_GENERIC_STRING = "hello"
    DUT_FAIL_STRING = "fail"
    DUT_OPEN_CHAR_UUID = "8a7f1168-48af-4efb-83b5-e679f9320002"
    DUT_OPEN_DESCR_UUID = "8a7f1168-48af-4efb-83b5-e679f9320008"
    DUT_WRITE_NO_RESP_CHAR_UUID = "8a7f1168-48af-4efb-83b5-e679f9320005"
    DUT_NOTIFY_CHAR_UUID = "8a7f1168-48af-4efb-83b5-e679f9320006"
    DUT_INDICATE_CHAR_UUID = "8a7f1168-48af-4efb-83b5-e679f9320007"

    DUT_ENCRYPT_CHAR_UUID = "8a7f1168-48af-4efb-83b5-e679f9320003"
    DUT_ENCRYPT_DESCR_UUID = "8a7f1168-48af-4efb-83b5-e679f9320009"

    DUT_UUID_128 = "8a7f1168-48af-4efb-83b5-e679f932db5a"
    DUT_UUID_16 = "abcd"
    DUT_SERVICEB_UUID = "8a7f1168-48af-4efb-83b5-e679f9320001"
    DUT_SERVICEC_UUID = "3113a187-4b9f-4f9a-aa83-c614e11b0002"
    DUT_CHAR = {"8a7f1168-48af-4efb-83b5-e679f9320002": {"Flags": "read, write"},
                "8a7f1168-48af-4efb-83b5-e679f9320003": {"Flags": "read, write"},
                "8a7f1168-48af-4efb-83b5-e679f9320004": {"Flags": "read, write"},
                "8a7f1168-48af-4efb-83b5-e679f9320005": {"Flags": "write-without-response"},
                "8a7f1168-48af-4efb-83b5-e679f9320006": {"Flags": "notify"},
                "8a7f1168-48af-4efb-83b5-e679f9320007": {"Flags": "indicate"}}

    DUT_DESCR = {"8a7f1168-48af-4efb-83b5-e679f9320008": None,
                 "8a7f1168-48af-4efb-83b5-e679f9320009": None,
                 "8a7f1168-48af-4efb-83b5-e679f932000a": None,
                 "8a7f1168-48af-4efb-83b5-e679f932000b": None}

    DUT_NAME = "TEST"

    TEST_GROUP = "Full_BLE"
    TEST_NAME_PREFIX = "RaspberryPI"

    SHORT_LOCAL_NAME_SIZE = 4
    ADVERTISEMENT_TEST_TIMEOUT = 120
    STOP_ADVERTISEMENT_TEST_TIMEOUT = 2000  # 2 seconds
    SIMPLE_CONNECTION_TEST_TIMEOUT = 120
    SERVICE_DISCOVERY_TEST_TIMEOUT = 120
    PAIRING_TEST_TIMEOUT = 120
    GENERIC_TEST_TIMEOUT = 120
    MTU_SIZE = 200

    numberOfTests = 0
    numberOfFailedTests = 0

    # Manufacturer-specific Data
    # First two bytes are company ID (randomly select Espressif(741) for test purpose)
    # Next bytes are defined by the company (randomly select unit8_t 5 for
    # test purpose)
    COMPANY_ID = 741
    MANU_DATA = 5

    # Service Data
    # First 16 bit are Service UUID (randomly select 0xEF12 for test purpose)
    # Next bytes are Data related to this Service (randomly select 0xD6 for test purpose)
    SERV_UUID = "000012ef-0000-1000-8000-00805f9b34fb"
    SERV_DATA = 214

    # The maximum possible attribute size is 512 bytes. Long write/read tests use 512 for data length.
    LONG_READ_WRITE_LEN = 512

    testDevice = []

    DUT_MTU_2_STRING = "a" * (MTU_SIZE - 3)
    DUT_LONG_STRING = ["A" * (MTU_SIZE - 3), "B" *
                       (MTU_SIZE - 3), "C" * (MTU_SIZE - 3)]
    DUT_CHAR_E_STRING = "E"
    DUT_CHAR_F_STRING = "F"
    isNotificationDeclinedSuccessFull = False

    testResult = False

    @staticmethod
    def discoveryStoppedCb(testDevice=None):
        global testResult
        testResult = False
        if testDevice is None:
            testResult = True
        runTest.mainloop.quit()

    @staticmethod
    def discoveryStartedCb(testDevice):
        runTest.mainloop.quit()

    @staticmethod
    def discoveryEventCb(testDevice):
        isTestSuccessFull = runTest.advertisement(testDevice)

        if isTestSuccessFull:
            runTest.setTestDevice(testDevice)
            # discoveryEvent.set()
            runTest.mainloop.quit()

    @staticmethod
    def discoveryEventCb_16bit(testDevice):
        isTestSuccessFull = runTest.advertisement_16bit(testDevice)

        if isTestSuccessFull:
            runTest.setTestDevice(testDevice)
            # discoveryEvent.set()
            runTest.mainloop.quit()

    @staticmethod
    def notificationCb(uuid, value, flag):
        isNotificationTestSuccessFull = runTest.notification(uuid, value, flag)
        if isNotificationTestSuccessFull:
            # notificationEvent.set()
            runTest.mainloop.quit()

    @staticmethod
    def indicationCb(uuid, value, flag):
        isIndicationTestSuccessFull = runTest.indication(uuid, value, flag)
        if isIndicationTestSuccessFull:
            # indicationEvent.set()
            runTest.mainloop.quit()

    @staticmethod
    def notificationMTUCb(uuid, value, flag):
        notification = runTest.notificationMTU2(uuid, value, flag)
        if notification == runTest.DUT_MTU_2_STRING:
            runTest.mainloop.quit()
            runTest.isNotificationDeclinedSuccessFull = True

    @staticmethod
    def errorConnectCb():
        print("Connection error")
        sys.stdout.flush()
        connectEvent.put(0)

    @staticmethod
    def stopAdvertisement(scan_filter):
        # Do one cycle of discovery to remove cached messages.
        timerHandle = GObject.timeout_add(
            runTest.STOP_ADVERTISEMENT_TEST_TIMEOUT,
            runTest.discoveryStoppedCb)
        bleAdapter.setDiscoveryFilter(scan_filter)
        # wait for DUT to start advertising
        bleAdapter.startDiscovery(runTest.discoveryStoppedCb)
        runTest.mainloop.run()
        bleAdapter.stopDiscovery()

        # All cached message have been remove. Try again a discovery.
        timerHandle = GObject.timeout_add(
            runTest.STOP_ADVERTISEMENT_TEST_TIMEOUT,
            runTest.discoveryStoppedCb)
        bleAdapter.setDiscoveryFilter(scan_filter)
        # wait for DUT to start advertising
        bleAdapter.startDiscovery(runTest.discoveryStoppedCb)
        runTest.mainloop.run()
        runTest.submitTestResult(testResult, runTest.stopAdvertisement)
        bleAdapter.stopDiscovery()

    @staticmethod
    def reconnectWhileNotBonded():
        isTestSuccessFull = bleAdapter.connect(runTest.testDevice)
        if not isTestSuccessFull:
            print("reconnectWhileNotBonded test: Could not connect")
            sys.stdout.flush()
            runTest.submitTestResult(False, runTest.reconnectWhileNotBonded)
            return

        # Since secure connection only are accepted, pairing in "just works"
        # shoud get rejected
        if bleAdapter.pair():
            print("reconnectWhileNotBonded test: Able to pair in just Works mode")
            sys.stdout.flush()
            runTest.submitTestResult(False, runTest.reconnectWhileNotBonded)
            return

        runTest.submitTestResult(True, runTest.reconnectWhileNotBonded)

    @staticmethod
    def reconnectWhileBonded():
        isTestSuccessFull = bleAdapter.connect(runTest.testDevice)
        # since there is a bond with DUT, pairing is automatic
        if(isTestSuccessFull):
            isTestSuccessfull = bleAdapter.writeCharacteristic(
                runTest.DUT_ENCRYPT_CHAR_UUID, runTest.DUT_ENCRYPT_CHAR_UUID)
        runTest.submitTestResult(
            isTestSuccessFull,
            runTest.reconnectWhileBonded)

    @staticmethod
    def disconnect():
        isTestSuccessFull = bleAdapter.disconnect()
        runTest.submitTestResult(isTestSuccessFull, runTest.disconnect)

    @staticmethod
    def waitForDisconnect():
        isTestSuccessfull = bleAdapter.isDisconnected(
            timeout=runTest.GENERIC_TEST_TIMEOUT)
        runTest.submitTestResult(isTestSuccessfull, runTest.waitForDisconnect)

    @staticmethod
    def pairing():
        isTestSuccessFull = True
        if bleAdapter.isPaired() == False:
            bleAdapter.writeCharacteristic(
                runTest.DUT_ENCRYPT_CHAR_UUID,
                runTest.DUT_ENCRYPT_CHAR_UUID)  # should trigger a pairing event
            isTestSuccessFull = bleAdapter.isPaired(
                timeout=runTest.GENERIC_TEST_TIMEOUT)
        else:
            isTestSuccessFull = False
        return isTestSuccessFull

    @staticmethod
    def _readWriteProtectedAttributes(pairingStatus):

        if pairingStatus:
            expectedSuccess = True
        else:
            expectedSuccess = False

        isTestSuccessfull = bleAdapter.writeDescriptor(
            runTest.DUT_ENCRYPT_DESCR_UUID, runTest.DUT_ENCRYPT_DESCR_UUID)
        if isTestSuccessfull != expectedSuccess:
            print(
                "readWriteProtectedAttributes test: Error while reading protect descriptor, pairing status was " +
                str(pairingStatus) +
                " Operation success was " +
                str(isTestSuccessfull))
            sys.stdout.flush()
            return False

        isTestSuccessfull = bleAdapter.writeCharacteristic(
            runTest.DUT_ENCRYPT_CHAR_UUID, runTest.DUT_ENCRYPT_CHAR_UUID)
        if isTestSuccessfull != expectedSuccess:
            print(
                "readWriteProtectedAttributes test: Error while writing protect characteristic, pairing status was " +
                str(pairingStatus) +
                " Operation success was " +
                str(isTestSuccessfull))
            sys.stdout.flush()
            return False

        return True

    # Expect writing/Reading to protect attribute to succeed.
    @staticmethod
    def readWriteProtectedAttributesWhilePaired():
        isPaired = bleAdapter.isPaired()
        if not isPaired:
            print(
                "readWriteProtectedCharacteristicWhileNotPaired test: Expected paired:1, got:" +
                str(isPaired))
            sys.stdout.flush()
            return False

        return runTest._readWriteProtectedAttributes(True)

    # Expect writing/Reading to protect attribute to fail.
    @staticmethod
    def readWriteProtectedAttributesWhileNotPaired():
        isPaired = bleAdapter.isPaired()
        if isPaired:
            print(
                "readWriteProtectedCharacteristicWhileNotPaired test: Expected paired:0, got:" +
                str(isPaired))
            sys.stdout.flush()
            return False

        return runTest._readWriteProtectedAttributes(False)

    @staticmethod
    def indication(uuid, value, flag):
        isSuccessfull = False
        if (uuid == runTest.DUT_INDICATE_CHAR_UUID) and (
                value == runTest.DUT_GENERIC_STRING) and (flag == "indicate"):
            isSuccessfull = True

        return isSuccessfull

    @staticmethod
    def notification(uuid, value, flag):
        isSuccessfull = False
        if (uuid == runTest.DUT_NOTIFY_CHAR_UUID) and (
                value == runTest.DUT_GENERIC_STRING) and (flag == "notify"):
            isSuccessfull = True

        return isSuccessfull

    @staticmethod
    def notificationMTU2(uuid, value, flag):
        if (uuid == runTest.DUT_NOTIFY_CHAR_UUID) and (flag == "notify"):
            return value

    @staticmethod
    def notificationOnCharE(uuid, value, flag):
        isSuccessfull = False
        if (uuid == runTest.DUT_NOTIFY_CHAR_UUID) and (
                value == runTest.DUT_CHAR_E_STRING) and (flag == "notify"):
            isSuccessfull = True

        return isSuccessfull

    @staticmethod
    def indicationOnCharF(uuid, value, flag):
        isSuccessfull = False
        if (uuid == runTest.DUT_INDICATE_CHAR_UUID) and (
                value == runTest.DUT_CHAR_F_STRING) and (flag == "indicate"):
            isSuccessfull = True

        return isSuccessfull

    @staticmethod
    def writeWithoutResponse():
        return bleAdapter.writeCharacteristic(
            runTest.DUT_WRITE_NO_RESP_CHAR_UUID,
            runTest.DUT_WRITE_NO_RESP_CHAR_UUID,
            False)

    @staticmethod
    def writeResultWithoutResponse(result):
        return bleAdapter.writeCharacteristic(
            runTest.DUT_WRITE_NO_RESP_CHAR_UUID, result, False)

    @staticmethod
    def writereadLongCharacteristic():
        long_value = "1" * runTest.LONG_READ_WRITE_LEN
        bleAdapter.writeCharacteristic(runTest.DUT_OPEN_CHAR_UUID, long_value)
        (isTestSuccessfull, charRead) = bleAdapter.readCharacteristic(
            runTest.DUT_OPEN_CHAR_UUID)

        if charRead != long_value:
            isTestSuccessfull = False
            print(
                "writereadLongCharacteristic test: Expected value:" +
                long_value +
                " got:" +
                charRead)

        sys.stdout.flush()
        return isTestSuccessfull

    @staticmethod
    def _readWriteChecks(charUUID, descrUUID):
        bleAdapter.writeCharacteristic(charUUID, charUUID)

        bleAdapter.writeDescriptor(descrUUID, descrUUID)

        (isTestSuccessfull, charRead) = bleAdapter.readCharacteristic(charUUID)
        (isTestSuccessfull, descrRead) = bleAdapter.readDescriptor(descrUUID)

        if charRead != charUUID:
            isTestSuccessfull = False
            print(
                "readWriteSimpleConnection test: Expected char uuid:" +
                charUUID +
                " got:" +
                charRead)

        if descrRead != descrUUID:
            isTestSuccessfull = False
            print(
                "readWriteSimpleConnection test: Expected descr uuid:" +
                descrUUID +
                " got:" +
                descrRead)

        sys.stdout.flush()
        return isTestSuccessfull

    @staticmethod
    def readWriteSimpleConnection():
        isTestSuccessfull = runTest._readWriteChecks(
            runTest.DUT_OPEN_CHAR_UUID, runTest.DUT_OPEN_DESCR_UUID)

        isPaired = bleAdapter.isPaired()

        if isPaired:
            isTestSuccessfull = False
            print(
                "readWriteSimpleConnection test: Expected paired:0, got:" +
                str(isPaired))

        sys.stdout.flush()
        return isTestSuccessfull

    @staticmethod
    def discoverPrimaryServices():
        return bleAdapter.isServicesResolved(
            timeout=runTest.GENERIC_TEST_TIMEOUT)

    @staticmethod
    def checkProperties(gatt):
        isTestSuccessfull = True

        for uuid in runTest.DUT_CHAR.keys():
            if runTest.DUT_CHAR[uuid]["Flags"] != gatt.characteristics[uuid]["Flags"]:
                print(
                    "checkProperties test: incorrect flags, expected: " +
                    runTest.DUT_CHAR[uuid]["Flags"] +
                    " was: " +
                    gatt.characteristics[uuid]["Flags"])
                isTestSuccessfull = False

        sys.stdout.flush()
        return isTestSuccessfull

    @staticmethod
    def checkUUIDs(gatt, bEnableSecondaryService):
        isTestSuccessfull = True
        if runTest.DUT_SERVICEB_UUID not in gatt.services.keys():
            print(
                "checkUUIDs test: missing service UUID: " +
                runTest.DUT_SERVICEB_UUID)
            isTestSuccessfull = False
        elif (gatt.services[runTest.DUT_SERVICEB_UUID]["Primary"] != True):
            print(
                "checkUUIDs test: wrong service type: " +
                runTest.DUT_SERVICEC_UUID)
            isTestSuccessfull = False

        #Check secondary service UUID
        if bEnableSecondaryService == True and ENABLE_TC_AFQP_SECONDARY_SERVICE == 1 :
            if runTest.DUT_SERVICEC_UUID not in gatt.services.keys():
                print(
                    "checkUUIDs test: missing secondary service UUID: " +
                    runTest.DUT_SERVICEC_UUID)
                isTestSuccessfull = False
            elif (gatt.services[runTest.DUT_SERVICEC_UUID]["Primary"]):
                print(
                    "checkUUIDs test: wrong service type: " +
                    runTest.DUT_SERVICEC_UUID)
                isTestSuccessfull = False

        # Check characteristics UUIDs
        for uuid in runTest.DUT_CHAR.keys():
            if uuid not in gatt.characteristics.keys():
                print("checkUUIDs test: missing characteristic UUID: " + uuid)
                isTestSuccessfull = False

        # Check descriptors
        for uuid in runTest.DUT_DESCR.keys():
            if uuid not in gatt.descriptors.keys():
                print("checkUUIDs test: missing descriptors UUID: " + uuid)
                isTestSuccessfull = False

        sys.stdout.flush()
        return isTestSuccessfull

    @staticmethod
    def simpleConnection(isConnected):
        return isConnected

    @staticmethod
    def reConnection(isConnected):
        return isConnected

    @staticmethod
    def removeIndication(isSuccessfull):
        return isSuccessfull

    @staticmethod
    def removeNotification(isSuccessfull):
        return isSuccessfull

    @staticmethod
    def advertisement(testDevice, DUT_UUID=None):
        if (DUT_UUID is None):
            DUT_UUID = runTest.DUT_UUID_128

        if (bleAdapter.getPropertie(testDevice, "Address") is None):
            print("Advertisement test: Waiting for Address")
            sys.stdout.flush()
            return False

        UUIDs = bleAdapter.getPropertie(testDevice, "UUIDs")
        if (UUIDs is None):
            print("Advertisement test: Waiting for UUIDs")
            sys.stdout.flush()
            return False
        else:
            if (DUT_UUID not in UUIDs):
                print("Advertisement test: Waiting for device UUID")
                sys.stdout.flush()
                return False

            # Remove test for service B. Advertisement messages were too small.
            # Should look into improving this part if it can be done.
            # if (runTest.DUT_SERVICEB_UUID not in UUIDs):
            #   print("Advertisement test: Waiting for serviceB UUID")
            #   sys.stdout.flush()
            #   return False

        name = bleAdapter.getPropertie(testDevice, "Name")
        if(name is None):
            print("Advertisement test: Waiting name")
            sys.stdout.flush()
            return False
        else:
            # Names can be cached. So the complete local name may still be in
            # memory. Check the 4 first letter which constitutes the short name
            if (runTest.DUT_NAME != name[:runTest.SHORT_LOCAL_NAME_SIZE]):
                print("Advertisement test: name is incorrect: " + name)
                sys.stdout.flush()
                # return False

        if (bleAdapter.getPropertie(testDevice, "TxPower") is None):
            print("Advertisement test: Waiting for TxPower")
            sys.stdout.flush()
            return False

        if(bleAdapter.getPropertie(testDevice, "RSSI") is None):
            print("Advertisement test: Waiting for RSSI")
            sys.stdout.flush()
            return False

        return True

    @staticmethod
    def get_manufacture_data(testDevice, DUT_UUID=None):
        manufacture_data_dict = bleAdapter.getPropertie(
            testDevice, "ManufacturerData")

        # If manufacture data doesn't exist, return None
        if(manufacture_data_dict is None):
            return None

        # If manufacture data exists, return manufacture data
        else:
            print("Manufacturer Specific Data: " +
                  str(manufacture_data_dict.items()))
            sys.stdout.flush()
            if manufacture_data_dict.get(runTest.COMPANY_ID) != None:
                manufacture_data = manufacture_data_dict[runTest.COMPANY_ID]
                return manufacture_data
            else:
                return None

    @staticmethod
    def get_service_data(testDevice, DUT_UUID=None):
        service_data_dict = bleAdapter.getPropertie(
            testDevice, "ServiceData")

        # If service data doesn't exist, return None
        if(service_data_dict is None):
            return None

        # If service data exists, return service data
        else:
            print("Service Data: " +
                  str(service_data_dict.items()))
            sys.stdout.flush()
            if service_data_dict.get(runTest.SERV_UUID) != None:
                service_data = service_data_dict[runTest.SERV_UUID]
                return service_data
            else:
                return None

    @staticmethod
    def _advertisement_start(scan_filter, UUID, discoveryEvent_Cb, bleAdapter):
        scan_filter.update({"UUIDs": [UUID]})
        bleAdapter.setDiscoveryFilter(scan_filter)

        # Discovery test
        bleAdapter.startDiscovery(discoveryEvent_Cb)
        runTest.mainloop.run()
        bleAdapter.stopDiscovery()

    @staticmethod
    def _simple_connect():
        # Simple Connection test
        testDevice = runTest.getTestDevice()
        isTestSuccessFull = bleAdapter.connect(testDevice)
        time.sleep(2)  # wait for connection parameters update

    @staticmethod
    def _advertisement_connection_tests(scan_filter,
                                        bleAdapter,
                                        UUID,
                                        discoveryEvent_Cb):
        runTest._advertisement_start(scan_filter=scan_filter,
                                     UUID=UUID,
                                     discoveryEvent_Cb=discoveryEvent_Cb,
                                     bleAdapter=bleAdapter)
        runTest._simple_connect()
        runTest.stopAdvertisement(scan_filter)
        bleAdapter.disconnect()

        testutils.removeBondedDevices()

    @staticmethod
    def Advertise_Without_Properties(scan_filter,
                                     bleAdapter):

        DUT_NAME_ORIGINAL = runTest.DUT_NAME
        runTest.DUT_NAME = "nimb"
        runTest._advertisement_connection_tests(
            scan_filter=scan_filter,
            bleAdapter=bleAdapter,
            UUID=runTest.DUT_UUID_128,
            discoveryEvent_Cb=runTest.discoveryEventCb)
        runTest.DUT_NAME = DUT_NAME_ORIGINAL
        return True

    @staticmethod
    def Check_ManufactureData(scan_filter,
                                        bleAdapter,
                                        bEnableManufactureData):
        isTestSuccessFull = True

        runTest._advertisement_start(
            scan_filter=scan_filter,
            UUID=runTest.DUT_UUID_16,
            discoveryEvent_Cb=runTest.discoveryEventCb_16bit,
            bleAdapter=bleAdapter)
        manufacture_data = runTest.get_manufacture_data(runTest.testDevice)

        if bEnableManufactureData == False:
            if manufacture_data is not None:
                print("ERROR: MANU_DATA is not None")
                isTestSuccessFull &= False
        else:
            if manufacture_data is None:
                print("ERROR: MANU_DATA is not None")
                isTestSuccessFull &= False
            else:
                for data in manufacture_data:
                    if data != runTest.MANU_DATA:
                        print( "MANU_DATA is not correct. Data received: %d" %data)
                        isTestSuccessFull &= False

        runTest._simple_connect()
        runTest.stopAdvertisement(scan_filter)
        isTestSuccessFull &= bleAdapter.disconnect()
        testutils.removeBondedDevices()

        return isTestSuccessFull

    @staticmethod
    def Check_ServiceData(scan_filter,
                                    bleAdapter,
                                    bEnableServiceData):
        isTestSuccessFull = True

        runTest._advertisement_start(
            scan_filter=scan_filter,
            UUID=runTest.DUT_UUID_16,
            discoveryEvent_Cb=runTest.discoveryEventCb_16bit,
            bleAdapter=bleAdapter)
        service_data = runTest.get_service_data(runTest.testDevice)

        if bEnableServiceData == False:
            if service_data is not None:
                print("ERROR: SERV_DATA is not None")
                isTestSuccessFull &= False
        else:
            if service_data is None:
                print("ERROR: SERV_DATA is None")
                isTestSuccessFull &= False
            else:
                for data in service_data:
                    if data != runTest.SERV_DATA:
                        print( "SERV_DATA is not correct. Data received: %d" %data)
                        isTestSuccessFull &= False

        runTest._simple_connect()
        runTest.stopAdvertisement(scan_filter)
        isTestSuccessFull &= bleAdapter.disconnect()
        testutils.removeBondedDevices()

        return isTestSuccessFull

    @staticmethod
    def Advertise_With_Manufacture_Data(scan_filter,
                                        bleAdapter):
        isTestSuccessFull = True

        # Check when manufacture data length is 0, but pointer is valid
        isTestSuccessFull &= runTest.Check_ManufactureData(scan_filter, bleAdapter, False)

        # Check when manufacture data pointer is NULL, but length is not 0
        isTestSuccessFull &= runTest.Check_ManufactureData(scan_filter, bleAdapter, False)

        # Check when manufacture data length is not 0, and pointer is valid
        isTestSuccessFull &= runTest.Check_ManufactureData(scan_filter, bleAdapter, True)

        return isTestSuccessFull

    @staticmethod
    def Advertise_With_Service_Data(scan_filter,
                                        bleAdapter):
        isTestSuccessFull = True

        # Check when service data length is 0, but pointer is valid
        isTestSuccessFull &= runTest.Check_ServiceData(scan_filter, bleAdapter, False)

        # Check when service data pointer is NULL, but length is not 0
        isTestSuccessFull &= runTest.Check_ServiceData(scan_filter, bleAdapter, False)

        # Check when service data length is not 0, and pointer is valid
        isTestSuccessFull &= runTest.Check_ServiceData(scan_filter, bleAdapter, True)

        return isTestSuccessFull

    @staticmethod
    def Advertise_With_16bit_ServiceUUID(scan_filter,
                                         bleAdapter):
        runTest._advertisement_connection_tests(
            scan_filter=scan_filter,
            bleAdapter=bleAdapter,
            UUID=runTest.DUT_UUID_16,
            discoveryEvent_Cb=runTest.discoveryEventCb_16bit)
        return True

    @staticmethod
    def _scan_discovery_with_timer(bleAdapter):
        bleAdapter.startDiscovery(runTest.discoveryStartedCb)
        StartScan = time.time()
        runTest.mainloop.run()
        ScanTime = time.time() - StartScan
        bleAdapter.stopDiscovery()
        return ScanTime

    @staticmethod
    def Advertise_Interval_Consistent_After_BT_Reset(scan_filter,
                                                     bleAdapter):
        isTestSuccessFull = True
        runTest._advertisement_start(
            scan_filter=scan_filter,
            UUID=runTest.DUT_UUID_128,
            discoveryEvent_Cb=runTest.discoveryEventCb,
            bleAdapter=bleAdapter)
        secondKPI = runTest._scan_discovery_with_timer(bleAdapter)

        runTest._simple_connect()

        isTestSuccessFull = runTest.discoverPrimaryServices()
        bleAdapter.gatt.updateLocalAttributeTable( False )

        time.sleep(2)  # wait for connection parameters update
        # Second time disconnect
        isTestSuccessFull &= bleAdapter.disconnect()

        # Third time connection
        # wait for DUT to start advertising
        thirdKPI = runTest._scan_discovery_with_timer(bleAdapter)
        isTestSuccessFull &= bleAdapter.connect(runTest.testDevice)

        if thirdKPI > secondKPI * 10:
            isTestSuccessFull &= False

        # write result back to server
        isTestSuccessFull = runTest.discoverPrimaryServices()
        bleAdapter.gatt.updateLocalAttributeTable( False )

        isTestSuccessFull &= runTest.writeResultWithoutResponse(
            chr(isTestSuccessFull + 48))

        runTest.stopAdvertisement(scan_filter)
        isTestSuccessFull &= bleAdapter.disconnect()
        testutils.removeBondedDevices()

        return isTestSuccessFull

    @staticmethod
    def Write_Notification_Size_Greater_Than_MTU_3(scan_filter,
                                                   bleAdapter):
        runTest._advertisement_start(
            scan_filter=scan_filter,
            UUID=runTest.DUT_UUID_128,
            discoveryEvent_Cb=runTest.discoveryEventCb,
            bleAdapter=bleAdapter)
        runTest._simple_connect()

        runTest.stopAdvertisement(scan_filter)
        isTestSuccessFull_discover = runTest.discoverPrimaryServices()
        bleAdapter.gatt.updateLocalAttributeTable( False )

        time.sleep(2)  # wait for connection parameters update

        # Check device not present. After discovery of services, advertisement
        # should have stopped.
        runTest.stopAdvertisement(scan_filter)

        bleAdapter.setNotificationCallBack(runTest.notificationMTUCb)
        bleAdapter.subscribeForNotification(
            runTest.DUT_NOTIFY_CHAR_UUID)  # subscribe for next test
        runTest.mainloop.run()
        isTestSuccessFull_notification = runTest.isNotificationDeclinedSuccessFull
        runTest.submitTestResult(
            isTestSuccessFull_notification,
            runTest.notification)

        isTestSuccessFull_removenotification = bleAdapter.subscribeForNotification(
            runTest.DUT_NOTIFY_CHAR_UUID, subscribe=False)  # unsubscribe
        runTest.submitTestResult(
            isTestSuccessFull_removenotification,
            runTest.removeNotification)

        isTestSuccessFull_disconnect = bleAdapter.disconnect()
        testutils.removeBondedDevices()

        isTestSuccessFull = (isTestSuccessFull_discover &
                             isTestSuccessFull_notification &
                             isTestSuccessFull_removenotification &
                             isTestSuccessFull_disconnect)
        return isTestSuccessFull

    @staticmethod
    def Send_Data_After_Disconnected(scan_filter,
                                     bleAdapter):
        runTest._advertisement_start(
            scan_filter=scan_filter,
            UUID=runTest.DUT_UUID_128,
            discoveryEvent_Cb=runTest.discoveryEventCb,
            bleAdapter=bleAdapter)
        runTest._simple_connect()

        isTestSuccessFull = runTest.discoverPrimaryServices()
        runTest.submitTestResult(
            isTestSuccessFull,
            runTest.discoverPrimaryServices)

        bleAdapter.gatt.updateLocalAttributeTable( False )

        # Check device not present. After discovery of services, advertisement
        # should have stopped.
        runTest.stopAdvertisement(scan_filter)

        # Check write and read
        bleAdapter.writeCharacteristic(
            runTest.DUT_OPEN_CHAR_UUID,
            runTest.DUT_OPEN_DESCR_UUID)
        bleAdapter.readCharacteristic(runTest.DUT_OPEN_CHAR_UUID)

        # Enable and receive notification and indication then disable.
        bleAdapter.subscribeForNotification(runTest.DUT_NOTIFY_CHAR_UUID)
        bleAdapter.subscribeForNotification(
            runTest.DUT_INDICATE_CHAR_UUID)  # subscribe for next test

        time.sleep(2)  # wait for connection parameters update

        # Check Notification and Indication
        bleAdapter.setNotificationCallBack(runTest.notificationCb)
        isTestSuccessFull = True
        runTest.mainloop.run()
        runTest.submitTestResult(isTestSuccessFull, runTest.notification)

        bleAdapter.setNotificationCallBack(runTest.indicationCb)
        isTestSuccessFull = True
        runTest.mainloop.run()
        runTest.submitTestResult(isTestSuccessFull, runTest.indication)

        isTestSuccessFull &= bleAdapter.disconnect()

        # Second time connection
        # wait for DUT to start advertising
        bleAdapter.startDiscovery(runTest.discoveryStartedCb)
        runTest.mainloop.run()
        bleAdapter.stopDiscovery()
        runTest._simple_connect()

        bleAdapter.subscribeForNotification(runTest.DUT_NOTIFY_CHAR_UUID)
        bleAdapter.subscribeForNotification(
            runTest.DUT_INDICATE_CHAR_UUID)  # subscribe for next test

        # Check write and read after reconnection
        bleAdapter.writeCharacteristic(
            runTest.DUT_OPEN_CHAR_UUID,
            runTest.DUT_OPEN_DESCR_UUID)
        bleAdapter.readCharacteristic(runTest.DUT_OPEN_CHAR_UUID)

        # Check Notification and Indication after reconnection
        bleAdapter.setNotificationCallBack(runTest.notificationCb)
        isTestSuccessFull = True
        runTest.mainloop.run()
        runTest.submitTestResult(isTestSuccessFull, runTest.notification)

        bleAdapter.setNotificationCallBack(runTest.indicationCb)
        isTestSuccessFull = True
        runTest.mainloop.run()
        runTest.submitTestResult(isTestSuccessFull, runTest.indication)

        isTestSuccessFull = bleAdapter.subscribeForNotification(
            runTest.DUT_NOTIFY_CHAR_UUID, subscribe=False)  # unsubscribe
        isTestSuccessFull = True
        runTest.submitTestResult(isTestSuccessFull, runTest.removeNotification)

        isTestSuccessFull = bleAdapter.subscribeForNotification(
            runTest.DUT_INDICATE_CHAR_UUID, subscribe=False)  # unsubscribe
        isTestSuccessFull = True
        runTest.submitTestResult(isTestSuccessFull, runTest.removeIndication)

        isTestSuccessFull &= bleAdapter.disconnect()
        testutils.removeBondedDevices()

        return isTestSuccessFull

    @staticmethod
    def Check_Bond_State(scan_filter, bleAdapter):
        runTest._advertisement_start(scan_filter=scan_filter,
                                     UUID=runTest.DUT_UUID_128,
                                     discoveryEvent_Cb=runTest.discoveryEventCb,
                                     bleAdapter=bleAdapter)
        runTest._simple_connect()

        isTestSuccessFull = runTest.discoverPrimaryServices()
        runTest.submitTestResult(
            isTestSuccessFull,
            runTest.discoverPrimaryServices)

        bleAdapter.gatt.updateLocalAttributeTable( False )

        isTestSuccessFull &= bleAdapter.pair_cancelpairing()

        time.sleep(2)
        testutils.removeBondedDevices()

        return isTestSuccessFull

    @staticmethod
    def Change_MTU_Size(scan_filter, bleAdapter):
        runTest._advertisement_start(scan_filter=scan_filter,
                                     UUID=runTest.DUT_UUID_128,
                                     discoveryEvent_Cb=runTest.discoveryEventCb,
                                     bleAdapter=bleAdapter)
        runTest._simple_connect()
        time.sleep(5)

        isTestSuccessFull = bleAdapter.disconnect()
        testutils.removeBondedDevices()

        return isTestSuccessFull

    @staticmethod
    def Callback_NULL_check(scan_filter, bleAdapter):
        runTest._advertisement_start(scan_filter=scan_filter,
                                     UUID=runTest.DUT_UUID_128,
                                     discoveryEvent_Cb=runTest.discoveryEventCb,
                                     bleAdapter=bleAdapter)
        runTest._simple_connect()

        isTestSuccessFull = runTest.discoverPrimaryServices()
        runTest.submitTestResult(
            isTestSuccessFull,
            runTest.discoverPrimaryServices)

        bleAdapter.gatt.updateLocalAttributeTable( False )
        isTestSuccessFull &= runTest.checkUUIDs(bleAdapter.gatt, False)
        time.sleep(5)

        isTestSuccessFull &= bleAdapter.disconnect()
        testutils.removeBondedDevices()

        return isTestSuccessFull

    @staticmethod
    def advertisement_16bit(testDevice):
        return runTest.advertisement(
            testDevice, DUT_UUID=runTest.UUID_16to128(
                runTest.DUT_UUID_16))

    @staticmethod
    def UUID_16to128(UUID_16bit):
        return "0000" + UUID_16bit + "-0000-1000-8000-00805f9b34fb"

    @staticmethod
    def setTestDevice(testDeviceTmp):
        runTest.testDevice = testDeviceTmp

    @staticmethod
    def getTestDevice():
        return runTest.testDevice

    @staticmethod
    def submitTestResult(isSuccessfull, testMethod):
        runTest.numberOfTests += 1

        if isSuccessfull is True:
            successString = "PASS"
        else:
            successString = "FAIL"
            runTest.numberOfFailedTests += 1

        print("TEST("
              + runTest.TEST_GROUP
              + ", "
                + runTest.TEST_NAME_PREFIX
                + "_"
                + testMethod.__name__
                + ") "
                + successString)

        sys.stdout.flush()

    @staticmethod
    def printTestsSummary():
        print("-----------------------")
        print(str(runTest.numberOfTests) + " Tests " +
              str(runTest.numberOfFailedTests) + " Failures 0 Ignored")
        sys.stdout.flush()


from . import music

def change_key(sounds, diff):
    """Transpose all sounds a chosen number
    of halftones up

    Parameters:
    sounds (list[Sound]) : Sounds to transpose
    diff (int) : Chosen number of halftones

    Returns:
    (list[Sound]) : Transposed sounds
    """
    sounds1 = []
    for s in sounds:
        n1 = s.note+diff if s.note is not None else None
        s1 = music.Sound(n1, s.timestamp, s.duration_ms)
        sounds1.append(s1)

    return sounds1


day = 27
weight = 59.5
month = 'February'

library_is_open = False

if library_is_open:
  print('Hurrayyy!!!')
  print("it's Open")
else:
  print(':(')

gold_rate = 4600

if gold_rate > 5000:
  print("We cannot Buy it now")
else:
  print("We're Buying!!!")

age = 16

if age >= 18:
  print('Adult')
else:
  print('Child')


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

"""
Created on mar 23 fév 2021 09:14:21 UTC

@author: vekemans

"""

import math as mt
import numpy as np

from math import pi as π
from numpy.fft import fft,fftshift,ifft

import matplotlib
import matplotlib.pyplot as plt
from matplotlib import animation
nfig = 1

def dft(func, start,end,N, order=1):
    """
    Return the 1D-derivative of function 'func', at specified order
    """
    L = end-start
    h = L/N
    x = np.arange(start,end, step=h)

    # -- Compute the FFT
    u = func(x)
    u_hat = fftshift(fft(u))
    k = np.arange(-N/2,N/2)

    # -- Compute the Derivative
    u_dot_hat = (1j*k)**order * u_hat
    u_dot = ifft(fftshift(u_dot_hat)).real

    return x, u_dot

def gaussian(x, μ=0,σ=1):
    """
    Gaussian function
    """
    u = 1/mt.sqrt(2*π*σ**2) * np.exp(-(x-μ)**2/(2*σ**2))
    return u

def dgaussian(x, μ=0,σ=1):
    """
    Derivative of the gaussian function
    """
    u_dot = -2*(x-μ)/(2*σ**2) * gaussian(x, μ=μ,σ=σ)
    return u_dot

if __name__=='__main__':
    m = np.arange(2,15)
    Nvec = 2**m
    error = np.empty(m.shape)

    μ = π
    σ = 0.5
    f = lambda x: gaussian(x, μ=μ,σ=σ)

    for (i,N) in enumerate(Nvec):
        x,u_dot = dft(f, 0,2*π,N, order=1)
        uprime  = -2*(x-μ)/(2*σ**2) * f(x)
        error[i] = np.abs(uprime-u_dot).max()

    fig = plt.figure(nfig)
    plt.plot(x,f(x), 'k-', label=r'$u$')
    plt.plot(x,uprime, 'k--', label=r"$u'$")
    plt.xlabel(r'$x$')
    # plt.title('Gaussian function and its derivative')
    plt.legend()
    plt.tight_layout()
    fig.savefig('../figs/gaussian_function.pdf')
    nfig += 1

    fig = plt.figure(nfig)
    plt.loglog(Nvec,error, 'k-o', markersize=4, lw=0)
    plt.xlabel(r'$N$')
    plt.ylabel('Error')
    # plt.title('Convergence of spectral method for differentiation')
    plt.grid(which='major', linestyle='--', linewidth=0.5)
    plt.grid(which='minor', linestyle=':', linewidth=0.25)
    plt.tight_layout()
    fig.savefig('../figs/spectral_convergence.pdf')
    nfig += 1

    N = 2**8
    x = np.arange(0,2*π, step=2*π/N)
    u = gaussian(x, μ=π,σ=σ)
    # u = np.exp(-100*(x-1)**2)
    c = 0.2 + np.power(np.sin(x-1),2)

    tmax = 8.
    tplot = .02
    plotgap = int(tplot/0.001)
    dt = tplot/plotgap
    Nplots = int(tmax/tplot)

    data = np.zeros((Nplots,N))
    data[0,:] = u; u_old = u
    time = np.arange(Nplots)/Nplots * tmax
    for i in range(Nplots):
        for n in range(plotgap):
            u_hat = fftshift(fft(u))
            u_dot_hat = (1j*np.arange(-N/2,N/2)) * u_hat
            u_dot = ifft(fftshift(u_dot_hat)).real

            u_new = u_old - 2*dt*c*u_dot if i>0 else u_old - dt*c*u_dot
            u_old = u

        data[i,:] = u_new

    fig = plt.figure(nfig)
    u_plt, = plt.plot([], [], 'k-')
    u_txt  = plt.text(π, 0.9, '', ha='center', fontsize=10)

    plt.xlim([x[0],x[-1]])
    plt.ylim([0,1])
    plt.xlabel(r'$x$', fontsize=10)
    plt.ylabel(r'$u$', fontsize=10)
    # plt.title(r'$u_t + c(x) u_x = 0 \qquad u^0 = \mathcal{N}(\pi,0.5)$', fontsize=12)
    plt.tight_layout()
    nfig += 1

    def animate(t):
        u_plt.set_data(x, data[t,:])
        u_txt.set_text('Current time : t = %.2f [s]' %(t*tplot))
        return u_plt,u_txt,

    anim = animation.FuncAnimation(fig, animate, Nplots, interval=100*tplot, blit=True)
    writer = animation.PillowWriter(fps=25)
    anim.save('../figs/gaussian_animation.gif', writer=writer)

    fig = plt.figure(nfig)
    ax  = plt.axes(projection='3d')
    for i in range(Nplots):
        t = time[i]*np.ones(x.shape)
        ax.plot3D(x,t, data[i,:], color='tab:blue')
    # X,T = np.meshgrid(x,time)
    # print(x.shape,time.shape,X.shape,data.shape)
    # ax.plot_surface(X,T, data, cmap='w')
    ax.set_xlim([x[0],x[-1]])
    ax.set_ylim([0,tmax])
    ax.set_zlim([0,4])
    ax.set_xlabel('X-axis')
    ax.set_ylabel('Time-axis')
    ax.set_zlabel(r'$u$')
    ax.view_init(40,-70)
    fig.tight_layout()
    fig.savefig('../figs/gaussian_convection.pdf')
    nfig += 1

# -- Show figures
plt.show()


# import asyncio
import time
from evdev import InputDevice, categorize, ecodes

source_device = None
target_device = None

# Init dev reference
while source_device is None and target_device is None:
  try:
    source_device = InputDevice('/dev/input/event1')
    target_device = InputDevice('/dev/hidg0')
  except Exception as err:
    print ("No device - waiting...")
    time.sleep (10)

# # Async helper
# async def helper(source_device, target_device):
#   async for ev in source_device.async_read_loop():
#     print(categorize(ev))
#     target_device.write_event(ev)

# # Loop waiting for keystroke
# loop = asyncio.get_event_loop()
# loop.run_until_complete(helper(source_device, target_device))

for ev in source_device.async_read_loop():
  print(categorize(ev))
  target_device.write_event(ev)


# #1. 분할 정복
# def bs(A, l, r, k):
#   if l>r:
#     return None
#   m=(l+r)//2
#   if A[m]>k:
#     return bs(A, l, m-1, k)
#   elif A[m] < k:
#     return bs(A, m+1, r, k)
#   else:
#     return m

#A에 이중리스트로 주어진 값 저장
n, k = map(int, input().split()) #4, 16
A=[] #[[2, 5, 10, 19],[3, 8, 16, 19],[7, 20, 20, 32],[13, 25, 37, 44]]
for i in range(n):
  A.append(list(map(int, input().split())))

def bs(A, k, n, i, j): #(i,j)의 형태로 반환, 없으면 -1,-1 출력 //n은 2^f의 형태!
  if n == 1:
    if A[i][j] == k:
      return (i, j)
    return (-1, -1)
  elif n%2==0:
    x = A[i+n//2-1][j+n//2-1]
    y = A[i+n//2][j+n//2]
    if k == x:
      return (i+n//2-1, j+n//2-1)
    elif k == y:
      return (i+n//2, j+n//2)
    elif k<x: #1,2,3사분면에 존재, 그 중 한 곳에 존재
      result = bs(A, k, n//2, i, j+n//2) #1사분면
      if result != (-1, -1):
        return result
      result = bs(A, k, n//2, i, j) #2사분면
      if result != (-1, -1):
        return result
      result = bs(A, k, n//2, i+n//2, j) #3사분면
      if result != (-1, -1):
        return result
    elif k>y: #1,3,4사분면에 존재, 그 중 한 곳에 존재
      result = bs(A, k, n//2, i, j+n//2) #1사분면
      if result != (-1, -1):
        return result
      result = bs(A, k, n//2, i+n//2, j) #3사분면
      if result != (-1, -1):
        return result
      result = bs(A, k, n//2, i+n//2, j+n//2) #4사분면
      if result != (-1, -1):
        return result
    else:#elif x<k<y: #1,3사분면에 존재 그 중 한 곳에 존재
      result = bs(A, k, n//2, i, j+n//2) #1사분면
      if result != (-1, -1):
        return result
      result = bs(A, k, n//2, i+n//2, j) #3사분면
      if result != (-1, -1):
        return result
    return (-1, -1)
  else: #n이 2^f형태가 아닌 입력은 문제에서 주어지지 않음
    print("n이 2^f형태가 아니라서 주어진 조건과 다름!!")
#n=짝수라 가정
print(bs(A, k, n, 0, 0))

#문제의 주어진 조건대로 값이 들어오기 때문에 n//2의 값을 기준으로 4등분하여 1,2,3,4분면으로 나눠서 접근하였다.
#슬라이싱하면 따로 시간이 더 들기 때문에 인덱스로 접근하였다.
#x = A[i+n//2-1][j+n//2-1], y = A[i+n//2][j+n//2] 값과 비교해서 찾으면 바로 그 위치에 있는 것이다.
#그리고 x와 y에 대해서 k값을 비교해서 k가 x보다 작다면 1,2,3사분면에 존재하고 k가 y보다 크다면 1,3,4분면에 존재하고 x<k<y면 1,3사분면에 존재한다.
#여기서 없다면 (-1,-1)을 출력해야하기 때문에 n=1인 바닥조건에서 k값이 없으면 (-1,-1)이 반환되어야 하지만 여러 사분면 중에서 k값이 있다면 한 곳에서만 존재한다.
#따라서 조건문으로 (-1,-1)이 아닌 경우에만 그 값을 반환하고 모두 없을 경우에는 사분면의 조건을 따지는 문장이 다 끝나고 마지막에 (-1,-1)을 반환해서 없는 것을 의미하게 했다.
#또한 함수를 여러번 호출하면 그때마다 값을 계산하므로 값을 저장해두고 그 값으로 비교 후 조건에 충족된다면 그 값을 반환하게 했다.
#그렇게 수행시간을 분석해보면 T(n)=3T(n/2)+C=3(3T(n/2^2)+c)+c=3^2 * T(n/2^2)+c(1+3)이므로 n=2^k로 가정하고 쭉 점화식을 전개하면
#3^k * T(n/2^k)+c(1+3+3^2+......+3^(k-1))=3^k * c+c(1+3+3^2+......+3^(k-1))=c(1+3+....+3^k)=c'*3^k이 된다.
#따라서 [LaTex] Markdown 수식 작성법을 활용하여 Big-O로 표기하면 O(3^k)=O(3^{log_{2}n})=O(n^{log_{2}3})=O(n^{1.5849....})이다.

# #2. 이진 탐색
# def bs(A, k):
#   l = 0
#   r = len(A)-1
#   while l <= r:
#     m = (l+r)//2
#     if A[m]>k:
#       r=m-1
#     elif A[m]<k:
#       l=m+1
#     else:
#       return m
#   return None

# n, k = map(int, input().split())
# A=[]
# for i in range(n):
#   A.append(list(map(int, input().split())))
#   result = bs(A[i], k)
#   if result != None:
#     print(f"({i}, {result})")
#     break
#   elif i == n-1:
#     print(f"(-1, -1)")

# #행별로 이진탐색이 더 빠름
# #O(logn)


import numpy as np
import tensornetwork as tn

np_vec = np.array([[0], [1]])
tn_vec1 = tn.Node(np_vec)
tn_vec2 = tn.Node(np_vec)

# Contracting the first index gives matrix with 1 element
tn_outer = tn.contract(tn_vec1[0] ^ tn_vec2[0])

# Contracting the second index gives matrix
tn_outer1 = tn.contract(tn_vec1[1] ^ tn_vec2[1])
tn_outer2 = tn.contract(tn_vec2[1] ^ tn_vec1[1])

# Matrix multiplication
np_mat1 = np.array([[1, 2], [3, 4]])

np_mat2 = np.array([[0, 1], [1, 0]])

tn_mat1 = tn.Node(np_mat1)
tn_mat2 = tn.Node(np_mat2)

# Multiplying by contracting the edges

mat12 = tn.contract(tn_mat1[1] ^ tn_mat2[0])

# Vector multiplication

vec1 = tn.contract(mat12[0] ^ tn_vec1[0])  # Picks 2nd row.
vec2 = tn.contract(mat12[1] ^ tn_vec1[0])  # Picks 2nd column.

# Quantum gate simulation

qubit = tn.Node(np.array([[0], [1]]))
z = tn.Node(np.array([[1, 0], [0, -1]]))
# _ = z[1] ^ qubit[0]
val = tn.contract(qubit[0] ^ z[1])
# val = qubit @ z


from pathlib import Path
import sqlite3
from datetime import datetime
from pymongo import ASCENDING

import pandas as pd

from utils.many_utils import PATH, get_collection

def inserisci_scadenza(
    st,
    nome,
    data_scadenza,
    dettagli,
    importo,
    stato,
    categoria,
    frequenza,
    notifiche=False,
):
    conn = sqlite3.connect(Path(PATH, f"utente_{st.session_state['user']}.db"))
    c = conn.cursor()

    data_inserimento = datetime.now().strftime("%Y-%m-%d")
    data_completamento = None
    completata = 1 if stato == "Completata" else 0
    c.execute(
        """
        INSERT INTO scadenze (nome, data_inserimento, data_scadenza, data_completamento, dettagli, importo, categoria, frequenza, notifiche, completata)
        VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
    """,
        (
            nome,
            data_inserimento,
            data_scadenza,
            data_completamento,
            dettagli,
            importo,
            categoria,
            frequenza,  # mensile? annuale? settimanale?
            notifiche,  # o meglio, "quanti giorni prima della scadenza voglio essere notificato"
            completata,  # completata/da fare
        ),
    )

    conn.commit()
    conn.close()

def get_scadenze(st):
    conn = sqlite3.connect(Path(PATH, f"utente_{st.session_state['user']}.db"))
    c = conn.cursor()

    c.execute("SELECT * FROM scadenze ORDER BY data_scadenza")
    scadenze = c.fetchall()
    cols = [
        "id",
        "nome",
        "data_inserimento",
        "data_scadenza",
        "data_completamento",
        "dettagli",
        "importo",
        "categoria",
        "frequenza",
        "notifiche",
        "completata",
    ]
    st.write()
    conn.close()
    return pd.DataFrame(scadenze, columns=cols).sort_values(
        "data_scadenza", ascending=True
    )

def aggiorna_stato_scadenza(st, id_scadenza):
    conn = sqlite3.connect(Path(PATH, f"utente_{st.session_state['user']}.db"))
    c = conn.cursor()

    c.execute("UPDATE scadenze SET completata = 1 WHERE id = ?", (id_scadenza))
    c.execute(
        "UPDATE scadenze SET data_completamento = ? WHERE id = ?",
        (datetime.strftime(datetime.now(), "%Y-%m-%d"), id_scadenza),
    )

    conn.commit()
    conn.close()

def elimina_scadenza(st, id_scadenza):
    conn = sqlite3.connect(Path(PATH, f"utente_{st.session_state['user']}.db"))
    c = conn.cursor()

    c.execute("DELETE FROM scadenze WHERE id = ?;", (id_scadenza))

    conn.commit()
    conn.close()

def genera_body_scadenza(s):
    res_id = s["_id"]
    res_nome = s["nome"]
    res_data_inserimento = s["data_inserimento"]
    res_data_scadenza = s["data_scadenza"]
    res_data_completamento = s["data_completamento"]
    res_dettagli = s["dettagli"]
    res_importo = s["importo"]
    res_categoria = s["categoria"]
    res_frequenza = s["frequenza"]
    res_notifiche = s["notifiche"]
    res_completata = "Si" if s["completata"] == 1 else "No"
    return f"\
        ID: {res_id} - {res_nome}, \n\
        Categoria: {res_categoria},\n\
        Inserita il: {res_data_inserimento}\n\
        Scadenza: {res_data_scadenza},\n\
        Dettagli: {res_dettagli},\n\
        Importo: {res_importo},\n\
        Completata: {res_completata}\n\
        Data completamento: {res_data_completamento}\
        "

######### Mongo

def get_scadenze_mongo(st, mongo_uri):
    scadenze_col = get_collection(
        st.session_state["user"],
        "scadenze",
        mongo_uri,
        mongo_db="solexiv_db",
    )

    scadenze = list(scadenze_col.find().sort("data_scadenza", ASCENDING))
    cols = [
        "_id",
        "nome",
        "data_inserimento",
        "data_scadenza",
        "data_completamento",
        "dettagli",
        "importo",
        "categoria",
        "frequenza",
        "notifiche",
        "completata",
    ]

    return pd.DataFrame(scadenze, columns=cols).sort_values(
        "data_scadenza", ascending=True
    )

def inserisci_scadenza_mongo(
    st,
    nome,
    data_scadenza,
    dettagli,
    importo,
    stato,
    categoria,
    frequenza,
    notifiche=False,
):
    scadenze_col = get_collection(
        st.session_state["user"],
        "scadenze",
        st.session_state["mongo_uri"],
        mongo_db="solexiv_db",
    )

    data_inserimento = datetime.now().strftime("%Y-%m-%d")
    data_scadenza = data_scadenza.strftime("%Y-%m-%d")
    data_completamento = None
    completata = True if stato == "Completata" else False

    scadenza = {
        "nome": nome,
        "data_inserimento": data_inserimento,
        "data_scadenza": data_scadenza,
        "data_completamento": data_completamento,
        "dettagli": dettagli,
        "importo": importo,
        "categoria": categoria,
        "frequenza": frequenza,
        "notifiche": notifiche,
        "completata": completata,
    }

    res = scadenze_col.insert_one(scadenza)

    st.toast("Scadenza inserita correttamente.")
    return True

def aggiorna_stato_scadenza_mongo(st, id_scadenza):
    scadenze_col = get_collection(
        st.session_state["user"],
        "scadenze",
        st.session_state["mongo_uri"],
        mongo_db="solexiv_db",
    )

    scadenza = scadenze_col.find_one({"_id": id_scadenza})

    if scadenza:
        scadenza["completata"] = True
        scadenza["data_completamento"] = datetime.now().strftime("%Y-%m-%d")

        scadenze_col.update_one({"_id": id_scadenza}, {"$set": scadenza})

        st.toast("Stato della scadenza aggiornato correttamente.")
    else:
        st.error("Scadenza non trovata.")

def elimina_scadenza_mongo(st, id_scadenza):
    scadenze_col = get_collection(
        st.session_state["user"],
        "scadenze",
        st.session_state["mongo_uri"],
        mongo_db="solexiv_db",
    )

    # Elimina la scadenza corrispondente all'id fornito
    result = scadenze_col.delete_one({"_id": id_scadenza})

    if result.deleted_count > 0:
        st.toast("Scadenza eliminata correttamente.")
    else:
        st.error("Scadenza non trovata.")


# -*- coding: utf-8 -*-
import scrapy
import re
import datetime
from scrapy.http import Request
from urllib import parse

from ..items import JobBoleArticleItem
from ..utils.common import get_md5

class JobboleSpider(scrapy.Spider):
    name = 'jobbole'
    allowed_domains = ['blog.jobbole.com']
    start_urls = ['http://blog.jobbole.com']
    #start_urls = ['http://blog.jobbole.com/licai/zq/164942.html']

    def parse(self, response: scrapy.http.TextResponse):
        """
        1、获取文章列表页中的文章url并交给scrapy，下载后并进行解析
        2、获取下一页的url并交给scrapy进行下载，下载完成后交给parse

        """
        # 提取下一页并交给scrapy进行下载
        next_page = response.meta.get("next_page", 0)+1
        if next_page <= 10:
            next_url = f"http://blog.jobbole.com/kaifadou/snews-getajax.php?next={next_page}"
            yield Request(url=next_url, meta={"next_page": next_page}, callback=self.parse)

        #解析列表页中的所有文章url并交给scrapy下载后并进行解析
        post_nodes = response.css(".zhicheng_news_list a")
        for post_node in post_nodes:
            image_url = post_node.css("img::attr(src)").extract_first("")
            post_url = post_node.css("::attr(href)").extract_first("")
            #new_url = response.url + post_url
            #parse.urljoin(response.url,post_url) 拼接url
            yield Request(url=parse.urljoin(response.url, post_url), meta={"front_image_url": parse.urljoin(response.url, image_url)}, callback=self.parse_detail)
            #print(post_url)

    def parse_detail(self, response):
        article_item = JobBoleArticleItem()
        #提取文章的具体字段
        #xpath语法
        # title = response.xpath('/html/body/div[3]/div[2]/div[1]/h2[1]/text()').extract()[0]
        # creatdate = response.xpath('/html/body/div[3]/div[2]/div[1]/div[1]/span[1]/text()').extract()[0]
        # #方法一：
        # content = response.xpath("//div[@class='wen_article']").extract_first("")
        # content = re.findall(r">(.*?)<", content)
        # content = ''.join(content)
        # #方法二：
        # #content = response.xpath("//div[@class='wen_article']/p/text()").extract()
        # #content = ''.join(content)
        # #方法三：
        # #content = response.xpath("//div[@class='wen_article']").extract().replace("<p>", "").replace("</p>", "")

        #css选择器语法
        front_image_url = response.meta.get("front_image_url", "")
        title = response.css(".ship_wrap h2::text").extract()[0]
        create_date = response.css(".meta span::text").extract()[0]
        content = response.css(".wen_article p::text").extract()
        content = "".join(content)
        #print(re_selector)

        article_item["url_object_id"] = get_md5(response.url)
        article_item["title"] = title
        try:
            create_date = datetime.datetime.strftime(create_date, "%Y/%m/%d").date()
        except Exception as e:
            create_date = datetime.datetime.now().date()
        article_item["create_date"] = create_date
        article_item["url"] = response.url
        article_item["front_image_url"] = [front_image_url]
        article_item["content"] = content

        yield article_item


# 숫자 맞추기 게임
import random

com = random.randint(1, 10)
cnt = 0

while True :
    cnt += 1
    user = int(input('1부터 10까지의 숫자를 입력하세요. >> '))
    if user == com :
        print(f'정답! {cnt}번 만에 맞췄습니다!')
        break
    else :
        print('오답! 다시 시도해보세요.')

# 숫자 찍기
for i in range(1, 6) :
    print(str(i) * 5)

for i in range(1, 26) :
    for j in range(i, i+1) :
        if j < 10 :
            print(j, end='  ')
        else :
            print(j, end=' ')
    if i % 5 == 0 :
        print()

for i in range(1, 26, 5) :
    for j in range(i, i+5) :
        if j < 10 :
            print(j, end='  ')
        else :
            print(j, end=' ')
    print()

# 별 찍기
# 1번
for i in range(5) :
    print('★' * 5)

# 2번
for i in range(1, 6) :
    print('★' * i)

# 3번
for i in range(5, 0, -1) :
    print('★' * i)

# 4번
for i in range(1, 11, 2) :
    print(' ' * ((11 - i) // 2), '★' * i)

# 5번
for i in range(9, 0, -2) :
    print(' ' * ((11 - i) // 2), '★' * i)

# 6번
for i in range(1, 13, 2) :
    print(' ' * ((13 - i) // 2), '★' * i)
for i in range(9, 0, -2) :
    print(' ' * ((13 - i) // 2), '★' * i)

# 주사위 눈 구하기
for i in range(1, 7) :
    for j in range(1, 7) :
        if i + j == 6 :
            print(f'({i}, {j})', end=' ')

for x in range(0, 11) :
    for y in range(0, 11) :
        if x * 2 + y * 4 == 10 :
            print(f'x = {x}, y = {y}')

# 버블 정렬
sort_num = []
for i in range(10) :
    sort_num.append(random.randint(0, 10))
print(sort_num)

for i in range(len(sort_num)-1) :
    check = False
    for j in range(len(sort_num)-1-i) :
        if sort_num[j] > sort_num[j+1] :
            check = True
            sort_num[j], sort_num[j+1] = sort_num[j+1], sort_num[j]
            print(sort_num)
    if not check :
        break

# 로또 뽑기
# 1장 뽑기
lotto = set()
while True :
    lotto.add(random.randint(1, 46))
    if len(lotto) == 6 :
        break
print(lotto)

# 5장 뽑기
lotto5 = []
lotto = set()
while True :
    lotto.add(random.randint(1, 45))
    if len(lotto) == 6 :
        lotto5.append(lotto)
        lotto = set()
    if len(lotto5) == 5 :
        break
print(lotto5)

# list 사용
lotto_num = []
for i in range(1, 45) :
    lotto_num.append(i)

lotto5 = []
for i in range(5) :
    for j in range(1000) :
        shuffle = random.randint(0, 44)
        lotto_num[0], lotto_num[shuffle] = lotto_num[shuffle], lotto_num[0]
    lotto = lotto_num[:6]
    print(lotto)
    lotto5.append(lotto)
print(lotto5)


import logging
import os
from io import StringIO

import boto3
import pandas as pd
from botocore.exceptions import ClientError

AWS_KEY_ID = os.environ.get("AWS_ACCESS_KEY_ID")
AWS_SECRET = os.environ.get("AWS_SECRET_ACCESS_KEY")
bucket = "kiwi-bot"
# key = "ordersDB.csv"
prefix = "data/"
filename = "https://kiwi-bot.s3.us-east-2.amazonaws.com/ordersDB.csv"
filepath = "kiwi_bot\data\order.csv"

s3 = boto3.client(
    "s3",
    region_name="us-east-1",
    aws_access_key_id=AWS_KEY_ID,
    aws_secret_access_key=AWS_SECRET,
)

read_file = s3.get_object(Bucket=bucket, Key=key)

df = pd.read_csv(read_file["Body"])
df.to_csv("kiwi_bot\data\order2.csv")
print("File succesfully loaded")


#
# Title:pid_lock.py
# Description:ensure only a single instance runs
# Development Environment:OS X 10.15.5/Python 3.7.6
# Author:G.S. Cole (guycole at gmail dot com)
#
import os

class PidLock:
    def lock_test(self, file_name: str) -> bool:
        """
        return True if active lock noted
        """
        target_pid = os.getpid()

        try:
            infile = open(file_name, "r")
            target_pid = int(infile.readline())
            infile.close()
        except IOError:
            return False

        command = "/bin/ps -p %d" % target_pid
        temp = os.popen(command).readlines()
        # returns one or two lines, w/first line as header
        # ['  PID TTY           TIME CMD\n', '52645 ttys000    0:00.04 python pid_lock.py\n']

        if len(temp) > 1:
            return True

        return False

    def write_lock(self, file_name: str) -> bool:
        """
        write a PID lock file
        """
        outfile = open(file_name, "w")
        outfile.write("%d\n" % (os.getpid()))
        outfile.close()

if __name__ == "__main__":
    print("start")

    pid_lock = PidLock()

    flag = pid_lock.lock_test("/tmp/target")

    if flag:
        print("pidlock test true")
    else:
        print("pidlock test false, now write lock")
        pid_lock.write_lock("/tmp/target")

    flag = pid_lock.lock_test("/tmp/target")
    print("pidlock test now %s" % flag)

    print("stop")

# ;;; Local Variables: ***
# ;;; mode:python ***
# ;;; End: ***