import gzip

#  对两跳子图的处理：先过滤掉出现超过 2w 次的实体和出现少于 50 次的关系；然后再采样 15 核的
#  设置，同时只保留出现大于50次的关系，对两跳子图进行清洗
if __name__ == "__main__":
    item_dict = {}
    rela_dict = {}

    print('start statistics')
    with gzip.open('../doc/origin_graph_step2.txt.gz', 'rb') as f:
        for num, line in enumerate(f):
            line = line.strip()
            triplet = line.decode().split()
            # print(triplet)
            # 头实体
            item_dict[triplet[0]] = 1 if triplet[0] not in item_dict else item_dict[triplet[0]] + 1
            # 尾实体
            item_dict[triplet[2]] = 1 if triplet[2] not in item_dict else item_dict[triplet[2]] + 1
            # 关系
            rela_dict[triplet[1]] = 1 if triplet[1] not in rela_dict else rela_dict[triplet[1]] + 1
            if num % 100000 == 0:
                print(num)

    print('start filter')
    filter_list = []
    with gzip.open('../doc/origin_graph_step2.txt.gz', 'rb') as f:
        for num, line in enumerate(f):
            line = line.strip()
            triplet = line.decode().split()
            # 高频过滤
            if item_dict[triplet[0]] < 20000 and item_dict[triplet[2]] < 20000 and rela_dict[triplet[1]] > 50:
                filter_list.append(triplet)
            if num % 100000 == 0:
                print(num)

    # 统计新的实体
    item_dict.clear()
    rela_dict.clear()
    for triplet in filter_list:
        # 头实体
        item_dict[triplet[0]] = 1 if triplet[0] not in item_dict else item_dict[triplet[0]] + 1
        # 尾实体
        item_dict[triplet[2]] = 1 if triplet[2] not in item_dict else item_dict[triplet[2]] + 1
        # 关系
        rela_dict[triplet[1]] = 1 if triplet[1] not in rela_dict else rela_dict[triplet[1]] + 1

    # 过滤实体
    res_file = open('../doc/graph_step2.txt', 'w', encoding='utf-8')
    for triplet in filter_list:
        if item_dict[triplet[0]] > 15 and item_dict[triplet[2]] > 15 and rela_dict[triplet[1]] > 50:
            tri_str = triplet[0] + ' ' + triplet[1] + ' ' + triplet[2] + '\n'
            res_file.write(tri_str)

    # 统计关系
    # rela_dict.clear()
    # for triplet in filter2_list:
    #     rela_dict[triplet[1]] = 1 if triplet[1] not in rela_dict else rela_dict[triplet[1]] + 1

    # 第二次过滤关系
    # res_file = open('../doc/graph_step2.txt', 'w', encoding='utf-8')
    # for num, line in enumerate(filter2_list):
    #     # triplet = line.split()
    #     triplet = line
    #     if rela_dict[triplet[1]] > 50:
    #         # filter2_list.append(triplet)
    #         tri_str = triplet[0] + ' ' + triplet[1] + ' ' + triplet[2] + '\n'
    #         res_file.write(tri_str)


import hp_items as hpi
import hp_classes as hpc
import random
import time

player_options = ['chaser', 'beater', 'keeper', 'seeker']
test_team_1 = {'chaser': [100, 150, 200],
				'beater': [175, 125],
				'keeper': [100, 150, 200],
				'seeker': [13]}
test_team_2 = {'chaser': [100, 150, 200],
				'beater': [135, 165],
				'keeper': [100, 150, 200],
				'seeker': [7]}

def quidditch_match(team1, team2):
	global player_options
	in_progress = True
	team1_score = 0
	team1_snitch_score = 0
	team2_score = 0
	team2_snitch_score = 0

	offense = team2
	defense = team1
	while in_progress:
		player1 = random.choice(player_options)
		player2 = random.choice(player_options)
		# seekers in play
		if player1 == 'seeker' or player2 == 'seeker':
			seeker_match = random.randrange(0,31)
			if team1['seeker'][0] == seeker_match:
				print(f'''
***
		Team 1's seeker has caught the snitch!
	''')
				team1_snitch_score += 150
				in_progress = False
				break
			elif team2['seeker'][0] == seeker_match:
				print(f'''
***
		Team 2's seeker has caught the snitch!
	''')
				team2_snitch_score += 150
				in_progress = False
				break
			else:
				print(f'''
***
		One of the seekers has seen the snitch!

		The Team1 and Team2 seekers race towards a glint
		of gold in the air, but it quickly disappears.
		Play resumes.
	''')
		# chaser v. keeper
		elif player1 == 'chaser' and player2 == 'keeper':
			player1_value = random.choice(team1[player1])
			player2_value = random.choice(team2[player2])
			if player1_value >= player2_value:
				team1_score += 10
				print(f'''
***
		Team1's chaser throws the quaffle past the keeper
		and scores!
		Team1's score: {team1_score}
	''')
			elif player2_value > player1_value:
				print(f'''
***
		Team1's chaser throws the quaffle, but the Team2
		keeper makes an excellent save!
		Play resumes.
	''')
		elif player2 == 'chaser' and player1 == 'keeper':
			player2_value = random.choice(team1[player1])
			player1_value = random.choice(team2[player2])
			if player2_value >= player1_value:
				team1_score += 10
				print(f'''
***
		Team2's chaser throws the quaffle past the keeper
		and scores!
		Team2's score: {team2_score}
	''')
			elif player1_value > player2_value:
				print(f'''
***
		Team2's chaser throws the quaffle, but the Team1
		keeper makes an excellent save!
		Play resumes.
	''')
		# beaters.
		if player1 == 'beater' or player2 == 'beater':
			player1_value = random.choice(team1[player1])
			player2_value = random.choice(team2[player2])
			# team1 beater
			if player1 == 'beater' and player1_value >= player2_value:
				team1_score += 10
				print(f'''
***
		Team1's beater knocks a bludger toward Team2's
		{player2}. The bludger knocks the {player2} off
		track, allowing Team1's chaser to score a goal!
		Team1's score: {team1_score}
	''')
			elif player1 == 'beater' and player2_value > player1_value:
				team2_score += 10
				print(f'''
***
		Team1's beater tries to knock Team2 off course,
		but the referee calls a foul on the play. During
		the foul shot, Team2 scores!
		Team2's score: {team2_score}
	''')
			elif player2 == 'beater' and player2_value >= player1_value:
				team2_score += 10
				print(f'''
***
		Team2's beater knocks a bludger toward Team1's
		{player2}. The bludger knocks the {player1} off
		track, allowing Team2's chaser to score a goal!
		Team2's score: {team2_score}
	''')
			else:
				team1_score += 10
				print(f'''
***
		Team2's beater tries to knock Team1 off course,
		but the referee calls a foul on the play. During
		the foul shot, Team1 scores!
		Team1's score: {team1_score}
	''')
		else:
			print(f'''
***
		Player 1: {player1}
		Player 2: {player2}
	''')
	# adding house points
	if team1_score > team2_score:
		winner = 'Team1'
	elif team2_score > team1_score:
		winner = 'Team2'
	else:
		winner = 'Tied game!'
	print(f'''
***
		End result:
		Team1: {team1_score + team1_snitch_score}
		Team2: {team2_score + team2_snitch_score}

		Winner: {winner}
	''')
	return [team1_score, team2_score]

game_1 = quidditch_match(test_team_1, test_team_2)
hpc.house_points['Gryffindor'] += game_1[0]
hpc.house_points['Slytherin'] += game_1[1]

print(hpc.display_points())


"""

Author: JW
Date: 07/26/2023
Module Name: picture_capture_controls_uplink.py

Description:
    This Python script is part of an image processing and classification application.
    It provides various functions for interacting with images, databases, and user stacks.
    The script includes functionalities such as simulating image classification, checking classification progress, and updating image labels in a database.
    It is designed to work with Anvil, tkinter, multiprocessing, and PIL (Python Imaging Library) libraries.

Functions:
- `open_file_explorer`: Opens a file explorer dialog for selecting directories.
- `classify_images_simulate`: Simulates image classification and stores results in a database.
- `start_classifier_build`: Initiates the image classification process, handling new or existing image stacks.
- `check_classifier_progress`: Monitors the progress of image classification and retrieves completed labels and images.
- `submit_labels_to_db`: Handles the submission of labels to a database, updates labels, and moves files based on labels.

For detailed information on each function's purpose and usage, please refer to the function definitions and comments within the script.

"""
from time import sleep
import random
import json
import uuid
import multiprocessing
from PIL import Image
import anvil.media
import os
import io
import shutil

# Uplink imports:
try:
    import utils.mySQL_utils as localSQL
    from uplink_scripts.stack import Stack
# Local host imports
except (ModuleNotFoundError) as mod_err:
    print("Trying local host imports in picture_capture_controls.py")
    from ..utils import mySQL_utils as localSQL
    from .stack import Stack

# NOTE: When running from a docker container, we will be unable to import tkinter:
try:
    import tkinter as tk
    from tkinter import filedialog
except(ImportError) as err:
    print("Unable to import tkinter")

# Set up our stack:
image_stack = Stack()

def open_file_explorer():
    """
        Opens a file explorer navigator for the user to select the source and / or destination directory.

        Returns str(file_path)
        *Depending on when function is called, file_path could be either the source or destination dir.
    """
    try:
        root = tk.Tk()
        root.withdraw()

        file_path = filedialog.askdirectory()

        if not file_path:
            file_path = "N/A"

        root.destroy()

        return file_path
    except (Exception) as err:
        print("tikinter not installed...returning empty path")
        return ""

def classify_images_simulate(image_full_path, img_name_list, job_id):
    """ Test function to simulate classify_images()
        1. sleep 5 seconds
        2. randomly pick a class
        3. write result and job id to data-table
    """

    labels = ["Cotton", "Plastic", "HID", "Tray", "Other"]
    cnx = localSQL.sql_connect()

    for index, img in enumerate(image_full_path):
        # 1 sleep
        sleep(10)
        # 2 randomly select a label
        rand = random.randint(0, 4)
        label = labels[rand]
        # write label & job_id to data-table:
        img_name = img_name_list[index]

        insert_query = f"INSERT INTO anvil_imgProcessor (job_id, img_name, img_label) VALUES ('{job_id}','{img_name}','{label}')"

        localSQL.sql_insert(cnx, insert_query)

    # Close db connection
    localSQL.sql_closeConnection(cnx)
    print("Finished classyfing")

def start_classifier_build(json_data):
    """
        json_data: {image_path, num_images}
    """

    # convert json dict to python dict
    python_dict_classifier = json.loads(json_data)

    # Unpack the dictionary:
    page_num = python_dict_classifier.get("page_num")
    user_id = python_dict_classifier.get("user_id")
    num_images = python_dict_classifier.get("num_images")
    file_path = python_dict_classifier.get("file_path_src")

    # IF user wants to grab previous images (back_button press or jump_to_page) -> "pop" images from stack, ELSE get new images
    try:
        # Try getting images from the users stack using page_num as the list index.
        labels, img_names, images, update_database = image_stack.pop(user_id, page_num)

        # If the number of images retrieved == to number of images user currently wants to retrieve, return the images:
        if (int(num_images) == len(img_names)):
            print(f"Retrieved previous images for page {page_num}")
            return images, labels, img_names, update_database
        # If the user changed the number of images to display on each page -> reset stack and grab new images.
        else:
            print(f"Number of images changed... reseting users stack")
            # TODO: If user changed the number of images to grab, reset the users stack:
            image_stack.reset_stack(user_id)
    # If we get a KeyError or IndexError -> grab new images from directory.
    except (KeyError, IndexError) as err:
        print(f"{err}: Grabbing new images for page {page_num}")

    # Set up a job ID:
    job_id = str(uuid.uuid4())

    job_id = job_id.replace("-", "")

    try:
        # NOTE: with large n we may want to only a subset of all images
        all_files_in_dir = os.listdir(file_path)
        # Filter to select only image files:
        all_images = [file for file in all_files_in_dir if file.endswith(".jpg") or file.endswith(".png")]
    except (Exception) as e:
        print("Could not access directory")
        return None

    num_images_found = len(all_images)

    # Check to make sure images were found in the directory:
    if(num_images_found == 0):
        print("Dir does not contain any images")
        return None, None, None, None
    # If for whatever reason the directory has < 10 images -> grab all found images
    if(num_images_found < int(num_images)):
        # Randomly select n images:
        rand_n_imgs = random.sample(all_images, int(num_images_found))
        # now that we've selected our images, lets move them to a seperate folder such that they are not re-used
    else:
        # Randomly select n images:
        rand_n_imgs = random.sample(all_images, int(num_images))
        # now that we've selected our images, lets move them to a seperate folder such that they are not re-used

    #Establish Connection to the Databse:
    cnx = localSQL.sql_connect()

    # Write job ID to anvil_img_Classifier data-table:
    insert_query = f"INSERT INTO anvil_imgProcessor (job_id) VALUES ('{job_id}')"

    localSQL.sql_insert(cnx, insert_query)

    #Close connection to the database:
    localSQL.sql_closeConnection(cnx)

    imgs_full_path, img_name_list  = [], []

    # Loop accomplishes two things:
    # 1) Creates the full image path for each randomly selected image
    # 2) Reads in the image and converts to anvil.BlobMedia
    for image in rand_n_imgs:

        # Get the full image path
        img_full_path = file_path + "/" + image

        # Keep track of all the img paths
        imgs_full_path.append(img_full_path)
        img_name_list.append(image)

    ##############
    # NOTE: SPAWN new process here:
    #classify_images(imgs_full_path, job_id)
    ##############
    process = multiprocessing.Process(target=classify_images_simulate, args=(imgs_full_path, img_name_list, job_id))
    # Start the process
    process.start()

    return job_id

def check_classifier_progress(json_data):
    """
        This function will be called every n seconds once timer reaches 0...
        1. Every n seconds go out and check database to see how many images / n are ready
            1a. if > n images are done, return % finished and update progress bar.
            1b. if n images are done retrieve labels, set flag HIGH indiciating we are ready to display the images to the user

    """

    MAX_STACK_HEIGHT = 50 # Starting with 50, could be increased... (100*num_images) = # of elem ents in each stack

    # convert json dict to python dict
    python_dict_classifier = json.loads(json_data)

    # Unpack the dictionary:
    user_id = python_dict_classifier.get("user_id")
    num_images = python_dict_classifier.get("num_images")
    job_id = python_dict_classifier.get("job_id")
    file_path = python_dict_classifier.get("file_path_src")

    # Check database using job_id to see how many images are ready.
    # Establish Connection to the Databse:
    cnx = localSQL.sql_connect()
    # Create a cursor
    cursor = cnx.cursor()

    search_query = f"SELECT * FROM anvil_imgProcessor WHERE job_id = ('{job_id}')"

    cursor.execute(search_query)
    rows = cursor.fetchall()

    # Close the connection
    cnx.close()

    num_rows_ready = len(rows)
    print(num_rows_ready)

    img_labels_list, img_name_list, img_list = [], [], []
    img_labels_dict = {}

    if(num_rows_ready == (num_images + 1)):
        done_classifying = True # Set our flag to true
        pct_ready = 1
        # Once images are done get the assigned labels:
        for row in rows:
            # Get the assigned label for each image:
            img_labels_list.append(row[-1])
            img_name_list.append(row[-2])

        # Delete the first element of each list (first element has NULL label and img name values)
        del img_labels_list[0]
        del img_name_list[0]

        # Store key-value pair (img_name: label) in dict data-structure
        for i in range(len(img_name_list)):
            img_labels_dict[img_name_list[i]] = img_labels_list[i]

            # Using the image name and file path, import the image to type anvil.BlobMedia
            # Get the full image path
            img_full_path = file_path + "/" + img_name_list[i]

            # Retrieve our image using PIL
            pil_img = Image.open(img_full_path)

            # resize image to 1280 x 960
            resized_image = pil_img.resize((960,720))

            bs = io.BytesIO()
            # Convert to bytes:
            resized_image.save(bs, format="png")

            # Conver to type anvil.BlobMedia so that we can display it for the client
            anvil_image = anvil.BlobMedia("image/png", bs.getvalue(), name="cotton")
            img_list.append(anvil_image)

        print(img_labels_list)
        print(img_labels_dict)

        # Set-up the "stack" here:
        # Pythonic: If user does not have a stack created, create one
        try:
            print(f"Adding images for user {user_id} to stack...")
            image_stack.push(user_id,
                             img_labels_dict,
                             img_name_list,
                             img_list)
        except (KeyError) as ke:
            print("No ID found!")
            print(f"Creating stack for user: {user_id} ")
            image_stack.init_user(user_id,
                                  img_labels_dict,
                                  img_name_list,
                                  img_list)

        #Check length of stack if stack is > max_len --> start removing elements
        try:
            stack_height = image_stack.size(user_id)
            if(stack_height > MAX_STACK_HEIGHT):
                print(f"Users stack reached max height of {MAX_STACK_HEIGHT}, Removing first element...")
                # Delete first [0] from stack
                image_stack.delete_element(user_id)
        except (KeyError) as err:
            print(f"Unable to get height of users stack: {err}")

        return [done_classifying, pct_ready, img_labels_dict, img_name_list, img_list]
    else:
        done_classifying = False
        pct_ready = ((num_rows_ready - 1) / (num_images)) * 100

        return [done_classifying, pct_ready, False, False, False]

def submit_labels_to_db(json_data):
    """
        Retrieves images from src directory, runs through classifier, adds images to users stack, and returns images and labels.

        Function Outline:
        1. Unpack JSON data
        2. Determine if retreiving previously used images, or grabing new images from directory.
            Using a Try / Except statement, that returns a IndexError if the index (page_num) is not valid (aka grab new images then)
        3. Access the source directory (file_path) and randomly selected num_images_to_get from directory.
        4. Convert each image to type Anvil.BlobMedia so that we can display them in a Canvas component.
            4a. TEMPORARY: assign image a "dummy" label of either HID or Cotton
            4b. TODO: ADD in classifers to replace "dummy" labels
        5. Check if user already has a stack made for them, if not create one using user_id
            5a. Add images to already made or newly created user stack
        6. Check if MAX_STACK_HEIGHT has been exceeded, if so remove first entry from stack.
        6. Return the images (img_list), img_labels (img_label_dict), img names (img_name_list), and update_database BOOLEAN indicator

    """

    #Extract our json data into a python dict
    python_dict = json.loads(json_data)

    processed_dir = python_dict.get("file_path_dst")
    #processed_dir = "/home/pi/Desktop/Jon_workspace/Anvil/processed_images" # NOTE: ONLY USED FOR TESTING (REMOVE FOR DEPLOYMENT)

    # Create the destination directory if it doesn't exist
    if not os.path.exists(processed_dir):
        os.makedirs(processed_dir)

    keys_list = []

    # Unpack the dict:
    classifier_labels = python_dict.get("original_labels")
    #human modified labels
    modified_labels = python_dict.get("modified_labels")
    selected_folder = python_dict.get("selected_folder")
    page_num = python_dict.get("page_num")
    user_id = python_dict.get("user_id")
    use_sub_folders = python_dict.get("proc_sub_folders")

    #If user manually specified the path, enter:
    if(selected_folder == "dir"):

        # Add the user modified labels to their stack:
        try:
            print(f"Adding modified labels for user {user_id} to stack...")
            image_stack.push(user_id,
                             user_labels=modified_labels)
        except (KeyError) as ke:
            print("No ID found!")
            print(f"Creating modified labels stack for user: {user_id} ")
            image_stack.init_user(user_id,
                                  user_labels=modified_labels)

        file_path = python_dict.get("file_path_src")
        #file_path = "/home/pi/Desktop/Jon_workspace/Anvil/Cotton" # NOTE: ONLY USED FOR TESTING (REMOVE FOR DEPLOYMENT)

        # Check if we need to set up sub-folders:
        if(use_sub_folders):
            print("Setting up sub folders")
            # Set-up sub-folders for the processed images
            proc_cotton_dir = processed_dir + "/cotton"
            proc_tray_dir = processed_dir + "/tray"
            proc_plastic_dir = processed_dir + "/plastic"
            proc_hid_dir = processed_dir + "/HID"
            proc_other_dir = processed_dir + "/other"
            proc_mislabeled_dir = processed_dir + "/mislabeled"

            # Create the destination directory if it doesn't exist
            if not os.path.exists(proc_cotton_dir):
                os.makedirs(proc_cotton_dir)
            if not os.path.exists(proc_tray_dir):
                os.makedirs(proc_tray_dir)
            if not os.path.exists(proc_plastic_dir):
                os.makedirs(proc_plastic_dir)
            if not os.path.exists(proc_hid_dir):
                os.makedirs(proc_hid_dir)
            if not os.path.exists(proc_other_dir):
                os.makedirs(proc_other_dir)
            if not os.path.exists(proc_mislabeled_dir):
                os.makedirs(proc_mislabeled_dir)

        # get all the keys (image names)
        for key in classifier_labels:
            keys_list.append(key)

        # Next, Establish Connection to the Databse:
        cnx = localSQL.sql_connect()

        # Loop through each key(image name) and add to correct db column
        for key in range(len(keys_list)):
            image_name = keys_list[key]
            orginal_label = classifier_labels[keys_list[key]]
            corrected_label = modified_labels[keys_list[key]]

            # Get our source path (used with moving the image):
            source_path = os.path.join(file_path, image_name)
            # Get our processed img path:
            dest_path = os.path.join(processed_dir, image_name)

            if(orginal_label == corrected_label):
                correctP = True
                # Add to to columns: Correct_column, JOINT, and Path
                add_query = f"INSERT INTO anvil_imgClassification ({corrected_label}, JOINT, Path) VALUES ('{str(keys_list[key])}', '{str(orginal_label)}' ,'{str(source_path)}')"
                localSQL.sql_insert(cnx, add_query)
            else:
                # If the classifier got the prediction wrong, add img file name to GotWrong column and correct column in database
                correctP = False
                # Add to to columns: GotWrong, Correct_column, JOINT, and Path
                gotWrong_query = f"INSERT INTO anvil_imgClassification (GotWrong, {corrected_label}, JOINT, Path) VALUES ('{str(keys_list[key])}', '{str(keys_list[key])}', '{str(orginal_label)}' , '{str(source_path)}')"
                localSQL.sql_insert(cnx, gotWrong_query)

            #Lastly, move image to new processed directory:
            try:
                if(use_sub_folders):
                    if(corrected_label == "Cotton"):
                        shutil.copy(source_path, proc_cotton_dir)
                    elif(corrected_label == "Plastic" ):
                        shutil.copy(source_path, proc_plastic_dir)
                    elif(corrected_label == "HID" ):
                        shutil.copy(source_path, proc_hid_dir)
                    elif(corrected_label == "Tray" ):
                        shutil.copy(source_path, proc_tray_dir)
                    elif(corrected_label == "Other" ):
                        shutil.copy(source_path, proc_other_dir)

                    # Check if we also need to move file to the GotWrong fodler:
                    if(correctP):
                        # Delete the file from the src directory
                        if os.path.exists(source_path):
                            os.remove(source_path)
                    else:
                        # move file to the GotWrong folder:
                        shutil.move(source_path, proc_mislabeled_dir)
                else:
                    shutil.move(source_path, dest_path)
            except (FileNotFoundError) as e_file:
                return

        #Close connection to the database:
        localSQL.sql_closeConnection(cnx)

        return

    elif(selected_folder == "update"):

        # Need to update modified labels stack:
        print(f"Updating modified labels from page {page_num} for user {user_id}")
        image_stack.update_stack(user_id, page_num, user_labels=modified_labels)

        # Names of table columns, will be iterated over
        column_names = ["Cotton","Plastic", "HID", "Tray", "Other"]

        print("Updating database...")

        # Search through CSV and find the lines that need to be altered:

        # get all the keys
        for key in classifier_labels:
            keys_list.append(key)

        # Next, Establish Connection to the Databse:
        cnx = localSQL.sql_connect()
        # Create a cursor
        cursor = cnx.cursor()

        for key in range(len(keys_list)):
            image_name = keys_list[key]
            corrected_label = modified_labels[keys_list[key]]

            #Iterate over the possible column (labels) in the table:
            for column in column_names:
                #Search for img name in each column to get the row:
                search_query = f"SELECT * FROM anvil_imgClassification WHERE {column} = ('{str(keys_list[key])}')"

                cursor.execute(search_query)
                result = cursor.fetchone()
                try:
                    cnx.commit()
                except (Exception) as err:
                    pass

                # RESULT RETURNED FORMAT: (row_number(id), user_id, Cotton, Plastic, Tray, HID, Other, GotWrong, PATH, JOINT) of type tuple
                if result:

                    if corrected_label == column:
                        print(f"No need to update img {image_name} found in {column} with label {corrected_label}, breaking out...")
                        break

                    # print(f"result value returned: {result}")
                    # print(f"Image name {str(keys_list[key])}")

                    # Get row number:
                    row_number = str(result[0])
                    # print(f"column value: {row_number}")
                    # Get JOINT value:
                    joint_value = str(result[-1])
                    # Set row value in previous column and GotWrong column to None:
                    update_query = "UPDATE anvil_imgClassification SET %s = NULL, GotWrong = NULL WHERE id = %s"%(column, row_number)
                    cursor.execute(update_query)
                    cnx.commit()

                    # check if joint == new_label
                    if(joint_value == corrected_label):
                        print("Joint == Correct!")
                        # Add img name to the corrected_label colum in row_number:
                        update_query = f"UPDATE anvil_imgClassification SET {str(corrected_label)} = '{str(keys_list[key])}' WHERE id = '{row_number}'"
                        cursor.execute(update_query)
                        cnx.commit()
                    else:
                        update_query =f"UPDATE anvil_imgClassification SET {str(corrected_label)} = '{str(keys_list[key])}', GotWrong = '{str(keys_list[key])}' WHERE id = '{row_number}'"
                        cursor.execute(update_query)
                        cnx.commit()

                    # print("breaking..")
                    break

                else:
                    print(f"result not found in column {column}")

    #Close connection to the database:
    cnx.close()

    return


from logging import Logger
from extract.adapters.airtable.credentials import AirtableCredentials
from pyairtable import Table

class AirTableAdapter:
    def __init__(self, logger: Logger, credentials: AirtableCredentials):
        self.logger = logger
        self.api_key = credentials.api_key
        self.base_id = credentials.base_id

    def extract(self, table_ids: list) -> dict:
        data_fetched = {}
        dict_of_data = {}

        for table_id in table_ids:
            try:
                table = Table(self.api_key, self.base_id, table_id)
                dict_of_data[table_id] = table.all()
                data_fetched[table_id] = True
            except RuntimeError:
                self.logger.error(f"loading of airtable '{table_id}' data has not been successful")

        for table_id in data_fetched:
            if data_fetched[table_id] is True:
                self.logger.info(f"loading of airtable '{table_id}' data has been successful")

        return dict_of_data


class Solution:
    def strToInt(self, s: str) -> int:
        s = s.lstrip()
        if not s:
            return 0
        res = 0
        i = 1
        is_positive = True
        max_int = 2 ** 31 - 1
        if s[0] == "-":
            is_positive = False
        elif s[0] != "+":
            i = 0
        for c in s[i: ]:
            if not "0" <= c <= "9":
                break
            res = 10 * res + ord(c) - ord("0")
            if res > max_int:
                return max_int if is_positive else -max_int - 1
        return res if is_positive else -res

# class Solution:
#     def strToInt(self, s: str) -> int:
#         nums = {str(x): x for x in range(10)}
#         # 跳过开头无用空格
#         i = 0
#         while i < len(s) and s[i] == " ":
#             i += 1
#         # 字符串为空或字符串仅包含空白字符
#         if i == len(s):
#             return 0
#         int_max = 2 ** 31 - 1
#         int_min = -(2 ** 31)
#         if s[i] == "+":
#             res = 0
#             i += 1
#             while res < int_max and i < len(s) and s[i] in nums:
#                 res = res * 10 + nums[s[i]]
#                 i += 1
#             return res if res < int_max else int_max
#         elif s[i] == "-":
#             res = 0
#             i += 1
#             while res < -int_min and i < len(s) and s[i] in nums:
#                 res = res * 10 + nums[s[i]]
#                 i += 1
#             return -res if -res > int_min else int_min
#         elif s[i] in nums:
#             res = 0
#             while res < int_max and i < len(s) and s[i] in nums:
#                 res = res * 10 + nums[s[i]]
#                 i += 1
#             return res if res < int_max else int_max
#         else:
#             return 0

code/面试题67. 把字符串转换成整数.py

面试题67. 把字符串转换成整数.py


from socket import *
import time
import osascript
from multiprocessing import Process, Manager, Value
import os
#osascript -e 'display notification "{}" with title "{}"'

volume = 0

def recieve_data(val):
    serverSock = socket(AF_INET, SOCK_STREAM)
    serverSock.bind(('', 7777))
    serverSock.listen(1)
    connectionSock, addr = serverSock.accept()
    print("Client address : ", str(addr))

    while True:
        print("val : ", val.value)
        try :
            vol = int(connectionSock.recv(4).decode('utf-8'))
            if vol == 1111:
                print("mute")
                osascript.osascript('set volume output muted TRUE')
                val.value = 0
                while True:
                    vol = int(connectionSock.recv(4).decode('utf-8'))
                    if vol == 2222:
                        osascript.osascript('set volume output muted FALSE')
                        break

            if vol == 3333:
                print("screenshot")
                os.system("screencapture screen.png")
                vol = 0

            if vol == 4444:
                print("fix volume")
                osascript.osascript('tell app "System Events" to shut down')
                time.sleep(5)
            if vol < 300:
                val.value = vol
        except:
            pass

def volume_control(val):
    while True:
        print("volume : ", val.value)
        osascript.osascript("set volume output volume " + str(val.value))
        time.sleep(0.1)

if __name__ == '__main__':
    v = Value('i', 0)
    p0 = Process(target = recieve_data, args = (v,))
    p0.start()

    p1 = Process(target = volume_control, args = (v,))
    p1.start()

    p0.join()
    p1.join()


import argparse
import numpy as np
import cv2
import time
import math

from sympy.solvers import solve
from sympy import Symbol

X_POS = 0
Y_POS = 1
Thresh = 170
imageName = "picture.jpg"

def modImage(sceneName, img, kernel, erodeNum, dilateNum, invertion=False):
	ret, result = cv2.threshold(img, Thresh, 255, cv2.THRESH_BINARY+cv2.THRESH_OTSU)

	if(invertion):
		result = cv2.bitwise_not(result)

	result = cv2.erode(result, kernel, iterations=erodeNum)
	result = cv2.dilate(result, kernel, iterations=dilateNum)

	result = cv2.GaussianBlur(result, (5,5), 0)

	return result

def searchBorder(img, numOfBorder):
	result_point = []
	myQ = []

	height, width = img.shape[:2]

	visited = [[False for rows in range(0, height)]for cols in range(0, width)]

	#direction = [ [0, -1], [1, -1], [1, 0], [1, 1], [0, 1], [-1, 1], [-1, 0], [-1, -1] ]

	direction = [ [0, 1], [1, 1], [1, 0], [-1, 1], [-1, 0], [-1, 1], [0, -1], [1, -1]]
	start_x = int(width / 2)
	start_y = int(height / 2)

	startBorder = False
	borderCounter = 0

	search_cursor_x = -1
	search_cursor_y = -1

	for y in range(start_y, 0, -1):
		for x in range(start_x, 0, -1):

			if(img[y][x] != 0 and not startBorder):
				startBorder = True
				search_cursor_x = x
				search_cursor_y = y
				borderCounter += 1

			elif(img[y][x] != 0 and startBorder):
				startBorder = False
				borderCounter = 0

			elif(img[y][x] == 0 and startBorder):
				borderCounter += 1

			if(startBorder and borderCounter > 10):
				myQ.append([search_cursor_x, search_cursor_y])

				while len(myQ) != 0:
					point = myQ.pop(0)

					try:
						if(visited[point[Y_POS]][point[X_POS]]):
							continue
					except:
						continue

					visited[point[Y_POS]][point[X_POS]] = True
					result_point.append(point)
					if( len(result_point) >= numOfBorder ):
						return result_point

					test_border = False
					temp_list = []
					for dir in direction:
						next_point = [ point[X_POS] + dir[X_POS], point[Y_POS] + dir[Y_POS] ]

						try:
							if(img[next_point[Y_POS]][next_point[X_POS]] == 0):
								temp_list.append(next_point)
							else:
								test_border = True
						except:
							continue

					if(test_border):
						for temp_point in temp_list:
							myQ.append(temp_point)

				return result_point

def findCircleCenter(pointA, pointB, pointC):
	x = Symbol('x')
	y = Symbol('y')

	AB_center_x = (pointA[X_POS] + pointB[X_POS])/2
	AB_center_y = (pointA[Y_POS] + pointB[Y_POS])/2
	AB_incline = (pointA[X_POS] - pointB[X_POS]) / (pointA[Y_POS] - pointB[Y_POS])

	equation1 = AB_incline * x + y - AB_incline*AB_center_x - AB_center_y

	AC_center_x = (pointA[X_POS] + pointC[X_POS])/2
	AC_center_y = (pointA[Y_POS] + pointC[Y_POS])/2
	AC_incline = (pointA[X_POS] - pointC[X_POS]) / (pointA[Y_POS] - pointC[Y_POS])

	equation2 = AC_incline * x + y - AC_incline*AC_center_x - AC_center_y

	result = solve( (equation1, equation2), dict=True)
	temp_total = math.pow(result[0][x] - pointA[X_POS], 2) + math.pow(result[0][y] - pointA[Y_POS], 2)
	radius = math.sqrt(temp_total)

	return int(result[0][x]), int(result[0][y]), int(radius)

def findResult(pointList, rate):
	unit_length = int(len(pointList) / 3)
	total_length = int(len(pointList) - unit_length*2)

	result = {}

	for i in range(0, rate):
		try:
			x,y,radius = findCircleCenter(pointList[i], pointList[i+unit_length], pointList[i+unit_length*2])
			if (x,y) in result:
				result[(x,y)].append(radius)
			else:
				result[(x,y)] = [ radius ]

		except:
			continue

		if(x < 0 or y < 0):
			continue

	if len(result) == 0:
		return None, None, None

	max_key = max(result, key=lambda p: len(result[p]))
	max_value = result[max_key]

	return int(max_key[0]), int(max_key[1]), int(sum(max_value) / float(len(max_value)))

def drawCircle(pointList, output_image, point_color, circle_color, rate):
	unit_length = int(len(pointList) / 3)
	total_length = int(len(pointList) - unit_length*2)

	for i in range(0, rate):
		try:
			x,y,radius = findCircleCenter(pointList[i], pointList[i+unit_length], pointList[i+unit_length*2])
		except:
			continue

		if(x < 0 or y < 0):
			continue

		cv2.circle(output_image, (x,y), radius, circle_color, 1)
		cv2.rectangle(output_image, (x-2, y-2), (x+2, y+2), point_color, -1)

def getPupil(eye_img):
	pupilImg = cv2.inRange(eye_img.copy(), (30,30,30), (80,80,80))

	_, contours, __ = cv2.findContours(pupilImg, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
	del pupilImg
	pupilImg = eye_img.copy()

	for cnt in contours:
		moments = cv2.moments(cnt)
		area = moments['m00']
		if (area > 50):
			pupilArea = area
			x = moments['m10']/area
			y = moments['m01']/area
			pupil = contours
			global centroid
			centroid = (int(x),int(y))
			cv2.drawContours(pupilImg, pupil, -1, (0,255,0), -1)
			break

	return (pupilImg)

def irisDetect_debug(output, image, scale, rate):
	kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5,5))

	processed_img = getPupil(image.copy())

	hsv = cv2.cvtColor(processed_img, cv2.COLOR_BGR2HSV)
	(channel_h, channel_s, channel_v) = cv2.split(hsv)
	cv2.imshow("hue", channel_h)
	cv2.imshow("saturation", channel_s)
	cv2.imshow("value", channel_v)

	pupil = modImage("pu_man", channel_h, kernel, 5, 5)
	iris = modImage("ir_man", channel_v, kernel, 8, 8, True)
	cv2.imshow("pupil", pupil)
	cv2.imshow("iris", iris)

	pupil_point_list = searchBorder(pupil, scale)
	iris_point_list = searchBorder(iris, scale)

	if not pupil_point_list is None:
		drawCircle(pupil_point_list, output, (255, 255, 0), (0, 255, 0), rate)

	if not iris_point_list is None:
		drawCircle(iris_point_list, output, (0, 255, 255), (255, 0, 0), rate)

def irisDetect(output, image, scale, rate):
	kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5,5))

	processed_img = getPupil(image.copy())

	hsv = cv2.cvtColor(processed_img, cv2.COLOR_BGR2HSV)
	(channel_h, channel_s, channel_v) = cv2.split(hsv)

	pupil = modImage("pu_man", channel_h, kernel, 5, 5)
	iris = modImage("ir_man", channel_v, kernel, 8, 8, True)

	pupil_point_list = searchBorder(pupil, scale)
	iris_point_list = searchBorder(iris, scale)

	if not pupil_point_list is None:
		x,y,radius = findResult(pupil_point_list, rate)

		if x is not None:
			cv2.circle(output, (x,y), radius, (0, 255, 0), 1)
			cv2.rectangle(output, (x-2, y-2), (x+2, y+2), (255, 255, 0), -1)
	"""
	if not iris_point_list is None:
		x,y,radius = findResult(iris_point_list, rate)

		if x is not None:
			cv2.circle(output, (x,y), radius, (255, 0, 0), 1)
			cv2.rectangle(output, (x-2, y-2), (x+2, y+2), (0, 255, 255), -1)
	"""

if __name__ == "__main__":
	image = cv2.imread(imageName)
	output = image.copy()

	irisDetect(output, image, 1500, 30)
	cv2.imshow("display", output)

	cv2.waitKey(0)
	if cv2.waitKey(1)&0xFF == ord('q'):
		cv2.destroyAllWindows()


'''
스도쿠
https://www.acmicpc.net/problem/2580
'''
import sys

sudoku = [list(map(int,sys.stdin.readline().split())) for _ in range(9)]
zeros = [(i,j) for i in range(9) for j in range(9) if sudoku[i][j] == 0]
is_complete = [False]

def check_horizontal(x,val):
    if val in sudoku[x]:
        return False
    return True

def check_vertical(y, val):
    for index in range(9):
        if val == sudoku[index][y]:
            return False
    return True

def check_sqaure(x,y,val):
    _x = x//3 * 3
    _y = y//3 * 3

    for i in range(3):
        for j in range(3):
            if val == sudoku[_x+i][_y+j]:
                return False
    return True

def solve(x):
    if is_complete[0]:
        return
    if len(zeros) == x:
        for row in sudoku:
            for val in row:
                print(val, end=' ')
            print()
        is_complete[0] = True
    else:
        for i in range(1,10):
            nx = zeros[x][0]
            ny = zeros[x][1]
            if check_horizontal(nx, i) and check_vertical(ny, i) and check_sqaure(nx,ny, i):
                sudoku[nx][ny] = i
                solve(x+1)
                sudoku[nx][ny] = 0
solve(0)


import re
import os
import socket
from threading import Thread, Event
import subprocess
import time
from shutil import copyfile

from tiny_test_fw import Utility, DUT
import ttfw_idf

stop_sock_listener = Event()
stop_io_listener = Event()
sock = None
client_address = None
manual_test = False

def io_listener(dut1):
    global sock
    global client_address
    data = b''
    while not stop_io_listener.is_set():
        try:
            data = dut1.expect(re.compile(r"PacketOut:\[([a-fA-F0-9]+)\]"), timeout=5)
        except DUT.ExpectTimeout:
            continue
        if data != () and data[0] != b'':
            packet_data = data[0]
            print("Packet_data>{}<".format(packet_data))
            response = bytearray.fromhex(packet_data.decode())
            print("Sending to socket:")
            packet = ' '.join(format(x, '02x') for x in bytearray(response))
            print("Packet>{}<".format(packet))
            if client_address is not None:
                sock.sendto(response, ('127.0.0.1', 7777))

def sock_listener(dut1):
    global sock
    global client_address
    sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    sock.settimeout(5)
    server_address = '0.0.0.0'
    server_port = 7771
    server = (server_address, server_port)
    sock.bind(server)
    try:
        while not stop_sock_listener.is_set():
            try:
                payload, client_address = sock.recvfrom(1024)
                packet = ' '.join(format(x, '02x') for x in bytearray(payload))
                print("Received from address {}, data {}".format(client_address, packet))
                dut1.write(str.encode(packet))
            except socket.timeout:
                pass
    finally:
        sock.close()
        sock = None

@ttfw_idf.idf_example_test(env_tag="Example_WIFI")
def lwip_test_suite(env, extra_data):
    global stop_io_listener
    global stop_sock_listener
    """
    steps: |
      1. Rebuilds test suite with esp32_netsuite.ttcn
      2. Starts listeners on stdout and socket
      3. Execute ttcn3 test suite
      4. Collect result from ttcn3
    """
    dut1 = env.get_dut("net_suite", "examples/system/network_tests", dut_class=ttfw_idf.ESP32DUT)
    # check and log bin size
    binary_file = os.path.join(dut1.app.binary_path, "net_suite.bin")
    bin_size = os.path.getsize(binary_file)
    ttfw_idf.log_performance("net_suite", "{}KB".format(bin_size // 1024))
    ttfw_idf.check_performance("net_suite", bin_size // 1024, dut1.TARGET)
    dut1.start_app()
    thread1 = Thread(target=sock_listener, args=(dut1, ))
    thread2 = Thread(target=io_listener, args=(dut1, ))
    if not manual_test:
        # Variables refering to esp32 ttcn test suite
        TTCN_SRC = 'esp32_netsuite.ttcn'
        TTCN_CFG = 'esp32_netsuite.cfg'
        # System Paths
        netsuite_path = os.getenv("NETSUITE_PATH")
        netsuite_src_path = os.path.join(netsuite_path, "src")
        test_dir = os.path.dirname(os.path.realpath(__file__))
        # Building the suite
        print("Rebuilding the test suite")
        print("-------------------------")
        # copy esp32 specific files to ttcn net-suite dir
        copyfile(os.path.join(test_dir, TTCN_SRC), os.path.join(netsuite_src_path, TTCN_SRC))
        copyfile(os.path.join(test_dir, TTCN_CFG), os.path.join(netsuite_src_path, TTCN_CFG))
        proc = subprocess.Popen(['bash', '-c', 'cd ' + netsuite_src_path + ' && source make.sh'],
                                cwd=netsuite_path, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        output = proc.stdout.read()
        print("Note: First build step we expect failure (titan/net_suite build system not suitable for multijob make)")
        print(output)
        proc = subprocess.Popen(['bash', '-c', 'cd ' + netsuite_src_path + ' && make'],
                                cwd=netsuite_path, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        print("Note: This time all dependencies shall be generated -- multijob make shall pass")
        output = proc.stdout.read()
        print(output)
        # Executing the test suite
        thread1.start()
        thread2.start()
        time.sleep(2)
        print("Executing the test suite")
        print("------------------------")
        proc = subprocess.Popen(['ttcn3_start', os.path.join(netsuite_src_path,'test_suite'), os.path.join(netsuite_src_path, TTCN_CFG)],
                                stdout=subprocess.PIPE)
        output = proc.stdout.read()
        print(output)
        print("Collecting results")
        print("------------------")
        verdict_stats = re.search('(Verdict statistics:.*)', output)
        if verdict_stats:
            verdict_stats = verdict_stats.group(1)
        else:
            verdict_stats = b""
        verdict = re.search('Overall verdict: pass', output)
        if verdict:
            print("Test passed!")
            Utility.console_log(verdict_stats, "green")
        else:
            Utility.console_log(verdict_stats, "red")
            raise ValueError('Test failed with: {}'.format(verdict_stats))
    else:
        try:
            # Executing the test suite
            thread1.start()
            thread2.start()
            time.sleep(2)
            while True:
                time.sleep(0.5)
        except KeyboardInterrupt:
            pass
    print("Executing done, waiting for tests to finish")
    print("-------------------------------------------")
    stop_io_listener.set()
    stop_sock_listener.set()
    thread1.join()
    thread2.join()

if __name__ == '__main__':
    print("Manual execution, please build and start ttcn in a separate console")
    manual_test = True
    lwip_test_suite()


import sys
#sys.stdin=open("A.txt","r")
#n,m=map(int,input().split()) #정n면체 정m면
#a=list(map(int,input().split()))
res=0
N=int(input())
#a=list(map(int,input().split())) 이거는 [1,2,3,4,5]이런식
for i in range(N):
    tmp=input().split()          #이거는['3','3','6']이렇게 문자열로저장
    tmp.sort()
    a,b,c=map(int,tmp)
    #print(a,b,c)
    if a==b and b==c:
        money=10000+a*1000
    elif a==b or b==c or a==c:
        if a==b or a==c:
            money= 1000+a*100
        elif b==c:
            money= 1000+b*100
    else:
        money=c*100#오름차순

    if money>res:
        res=money

print(res)

코드구현력기르기Part/주사위게임.py


''' Write a program which accepts a
string as input to print "Yes" if the
 string is "yes" or "YES" or "Yes",
 otherwise print "No". '''

str_val= input("enter a string : ")

if str_val == 'yes' or str_val =='YES' or str_val =='Yes':
    print("Yes")
else:
    print("No")


import networkx as nx
from sklearn.cluster import SpectralClustering

def spectral_clustering(G, n_clusters=2):
    adj_mat = nx.to_numpy_matrix(G)
    sc = SpectralClustering(n_clusters, affinity='precomputed', n_init=100)
    sc.fit(adj_mat)
    clusters = {}
    for i in range(len(sc.labels_)):
        if sc.labels_[i] not in clusters:
            clusters[sc.labels_[i]] = []
        clusters[sc.labels_[i]].append(i)
    return clusters.values()


###############################################################################
#  Process to read Customer Updates                                           #
#
#  Pre-requisites: Kafka server should be running                             #
###############################################################################
import os
import sys
import logging
import json

import settings as SETTINGS

curpath = os.path.dirname(__file__)
sys.path.append(os.path.abspath(os.path.join (curpath, "../")))

from app_messaging_utils import SimpleKafkaConsumer, SimpleKafkaMessage
from app_models import Customer, AppEventType
from app_utils import MongoRepository, DbEntity

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

class MessageProcessor():

    def __init__(self, process_func=None):

        #Create and configure logger
        logfile = os.path.abspath('{0}/{1}'.format(SETTINGS.Logging["LogFolder"],SETTINGS.Logging["LogFile"]))
        os.makedirs(os.path.dirname(logfile), exist_ok=True)

        logging.basicConfig(
            filename=logfile,
            format='%(asctime)s %(message)s',
            filemode='a'
        )

        #Creating an object
        self.logger=logging.getLogger()

        #Setting the threshold of logger to DEBUG
        self.logger.setLevel(SETTINGS.Logging["LogLevel"])

        self.config = SETTINGS.KafkaService
        self.topic  = SETTINGS.MESSAGE_TOPIC

        self.customer_repo = MongoRepository(
            logger=self.logger,
            server=SETTINGS.MongoDB["Url"],
            port=SETTINGS.MongoDB["Port"],
            database=SETTINGS.MongoDB["Db"],
            collection=SETTINGS.MongoDB["Collection"],
            session_id=1)

    ###########################################################################
    def process_message(self, evt_msg: SimpleKafkaMessage):
        '''
            Function to process SimpleKafkaMessage

            Deserialize the SimpleKafkaMessage,
            extract and process relevant payload
        '''
        try:

            evt = json.loads(evt_msg.message)

            if evt["app_event_type"] == AppEventType.Insert:
                entity = evt["after_change"]
                customer = Customer(
                    id=entity["id"],
                    name=entity["name"],
                    phone=entity["phone"],
                    email=entity["email"]
                )

                msg="Processing INSERT message for customer id:{0}".format(customer.id)
                print(msg)

                eid = self.customer_repo.create(customer)  # expect to get back an ObjectId

                msg="Created customer id:{0}".format(customer.id)
                print(msg)
                self.logger.debug(msg)

            elif evt["app_event_type"] == AppEventType.Update:
                entity = evt["after_change"]
                customer = Customer(
                    id=entity["id"],
                    name=entity["name"],
                    phone=entity["phone"],
                    email=entity["email"]
                )

                msg="Processing UPDATE message for customer id:{0}".format(customer.id)
                print(msg)

                self.customer_repo.update_by_id(customer.id, customer)
                msg="Updated customer id:{0}".format(customer.id)
                print(msg)
                self.logger.debug(msg)

            elif evt["app_event_type"] == AppEventType.Delete:
                entity = evt["after_change"]
                customer = Customer(
                    id=entity["id"],
                    name=entity["name"],
                    phone=entity["phone"],
                    email=entity["email"]
                )

                msg="Processing DELETE message for customer id:{0}".format(customer.id)
                print(msg)

                self.customer_repo.delete_by_id(customer.id)

                msg="Deleted customer id:{0}".format(customer.id)
                print(msg)
                self.logger.debug(msg)

            else:
                pass

        except Exception as e:
            msg = "Error in process_message function: {0}".format(str(e))
            print(msg)
            self.logger.error(msg)

    ###########################################################################
    def read_messages(self):
        '''
            Function to read messages from kafka queue
        '''
        reader_id = self.config["group.id"]
        counter=0

        try:
            msg = "Starting Process:{0} to read topic:{1} from Kafka Queue".format( reader_id , self.topic )
            self.logger.info(msg)
            print(msg)

            consumer = SimpleKafkaConsumer(logger=self.logger)
            consumer.configure(config=self.config)

            print ("Starting Consumer")
            for evt_msg in consumer.consume(topics=['MICROSERVICE-CUSTOMER-UPDATES']):

                counter +=1

                # msg = "Received msg: {0} # {1}".format(counter, evt_msg.message)
                # print(msg)
                # self.logger.debug(msg)

                # Process the message
                self.process_message(evt_msg)

        except KeyboardInterrupt:
            msg = "\n\n Exiting Process:'{0}'. {1} message(s) read on topic from Kafka Queue:'{2}'".format( reader_id, counter, self.topic )
            print (msg)
            self.logger.info(msg)

        except Exception as e:
            msg = "Error in {0} : {1}".format(reader_id, str(e))
            print(msg)
            self.logger.error(msg)

###############################################################################
if __name__ == "__main__":

    MessageProcessor().read_messages()

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


import sys
sys.path.append('D:/Users/Murph Strange/Jupyter Notebook/')
import menus
import random
import types

class Character:
    def __init__(self, name):
        self.name = name
        self.strength = 16
        self.intellect = 16
        self.resilience = 16

        #ability to run away (TODO: implement Escape action?)
        self.agility = 16

        self.max_hp = 16
        self.hp = self.max_hp
        self.max_mp = 16
        self.mp = self.max_mp

        self.attack_power = 0
        self.defense_power = 0

        self.equipment = {
            "weapon": False,
            "armor": False,
            "shield": False
        }
        self.status = []
        self.inventory = {}
        self.spellbook = {}

    def alive(self):
        if "deceased" not in self.status:
            return True

        else:
            print("%s is a corpse.\n" % self.name)
            return False

    def health(self, change = 0):
        self.hp += change
        if change == 0:
            return self.hp

        elif self.alive() and (change < 0):
            print("%s takes %d damage.\n" % (self.name, abs(change)))
            if self.hp < 1:
                self.hp = 0
                print("%s has died.\n" % self.name)
                self.status = ["deceased"]

            return True

        elif self.alive() and (change > 0):
            print("%s restores %d hp.\n" % (self.name, change))
            if self.hp > self.max_hp:
                self.hp = self.max_hp
                print("%s's health is fully restored!\n" % self.name)

            return True

        else:
            return False

    def magic(self, change = 0):
        if change == 0:
            return self.mp

        elif self.alive() and (change < 0):
            if abs(change) > self.mp:
                print("%s doesn't have enough magic!\n" % self.name)
                return False

            else:
                self.mp += change
                print("%s expends %d magic.\n" % (self.name, abs(change)))
                if self.mp < 1:
                    self.mp = 0
                    print("%s has depleted their magic.\n" % self.name)

                return True

        elif self.alive() and (change > 0):
            self.mp += change
            print("%s restores %d  mp.\n" % (self.name, change))
            if self.mp > self.max_mp:
                self.mp = self.max_mp
                print("%s's magic has been fully restored!\n" % self.name)

            return True

        else:
            return False

    def drink(self, item):
        if item in self.inventory.keys():
            return self.inventory[item].drink(self)

        else:
            print("%s can't drink a %s.\n" % (self.name, item))
            return False

    def equip(self, item):
        if item in self.inventory.keys():
            return self.inventory[item].equip(self)

        else:
            print("%s can't equip a %s.\n" % (self.name, item))
            return False

    def attack(self, target):
        if self.equipment["weapon"]:
            return self.equipment["weapon"].attack(self, target)

        else:
            print("%s is unarmed.\n" % self.name)
            return False

    def defend(self):
        return self.defense_power

    def cast(self, spell, target):
        if spell in self.spellbook.keys():
            print("%s casts %s.\n" % (self.name, spell))
            return self.spellbook[spell].cast(target, self)

        else:
            print("%s can't cast %s.\n" % (self.name, spell))
            return False

    def speak(self, target):
        #Options to converse, trade, engage in combat
        pass

class NPCharacter(Character):
    def __init__(self, name):
        super().__init__(name)
        pass

    def health(self, change = 0):
        res = super().health(change)
        if self.alive() and self.hp < int(self.max_hp/3):
            self.drink("red potion")

        return res

    def magic(self, change = 0):
        res = super().magic(change)
        if self.alive() and self.mp < int(self.max_mp/3):
            self.drink("blue potion")

        return res

    def speak(self, target):
        #Options to converse, trade, or engage in combat
        #overwrite this method with the dialog menus of
        #your choice, using menus and types.MethodType()
        print("%s says" % self.name)
        dialog = menus.Menu('"Continue?"', ['y', 'n'])
        res = dialog.display_prompt()
        return res

class PlayerCharacter(Character):
    def __init__(self, name):
        super().__init__(name)

        self.gold = 100
        self.level = 1
        self.xp = 0
        self.quest_flags = {}

    def speak(self, target):
        if self.alive() and target.alive():
            if type(target) == PlayerCharacter:
                #player character options (trade? duel? invite to party?)
                pass

            elif type(target) == NPCharacter:
                #invoke npc's menus for dialog,
                #changes depending on what the
                #npc is (foe, merchant, quest giver)
                return target.speak(self)

            else:
                print("%s can't speak to that.\n" % self.name)
                return False

        else:
            print("%s can't speak to %s.\n" % (self.name, target.name))
            return False

class MonsterCharacter(NPCharacter):
    def __init__(self, name, health, magic, attack_power, defense_power, agility, xp, gold, spell_list = []):
        super().__init__(name)

        self.max_hp = health
        self.hp = self.max_hp
        self.max_mp = magic
        self.mp = self.max_mp

        self.attack_power = attack_power
        self.defense_power = defense_power
        self.agility = agility

        self.xp = xp
        self.gold = gold

        for item in spell_list:
            self.spellbook[item] = Spell(item, spells[item][0], spells[item][1], spells[item][2])

    def attack(self, target):
        if self.equipment["weapon"]:
            return self.equipment["weapon"].attack(self, target)

        else:
            if self.alive() and target.alive():
                damage = random.randint(int((self.strength + self.attack_power)/3), self.strength + self.attack_power)
                print("%s attacks %s!\n" % (self.name, target.name))
                if random.randint(0, 7) in [3, 5]:
                    print("%s misses!\n" % self.name)
                    damage = 0

                else:
                    print("%s deals %d damage.\n" % (self.name, damage))
                    target_defense = target.defend()
                    if target.equipment["shield"]:
                        target_defense += target.equipment["shield"].defend()

                    if target.equipment["armor"]:
                        target_defense += target.equipment["armor"].defend()

                    resist = random.randint(int((target.resilience + target_defense)/3), target.resilience + target_defense)
                    print("%s has a defense rating of %d.\n" % (target.name, target_defense))
                    print("%s resists %d damage.\n" % (target.name, resist))
                    damage -= resist
                    if damage <= 0:
                        damage = 0
                        print("%s blocks the attack!\n" % target.name)

                target.health(-damage)
                return True

            else:
                return False

class Effect():
    def __init__(self, name, power):
        self.name = name
        self.power = power

class Potion(Effect):
    def __init__(self, name, attribute, power, quantity = 0):
        super().__init__(name, power)
        self.attribute = attribute
        self.quantity = quantity

    def pay(self, caster):
        if caster.inventory[self.name].quantity > 0:
            caster.inventory[self.name].quantity -= 1
            return True

        else:
            print("%s has no %s left.\n" % (caster.name, self.name))
            return False

    def drink(self, caster):
        if caster.alive() and self.pay(caster):
            print("%s drinks a %s.\n" % (caster.name, self.name))
            if self.attribute == 'hp':
                caster.health(self.power)

            elif self.attribute == 'mp':
                caster.magic(self.power)

            return True

        else:
            return False

class Spell(Effect):
    def __init__(self, name, cost, power, status = 'none'):
        super().__init__(name, power)
        self.cost = cost
        self.status = status

    def pay(self, caster):
        if caster.magic() > self.cost:
            caster.magic(-self.cost)
            return True

        else:
            return False

    def cast(self, target, caster):
        if caster.alive() and target.alive() and self.pay(caster):
            damage = random.randint(int((caster.intellect + self.power)/2), caster.intellect + self.power)
            print("%s deals %d damage.\n" % (self.name.capitalize(), damage))
            if self.status in target.status:
                resist = random.randint(int((target.intellect + target.resilience)/2), target.intellect + target.resilience)

            else:
                resist = random.randint(0, int((target.intellect + target.resilience)/2))
                if target.alive() and ((damage - resist) > 0) and not self.status == 'none' and self.status not in target.status:
                    target.status.append(self.status)

            print("%s resists %d damage.\n" % (target.name, resist))
            damage -= resist
            if damage <= 0:
                damage = 0
                print("%s is ineffective!\n" % self.name.capitalize())

            target.health(-damage)
            return True

        else:
            return False

class Equipment(Effect):
    def __init__(self, name, power, slot):
        super().__init__(name, power)
        self.slot = slot

    def equip(self, caster):
        if caster.alive() and self.name in caster.inventory.keys():
            if caster.equipment[self.slot]:
                caster.inventory.append(caster.equipment[self.slot])

            caster.equipment[self.slot] = self
            caster.inventory.pop(self.name)
            print("%s equips the %s.\n" % (caster.name, self.name))
            return True

        else:
            return False

    def defend(self):
        return self.power

class Weapon(Equipment):
    def __init__(self, name, power):
        super().__init__(name, power, "weapon")

    def attack(self, caster, target):
        if caster.alive() and target.alive():
            damage = random.randint(int((caster.strength + self.power)/3), caster.strength + self.power)
            print("%s attacks %s with %s.\n" % (caster.name, target.name, self.name))
            if random.randint(0, 7) == 3:
                print("%s misses!\n" % caster.name)
                damage = 0

            else:
                print("%s deals %d damage.\n" % (self.name, damage))
                target_defense = 0
                if target.equipment["shield"]:
                    target_defense += target.equipment["shield"].defend()

                if target.equipment["armor"]:
                    target_defense += target.equipment["armor"].defend()

                resist = random.randint(int((target.resilience + target_defense)/3), target.resilience + target_defense)
                print("%s has a defense rating of %d.\n" % (target.name, target_defense))
                print("%s resists %d damage.\n" % (target.name, resist))
                damage -= resist
                if damage <= 0:
                    damage = 0
                    print("%s blocks the attack!\n" % target.name)

            target.health(-damage)
            return True

        else:
            return False

weapons = {
    "Bamboo Pole": 2, #10
    "Club": 4, #60
    "Copper Sword": 10, #180
    "Hand Axe": 15, #560
    "Broad Sword": 20, #1500
    "Flame Sword": 28, #9800
    "Erdrick's Sword": 40 #0
}

armor = {
    "Clothes": 2, #50
    "Leather Armor": 4, #40
    "Chain Mail": 12, #300
    "Half Plate": 16, #1000
    "Full Plate": 24, #3000
    "Magic Armor": 24, #7700
    "Erdrick's Armor": 28 #0
}

shields = {
    "Leather Shield": 4, #90
    "Iron Shield": 10, #800
    "Silver Shield": 24 #14800
}

spells = {
    "zap": (1, 2, 'none'),
    "fireball": (2, 4, 'burning'),
    "blizzard": (4, 8, 'freezing'),
    "lightning": (8, 12, 'shocked')
}

potions = {
    "red potion": (8, 'hp'),
    "blue potion": (8, 'mp')
}

monsters = {
    "slime": (3, 0, 5, 3, 2, 1, 2, []),
    "she-slime":(4, 0, 7, 3, 4, 2, 4, []),
    "dracky": (6, 0, 9, 6, 5, 3, 6, []),
    "ghost": (7, 0, 11, 8, 6, 4, 8, []),
    "prestidigitator": (12, 8, 8, 12, 6, 8, 16, ["zap"]),
    "drackolyte": (15, 8, 13, 13, 8, 12, 20, ["zap"]),
    "scorpion": (20, 0, 18, 35, 4, 16, 25, []),
    "skeleton": (30, 0, 28, 22, 17, 25, 42, []),
    "lunatick": (22, 0, 22, 18, 11, 14, 21, []),
    "fightgeist": (23, 10, 18, 20, 14, 15, 19,["fireball"]),
    "drohl drone": (35, 0, 24, 6, 9, 18, 30, []),
    "drackyma":(20, 10, 22, 26, 16, 20, 25, ["fireball"]),
    "legerdeman": (28, 10, 26, 24, 15, 28, 50, ["fireball"]),
    "bewarewolf": (34, 0, 40, 30, 21, 40, 60, []),
    "iron scorpion": (22, 0, 36, 60, 25, 31, 48, []),
    "skeleton scrapper": (36, 0, 44, 34, 23, 42, 62, []),
    "scarewolf": (38, 6, 50, 36, 23, 52, 80, ["zap"]),
    "gold golem": (99, 0, 48, 30, 26, 6, 650, []),
    "chimaera": (42, 0, 56, 48, 31, 64, 150, []),
    "spitegeist": (33, 14, 40, 38, 26, 47, 72, ["fireball"]),
    "raving lunatick": (35, 30, 41, 40, 28, 58, 95, ["blizzard"]),
    "drohl diabolist": (38, 10, 44, 16, 11, 58, 110, ["fireball"]),
    "skeleton soldier": (46, 12, 62, 46, 36, 72, 120, ["fireball"]),
    "death scorpion": (35, 0, 55, 90, 33, 70, 110, []),
    "knight errant": (55, 6, 70, 71, 45, 78, 150, ["zap"]),
    "dark skeleton": (43, 0, 79, 51, 40, 90, 148, []),
    "hocus chimaera": (50, 12, 68, 62, 44, 83, 135, ["fireball"]),
    "metal slime": (4, 6, 18, 255, 153, 775, 6, ["zap"]),
    "tearwolf": (60, 0, 80, 65, 45, 95, 155, []),
    "cosmic chimaera": (73, 15, 82, 65, 52, 105, 169, ["zap", "fireball"]),
    "dragon": (67, 18, 88, 72, 47, 135, 160, ["zap", "fireball"]),
    "green dragon": (166, 65, 88, 72, 47, 950, 250, ["zap", "fireball", "blizzard", "lightning"]),
    "vis mager": (70, 16, 71, 60, 49, 120, 185, ["zap", "fireball"]),
    "golem": (155, 0, 120, 60, 39, 2000, 10, []),
    "knight aberrant": (79, 4, 94, 92, 53, 130, 165, ["zap"]),
    "blue dragon": (98, 75, 98, 80, 52, 180, 150, ["zap", "fireball", "blizzard", "lightning"]),
    "stone golem": (160, 0, 100, 40, 40, 155, 148, []),
    "knight abhorrent": (98, 14, 105, 99, 57, 172, 152, ["zap", "fireball"]),
    "red dragon": (105, 85, 115, 104, 62, 350, 143, ["zap", "fireball", "blizzard", "lightning"]),
    "dragon mage": (240, 95, 107, 110, 55, 480, 500, ["zap", "fireball", "blizzard", "lightning"]),
    "dragon lord": (361, 120, 130, 150, 90, 1000, 2500, ["zap", "fireball", "blizzard", "lightning"])
}

if __name__ == "__main__":
    pass

#TODO: Implement escape action
#Create a vendor from the NPC class that takes gold for weapons and armor


from copy import deepcopy
import json
import re
from flask import render_template
from maf_api_mock_data import EGFR_BLCA_BRCA as FAKE_MAF_DATA
from hotspots.seqpeek.tumor_types import tumor_types as ALL_TUMOR_TYPES

from app_logging import get_logger
log = get_logger()

try:
    from hotspots.seqpeek.gene_list import gene_list as GENE_LIST
except ImportError:
    log.error("Loading gene list failed, using static list.")
    GENE_LIST = ['EGFR', 'TP53', 'PTEN']

from hotspots.seqpeek.uniprot_data import get_uniprot_data
from hotspots.seqpeek.interpro_data import get_protein_domain_data
from hotspots.seqpeek.cluster_data import get_cluster_data as get_cluster_data_remote
from hotspots.seqpeek.mutation_data import get_mutation_data as get_mutation_data_remote
from hotspots.seqpeek.mutation_data import get_mutation_data_summary_for_gene

SEQPEEK_VIEW_DEBUG_MODE = False
SEQPEEK_VIEW_MUTATION_DEBUG = False

SAMPLE_ID_FIELD_NAME = 'patient_barcode'
TUMOR_TYPE_FIELD = "tumor"
COORDINATE_FIELD_NAME = 'amino_acid_position'

MUTATION_DATA_PROTEIN_FIELD = 'uniprot_id'

PROTEIN_DOMAIN_DB = 'PFAM'

ALPHA_FINDER = re.compile('[\W_]+', re.UNICODE)

TEMPLATE_NAME = 'hotspots/seqpeek/view.html'

def get_number_of_unique_samples(track):
    sample_ids = set()
    for mutation in track['mutations']:
        sample_ids.add(mutation[SAMPLE_ID_FIELD_NAME])

    return len(sample_ids)

# TODO remove if not needed
def clean_track_mutations(mutations_array):
    retval = []
    for mutation in mutations_array:
        cleaned = deepcopy(mutation)
        cleaned[COORDINATE_FIELD_NAME] = int(mutation[COORDINATE_FIELD_NAME])
        retval.append(cleaned)

    return retval

def sort_track_mutations(mutations_array):
    return sorted(mutations_array, key=lambda k: k[COORDINATE_FIELD_NAME])

def get_track_statistics(track):
    return {
        'samples': {
            'numberOf': get_number_of_unique_samples(track)
        }
    }

def filter_protein_domains(match_array):
    return [m for m in match_array if m['dbname'] == PROTEIN_DOMAIN_DB]

def get_table_row_id(tumor_type):
    return "seqpeek_row_{0}".format(tumor_type)

def build_seqpeek_regions(protein_data):
    return [{
        'type': 'exon',
        'start': 0,
        'end': protein_data['length']
    }]

def build_summary_track(tracks, render_summary_only=False):
    all = []
    for track in tracks:
        all.extend(track["mutations"])

    return {
        'mutations': all,
        'label': 'COMBINED',
        'tumor': 'none-combined',
        'type': 'summary',
        'do_variant_layout': True if render_summary_only is True else False
    }

def get_track_label(track):
    return track[TUMOR_TYPE_FIELD]

def process_raw_domain_data(data):
    result = []
    for item in data:
        database = item['database']

        # Filter for PFAM
        if not database.startswith('PF'):
            continue

        domain = {
            'name': item['name'][:5] + '...',
            'full_name': item['name'],
            'locations': [{
                'start': item['start'],
                'end': item['end']
            }],
            'dbname': 'PFAM',
            'ipr': {
                'type': 'Domain',
                'id': item['interpro_id'],
                'name': item['name'][:2]
            },
            'id': database
        }

        result.append(domain)

    log.debug("Found {total} domains, filtered down to {num}".format(total=len(data), num=len(result)))
    return result

def get_protein_domains_remote(uniprot_id):
    uniprot_data = get_uniprot_data(uniprot_id)
    log.debug("UniProt entry: " + str(uniprot_data))

    # Add protein domain data to the UniProt entry
    raw_domain_data = get_protein_domain_data(uniprot_id)
    domains = process_raw_domain_data(raw_domain_data)
    uniprot_data['matches'] = domains
    return uniprot_data

def get_protein_domains(uniprot_id):
    return get_protein_domains_remote(uniprot_id)

def get_maf_data_remote(gene, tumor_type_list):
    return get_mutation_data_remote(tumor_type_list, gene)

def get_mutation_data(gene, tumor_type_list):
    if SEQPEEK_VIEW_MUTATION_DEBUG:
        return deepcopy(FAKE_MAF_DATA['items'])
    else:
        return get_mutation_data_remote(tumor_type_list, gene)

def process_cluster_data_for_tumor(all_clusters, tumor_type):
    clusters = filter(lambda c: c['tumor_type'] == tumor_type, all_clusters)
    result = []
    for index, cluster in enumerate(clusters):
        item = {
            'name': '',
            'type': 'cluster',
            'id': 'cluster_' + str(index),
            'locations': [{
                'start': cluster['start'],
                'end': cluster['end']
            }],
            'mutation_stats': cluster['mutation_stats'],
            'stats': cluster['stats']
        }
        result.append(item)
    return result

def build_track_data(tumor_type_list, all_tumor_mutations, all_clusters):
    tracks = []
    for tumor_type in tumor_type_list:
        mutations = filter(lambda m: m['tumor_type'] == tumor_type, all_tumor_mutations);

        track_obj = {
            TUMOR_TYPE_FIELD: tumor_type,
            'mutations': mutations,
            'clusters': process_cluster_data_for_tumor(all_clusters, tumor_type),
            'do_variant_layout': True
        }

        if len(mutations) > 0:
            track_obj['render_in_seqpeek'] = True
        else:
            track_obj['render_in_seqpeek'] = False

        tracks.append(track_obj)

    return tracks

def find_uniprot_id(mutations):
    uniprot_id = None
    for m in mutations:
        if MUTATION_DATA_PROTEIN_FIELD in m:
            uniprot_id = m[MUTATION_DATA_PROTEIN_FIELD]
            break

    return uniprot_id

def get_cluster_data(tumor_type_array, gene):
    clusters = get_cluster_data_remote(tumor_type_array, gene)
    return clusters

def sanitize_gene_input(gene_parameter):
    return ALPHA_FINDER.sub('', gene_parameter)

def sanitize_normalize_tumor_type(tumor_type_list):
    tumor_set = frozenset(ALL_TUMOR_TYPES)
    sanitized = []
    for tumor_param in tumor_type_list:
        if tumor_param in tumor_set:
            sanitized.append(tumor_param)

    return sanitized

def format_tumor_type_list(tumor_type_array, selected_types=[]):
    result = []
    for tumor_type in tumor_type_array:
        result.append({
            'name': tumor_type,
            'selected': tumor_type in selected_types
        })

    return result

def seqpeek(request_gene, request_tumor_list, summary_only=False):
    gene = None
    if request_gene is not None:
        # Remove non-alphanumeric characters from parameters and uppercase all
        gene = sanitize_gene_input(request_gene).upper()

    parsed_tumor_list = sanitize_normalize_tumor_type(request_tumor_list)
    log.debug("Valid tumors from request: {0}".format(str(parsed_tumor_list)))

    tumor_types_for_tpl = format_tumor_type_list(ALL_TUMOR_TYPES, parsed_tumor_list)

    context = {
        'gene_select_widget': {
            'action': '/seqpeek',
            'tumor_type_select': True,
            'all_tumor_types': tumor_types_for_tpl,
            'button_label': 'Redraw'
        },
        'query_status': {
            'no_mutations_found': False,
            'uniprot_id_not_found': False,
            'data_found': False,
            'summary_only': False,
            'insufficient_parameters': False,
            'request_gene': request_gene
        },
        'gene_label': gene,
        'is_gene_summary': summary_only,
        'static_data': {
            'gene_list': GENE_LIST,
            'gene_label': gene,
            'fill_in_gene': True
        },
        'all_tumor_types': tumor_types_for_tpl
    }

    if (len(parsed_tumor_list) == 0 and summary_only is False) or gene is None:
        context['query_status']['insufficient_parameters'] = True
        context['static_data']['fill_in_gene'] = False
        context.update({
            'static_data': json.dumps(context['static_data'])
        })
        return render_template(TEMPLATE_NAME, **context)

    if summary_only is False:
        cluster_data = get_cluster_data(parsed_tumor_list, gene)
        maf_data = get_mutation_data(gene, parsed_tumor_list)
    else:
        maf_data = get_mutation_data_summary_for_gene(gene)

    if len(maf_data) == 0:
        context['query_status']['no_mutations_found'] = True
        context['static_data']['fill_in_gene'] = False
        context.update({
            'static_data': json.dumps(context['static_data'])
        })
        return render_template(TEMPLATE_NAME, **context)

    uniprot_id = find_uniprot_id(maf_data)

    if uniprot_id is None:
        context['query_status']['uniprot_id_not_found'] = True
        context['static_data']['fill_in_gene'] = False
        context.update({
            'static_data': json.dumps(context['static_data'])
        })
        return render_template(TEMPLATE_NAME, **context)

    log.debug("Found UniProt ID: " + repr(uniprot_id))

    context['query_status']['data_found'] = True

    protein_data = get_protein_domains(uniprot_id)

    plot_data = {
        'gene_label': gene,
        'protein': protein_data
    }

    if summary_only is False:
        track_data = build_track_data(parsed_tumor_list, maf_data, cluster_data)
        plot_data['tracks'] = track_data

        # Pre-processing
        # - Sort mutations by chromosomal coordinate
        for track in plot_data['tracks']:
            track['mutations'] = sort_track_mutations(track['mutations'])

        # Annotations
        # - Add label, possibly human readable
        # - Add type that indicates whether the track is driven by data from search or
        #   if the track is aggregate
        for track in plot_data['tracks']:
            track['type'] = 'tumor'
            track['label'] = get_track_label(track)

        plot_data['tracks'].append(build_summary_track(plot_data['tracks'], render_summary_only=False))

    else:
        summary_track = {
            'mutations': sort_track_mutations(maf_data)
        }
        plot_data['tracks'] = [build_summary_track([summary_track], render_summary_only=True)]

    for track in plot_data['tracks']:
        # Calculate statistics
        track['statistics'] = get_track_statistics(track)
        # Unique ID for each row
        track['render_info'] = {
            'row_id': get_table_row_id(track[TUMOR_TYPE_FIELD])
        }

    plot_data['regions'] = build_seqpeek_regions(plot_data['protein'])
    plot_data['protein']['matches'] = filter_protein_domains(plot_data['protein']['matches'])

    # Filter the tracks-array for Seqpeek. Only leave tracks with at least one mutation.
    seqpeek_data = {key: plot_data[key] for key in ['gene_label', 'protein', 'regions']}
    seqpeek_tracks = []
    for track in plot_data['tracks']:
        if len(track['mutations']) > 0:
            # Gene has to be passed to the track object, so that it can be used
            # to construct the URI for the pathway association view
            track['gene'] = gene
            seqpeek_tracks.append(track)
        else:
            log.debug("{0}: 0 mutations, not rendering in SeqPeek.".format(track['label']))

    seqpeek_data['tracks'] = seqpeek_tracks

    tumor_list = ','.join(parsed_tumor_list)

    context.update({
        'search': {},
        'plot_data': plot_data,
        'data_bundle': json.dumps(seqpeek_data),
        'gene': gene,
        'tumor_list': tumor_list
    })
    context.update({
        'static_data': json.dumps(context['static_data'])
    })

    return render_template(TEMPLATE_NAME, **context)


from unittest import result

from pip._vendor.distlib.compat import raw_input

def start():
    n1 = input("n1: ")
    control_input(n1)

def control_input(x):
        try:
            val = int(x)
            print("Input is an integer number. Number = ", val)
            result = "int_number"
        except ValueError:
            try:
                val = float(x)
                print("Input is a float  number. Number = ", val)
                result = "float_number"
            except ValueError:
                print(x + "is a string")
                result = "string"

        return result

if __name__ == '__main__':
    start()