from flask import wrappers
from flask.globals import session
import numpy as np
import time
import math
import random
import os
from PyDictionary import PyDictionary

# class testWrapper():
#     def __init__(self):
#         self.tests = {}
#         self.allWords = self.importWords()

#     def importWords(self):
#         a1 = np.genfromtxt(os.getcwd()+"/words/a1.txt", dtype=str,
#                          encoding='UTF-8', delimiter="\n")
#         a2 = np.genfromtxt(os.getcwd()+"/words/a2.txt", dtype=str,
#                          encoding='UTF-8', delimiter="\n")
#         b1 = np.genfromtxt(os.getcwd()+"/words/b1.txt", dtype=str,
#                          encoding='UTF-8', delimiter="\n")
#         b2 = np.genfromtxt(os.getcwd()+"/words/b2.txt", dtype=str,
#                          encoding='UTF-8', delimiter="\n")
#         c1 = np.genfromtxt(os.getcwd()+"/words/c1.txt", dtype=str,
#                          encoding='UTF-8', delimiter="\n")
#         c2 = np.genfromtxt(os.getcwd()+"/words/c2.txt", dtype=str,
#                          encoding='UTF-8', delimiter="\n")
#         allWords = (a1, a2, b1, b2, c1, c2)
#         return allWords

#     def createTest(self, session):
#         self.tests[session] = Test(self.allWords)

def testTest():
    mytest = Test()
    # for _ in range(2):
    #     print(mytest.getWord())
    #     mytest.setAnswer(int(input()))

    dic = {
        "cucumber": 1,
        "incise": 0,
        "hook": 1,
        "theoretical": 1,
        "quince": 0,
        "refract": 0,
        "merchantman": 1,
        "stance": 1,
        "coot": 0,
        "practitioner": 1,
    }

    mytest.setAnswers(dic)
    print(mytest.currentCatv)
    print("")
    print(mytest.levels)
    print("")
    print(mytest.itemsAndResponses)
    print("")
    print(mytest.usedWords)

class Test:
    # def __init__(self, allWords, initialLevel=3):
    def __init__(self, initialLevel=3):
        self.allWords = self.importWords()
        self.levels = np.empty(1)
        self.levels[0] = initialLevel
        self.itemsAndResponses = np.empty([0, 2])
        self.currentCall = 0
        self.possibleLevels = np.array([1, 2, 3, 4, 5, 6])
        self.currentCatv = np.empty([1, 6])
        self.usedWords = []

    def importWords(self):
        a1 = np.genfromtxt(os.getcwd()+"/words/a1.txt", dtype=str,
                         encoding='UTF-8', delimiter="\n")
        a2 = np.genfromtxt(os.getcwd()+"/words/a2.txt", dtype=str,
                         encoding='UTF-8', delimiter="\n")
        b1 = np.genfromtxt(os.getcwd()+"/words/b1.txt", dtype=str,
                         encoding='UTF-8', delimiter="\n")
        b2 = np.genfromtxt(os.getcwd()+"/words/b2.txt", dtype=str,
                         encoding='UTF-8', delimiter="\n")
        c1 = np.genfromtxt(os.getcwd()+"/words/c1.txt", dtype=str,
                         encoding='UTF-8', delimiter="\n")
        c2 = np.genfromtxt(os.getcwd()+"/words/c2.txt", dtype=str,
                         encoding='UTF-8', delimiter="\n")
        allWords = (a1, a2, b1, b2, c1, c2)
        return allWords

    def getWord(self):
        wordNumber = random.randrange(0, len(self.allWords[int(self.levels[self.currentCall]-1)]))
        outputWord = self.allWords[int(self.levels[self.currentCall]-1)][wordNumber]
        while outputWord in self.usedWords: #no repeats
            wordNumber = random.randrange(0, len(self.allWords[int(self.levels[self.currentCall]-1)]))
            outputWord = self.allWords[int(self.levels[self.currentCall]-1)][wordNumber]
        self.usedWords.append(outputWord)
        return outputWord

    def setAnswer(self, ans):
        item = self.levels[self.currentCall]
        self.itemsAndResponses = np.append(self.itemsAndResponses, [[item, ans]], axis=0)
        self.currentCatv = self.catvalues(self.itemsAndResponses, self.possibleLevels)
        currentLevel = np.argmax(self.currentCatv)+1
        self.levels = np.append(self.levels, currentLevel)
        self.currentCall += 1

    # accepts list of dictionaries of answers
    # [{"word1": 1}, {"word2": 1} {"word3": 0} ...]
    def setAnswers(self, answers):
        for dict in answers:
            [(word, ans)] = dict.items()
            item = self.levels[self.currentCall]
            self.itemsAndResponses = np.append(self.itemsAndResponses, [[item, ans]], axis=0)
            self.currentCatv = self.catvalues(self.itemsAndResponses, self.possibleLevels)
            currentLevel = np.argmax(self.currentCatv)+1
            self.levels = np.append(self.levels, currentLevel)
            self.currentCall += 1
            self.usedWords.append(word)

    # def runTest(self, iterationsNumber = 20, initialLevel = 3):
    #     currentLevel = np.empty(iterationsNumber+1, dtype=int)
    #     currentLevel[0] = initialLevel
    #     temp = -1
    #     itemsAndResponses = np.empty([0, 2])
    #     for i in range(iterationsNumber):
    #         print("Do you know this word? (1/0)")
    #         wordNumber = random.randrange(0, len(self.allWords[currentLevel[i]-1]))
    #         while temp == wordNumber: ##to avoid repeating words
    #             wordNumber = random.randrange(0, len(self.allWords[currentLevel[i]-1]))
    #         print(self.allWords[currentLevel[i]-1][wordNumber])
    #         item = currentLevel[i]
    #         response = int(input())
    #         itemsAndResponses = np.append(itemsAndResponses, [[item, response]], axis=0)
    #         levels = np.array([1, 2, 3, 4, 5, 6])
    #         catv = self.catvalues(itemsAndResponses, levels)
    #         currentLevel[i+1] = np.argmax(catv)+1
    #         temp = wordNumber
    #     return currentLevel, catv, itemsAndResponses

    def rasch(self, cefr, level):
        return 1/(1+math.exp(cefr-level))

    def cat(self, items, lev):
        probarray = np.empty(len(items))
        for i in range(len(items)):
            prob = ((self.rasch(items[i, 0], lev)**items[i, 1]))*((1-self.rasch(items[i, 0], lev))**(1-items[i, 1]))
            if i > 0:
                prob = prob*probarray[i-1]
            probarray[i] = prob
        return math.log10(probarray[i])

    def catvalues(self, items, levs):
        values = np.empty(len(levs))
        for i in range(len(levs)):
            values[i] = self.cat(items, i+1)
        return values

    def clear(self):
        self.levels = np.empty(1)
        self.levels[0] = 3
        self.itemsAndResponses = np.empty([0, 2])
        self.currentCall = 0
        self.possibleLevels = np.array([1, 2, 3, 4, 5, 6])
        self.currentCatv = np.empty([1, 6])

if __name__ == '__main__':
   testTest()


"""
This library does all the complex network analysis required by the program
"""
# from typing import List, Any, Tuple, Dict, Union
import inspect
import csv
import networkx as nx
import matplotlib
import matplotlib.pyplot as plt
import matplotlib.colors as colors
import matplotlib.cm as cmx
import json
import random
from pycanvass.all import *
import pycanvass.global_variables as gv
import sys
import pycanvass.utilities as util
import time
import datetime
import os
from pathlib import Path

from networkx import Graph

attempts = 0
settings = ""

def _input_user_pref_file():
    util._banner()
    current_folder_path, current_folder_name = os.path.split(os.getcwd())
    wd = current_folder_path + "\\" + current_folder_name + "\\"
    print("[i] Current working folder: {}".format(wd))
    default_json_file_name = current_folder_path + "\\" + current_folder_name + "\\user_preferences.json"
    default_json_file_name = Path(default_json_file_name)

    if default_json_file_name.exists():
        print("[i] Loaded default user preferences file: {}".format(default_json_file_name))
        # time.sleep(0.5)
        user_preference_path = default_json_file_name
    else:
        print("[x] Default user preferences file not found.")
        user_preference_path = input("\n[i] Please enter the path to your user-preferences file (*.JSON):\n")

    return str(user_preference_path)

while attempts < 4:
    if attempts == 3:
        break
    try:
        user_preference_path = _input_user_pref_file()
        gv.filepaths["user_preferences"] = user_preference_path
        u_settings = open(user_preference_path)
        settings = json.load(u_settings)
        u_settings.close()
        break
    except:
        print("[x] Could not get the user preference file.")
        attempts += 1
        if attempts == 3:
            print("[x] Failed to configure user preferences correctly.")
            sys.exit()
        elif attempts == 2:
            print("[i] One more chance to get the user preference correctly setup.")

# ---------------------------

# # #
# A #
# # #

def add_node_attr(graph):
    """
    Add all the details about the nodes here
    :param graph:
    :return: dictionary containing node features
    """
    all_nodes = graph.nodes()
    n_file = gv.filepaths["nodes"]

    for n in all_nodes:
        node_search_result = _node_search(n)
        try:
            with open(n_file, 'r') as f:
                csvr = csv.reader(f)
                csvr = list(csvr)
                for row in csvr:
                    if row[0].lstrip() == n:
                        if node_search_result is not 0:
                            graph.node[n]['type'] = row[9].lstrip()
                            graph.node[n]['gen'] = row[6].lstrip()
                            graph.node[n]['demand'] = row[5].lstrip()
                            graph.node[n]['lat'] = row[2].lstrip()
                            graph.node[n]['long'] = row[3].lstrip()

        except:
            print("[x] Error in setting up the node attributes. ")
            called_from = inspect.stack()[1]
            called_module = inspect.getmodule(called_from[0])
            logging.error("[x] Called from - {} : Node attributes could not be set.".format(called_module, e))

# # #
# N #
# # #

def _node_search(n):
    n_file = gv.filepaths["nodes"]
    with open(n_file) as f:
        counter = 0
        match_flag = 0
        nodes = csv.reader(f)
        for node in nodes:
            counter += 1
            if node[0].lstrip() == n:
                match_flag = 1
                return counter - 1

        if match_flag == 0:
            called_from = inspect.stack()[1]
            called_module = inspect.getmodule(called_from[0])
            logging.error("[x] Called from - {} : Node {} could not be found.".format(called_module, e))
            return 0

# # #
# B #
# # #

def build_network(node_dict, edge_dict):
    """

    :param node_dict:
    :param edge_dict:
    :return: network_dict: Dictionary containing several network graph objects, and edge details
             network_dict["normal"] : Normal network topology
             network_dict["total"] : Graph containing self-loops, including reconfiguration options
             network_dict["n_open"]: List of all edges which are normally open
             network_dict["n_closed"] : List of all edges which are normally closed
    """

    network_dict = {}

    graph = nx.Graph()
    total_graph = nx.DiGraph()

    gv.obj_nodes = []
    gv.obj_edges = []

    for key, value in node_dict.items():
        gv.obj_nodes.append(value)

    for key, value in edge_dict.items():
        gv.obj_edges.append(value)

    for edge in gv.obj_edges:
        total_graph.add_edge(edge.from_node.lstrip(), edge.to_node.lstrip())
        if edge.availability.lstrip() != "0":
            graph.add_edge(edge.from_node.lstrip(), edge.to_node.lstrip())
            gv.closed_edges_list.append(tuple((edge.from_node.lstrip(), edge.to_node.lstrip())))
        else:
            gv.open_edges_list.append(tuple((edge.from_node.lstrip(), edge.to_node.lstrip())))

    logging.info("Populating nodes and edges with values")
    # print(graph.nodes())
    for n in gv.obj_nodes:
        graph.node[n.name]['name'] = n.name
        graph.node[n.name]['load'] = n.load
        graph.node[n.name]['gen'] = n.gen
        graph.node[n.name]['lat'] = n.lat
        graph.node[n.name]['long'] = n.long
        graph.node[n.name]['kind'] = n.kind
        graph.node[n.name]['critical'] = n.critical

        total_graph.node[n.name]['name'] = n.name
        total_graph.node[n.name]['load'] = n.load
        total_graph.node[n.name]['gen'] = n.gen
        total_graph.node[n.name]['lat'] = n.lat
        total_graph.node[n.name]['long'] = n.long
        total_graph.node[n.name]['kind'] = n.kind
        total_graph.node[n.name]['critical'] = n.critical

        try:
            if n.kind.upper() == "PV" or n.kind.upper() == "SWING":
                gv.all_sources[n.name] = n.gen
            else:
                try:
                    gv.all_loads[n.name] = n.load
                    if int(n.critical) > 5:
                        gv.all_critical_loads[n.name] = n.load
                except ValueError:
                    logging.error("No loads found in the network while making the graph.")
        except ValueError:
            logging.error("No power resource found in the network while making the graph.")

    gv.graph_collection.append(graph)
    gv.graph_collection.append(total_graph)

    for g in gv.graph_collection:
        for e in gv.obj_edges:
            try:
                g[e.from_node.lstrip()][e.to_node.lstrip()]['water_risk'] = e.water_risk
                gv.water_risk_values.append(e.water_risk.lstrip())
            except KeyError:
                logging.info("No edge between %s and %s, so no water risk" % (e.from_node.lstrip(), e.to_node.lstrip()))
                gv.water_risk_values.append(0)

            try:
                g[e.from_node.lstrip()][e.to_node.lstrip()]['wind_risk'] = e.wind_risk
                gv.wind_risk_values.append(e.wind_risk.lstrip())
            except KeyError:
                logging.info(
                    "[i] No edge between %s and %s, so no wind risk " % (e.from_node.lstrip(), e.to_node.lstrip()))
                gv.wind_risk_values.append(0)

            try:
                g[e.from_node.lstrip()][e.to_node.lstrip()]['fire_risk'] = e.fire_risk
                gv.fire_risk_values.append(e.fire_risk.lstrip())
            except KeyError:
                logging.info(
                    "[i] No edge between %s and %s, so no fire risk " % (e.from_node.lstrip(), e.to_node.lstrip()))
                gv.fire_risk_values.append(0)

    network_dict["normal"] = graph
    network_dict["total"] = total_graph
    network_dict["n_open"] = gv.open_edges_list
    network_dict["n_closed"] = gv.closed_edges_list

    return network_dict

def build_network_2(node_dict, edge_dict, timestring):
    """

    :param node_dict:
    :param edge_dict:
    :return: network_dict: Dictionary containing several network graph objects, and edge details
             network_dict["normal"] : Normal network topology
             network_dict["total"] : Graph containing self-loops, including reconfiguration options
             network_dict["n_open"]: List of all edges which are normally open
             network_dict["n_closed"] : List of all edges which are normally closed
    """

    network_dict = {}

    graph = nx.Graph()
    total_graph = nx.DiGraph()

    gv.obj_nodes = []
    gv.obj_edges = []

    for key, value in node_dict.items():
        gv.obj_nodes.append(value)

    for key, value in edge_dict.items():
        gv.obj_edges.append(value)

    for edge in gv.obj_edges:
        total_graph.add_edge(edge.from_node.lstrip(), edge.to_node.lstrip())
        if edge.status.lstrip() != "0" and edge.availability.lstrip() != "0":
            graph.add_edge(edge.from_node.lstrip(), edge.to_node.lstrip())
            gv.closed_edges_list.append(tuple((edge.from_node.lstrip(), edge.to_node.lstrip())))
        else:
            gv.open_edges_list.append(tuple((edge.from_node.lstrip(), edge.to_node.lstrip())))

    logging.info("Building graph for time-stamp {}".format(timestring))
    # print(graph.nodes())

    for n in gv.obj_nodes:
        try:
            graph.node[n.name]['name'] = n.name
        except KeyError:
            print("[!] Encountered a disconnected load {}".format(n.name))
            continue
        graph.node[n.name]['load'] = n.load
        graph.node[n.name]['gen'] = n.gen
        graph.node[n.name]['lat'] = n.lat
        graph.node[n.name]['long'] = n.long
        graph.node[n.name]['kind'] = n.kind
        graph.node[n.name]['critical'] = n.critical

        total_graph.node[n.name]['name'] = n.name
        total_graph.node[n.name]['load'] = n.load
        total_graph.node[n.name]['gen'] = n.gen
        total_graph.node[n.name]['lat'] = n.lat
        total_graph.node[n.name]['long'] = n.long
        total_graph.node[n.name]['kind'] = n.kind
        total_graph.node[n.name]['critical'] = n.critical

        try:
            if n.kind.upper() == "PV" or n.kind.upper() == "SWING":
                gv.all_sources[n.name] = n.gen
            else:
                try:
                    gv.all_loads[n.name] = n.load
                    if int(n.critical) > 5:
                        gv.all_critical_loads[n.name] = n.load
                except ValueError:
                    logging.error("No loads found in the network while making the graph.")
        except ValueError:
            logging.error("No power resource found in the network while making the graph.")

    gv.graph_collection.append(graph)
    gv.graph_collection.append(total_graph)

    for g in gv.graph_collection:
        for e in gv.obj_edges:
            try:
                g[e.from_node.lstrip()][e.to_node.lstrip()]['water_risk'] = e.water_risk
                gv.water_risk_values.append(e.water_risk.lstrip())
            except KeyError:
                logging.info("No edge between %s and %s, so no water risk" % (e.from_node.lstrip(), e.to_node.lstrip()))
                gv.water_risk_values.append(0)

            try:
                g[e.from_node.lstrip()][e.to_node.lstrip()]['wind_risk'] = e.wind_risk
                gv.wind_risk_values.append(e.wind_risk.lstrip())
            except KeyError:
                logging.info(
                    "[i] No edge between %s and %s, so no wind risk " % (e.from_node.lstrip(), e.to_node.lstrip()))
                gv.wind_risk_values.append(0)

            try:
                g[e.from_node.lstrip()][e.to_node.lstrip()]['fire_risk'] = e.fire_risk
                gv.fire_risk_values.append(e.fire_risk.lstrip())
            except KeyError:
                logging.info(
                    "[i] No edge between %s and %s, so no fire risk " % (e.from_node.lstrip(), e.to_node.lstrip()))
                gv.fire_risk_values.append(0)

    network_dict["normal"] = graph
    network_dict["total"] = total_graph
    network_dict["n_open"] = gv.open_edges_list
    network_dict["n_closed"] = gv.closed_edges_list

    return network_dict

# # #
# C #
# # #

def _create_pos_dictionary(graph):
    """
    Internal function, that creates a dictionary that contains position of all nodes in the network
    :param graph:
    :return: dictionary of all nodes with their geo-coordinates,
             dictionary with little shifted position for showing labels
    """
    nodes = graph.nodes()  # list of all nodes <-- keys
    pos_dictionary = {}  # initializing a dictionary to hold the positions
    label_pos_dictionary = {}
    for n in nodes:
        pos_dictionary[n] = tuple((float(graph.node[n]['long']), float(graph.node[n]['lat'])))
        label_pos_dictionary[n] = tuple((float(graph.node[n]['lat']), float(graph.node[n]['long'])))

    return pos_dictionary, label_pos_dictionary

# # #
# F #
# # #

def feeder_path(graph, from_node, to_node):
    """
    :param graph: NetworkX graph object
    :param from_node:
    :param to_node:
    :return: all restoration paths from generator to load nodes
    """
    path_graph = nx.Graph()
    paths = nx.all_simple_paths(graph, from_node, to_node)

    return paths

# # #
# L #
# # #

def lat_long_layout(graph, show=False, save=True, title="Visualization"):
    """
    Help visualize the network graph and some of its resilience properties.
    If your graph does not come with
    :param graph:
    :param show: (Default is False)
    :param save: (Default is True)
    :return:
    """
    focus = "impact_on_edge"
    logging.info(
        "Lat_long_layout function used, focus = {}, trying to display = {}, saving = {}".format(focus, show, save))

    try:
        pos, label_pos = _create_pos_dictionary(graph)
    except ValueError:
        print("[x] Error: Could not create determine where to put the nodes and edges. "
              "... Please check the lat, longs of your nodes. "
              ""
              "... In case your file does not have the lat, longs, generate"
              "... random lat-longs by using the layout_model(<model.glm>, map_random=True) function."
              ""
              "... Please read the documentation on how to do that. ")

        logging.error('Could not create the dictionary for pos, or label_pos')

    color_scheme = settings['visualization']['color_scheme']

    values = []

    for e in graph.edges():
        try:
            values.append(graph[str(e[0])][str(e[1])][focus])
        except:
            values.append(1)

    color_scheme = plt.get_cmap(color_scheme)
    c_norm = colors.Normalize(vmin=0, vmax=7)
    scalar_map = cmx.ScalarMappable(norm=c_norm, cmap=color_scheme)
    color_list = []
    edge_labels = nx.get_edge_attributes(graph, focus)

    for i in range(len(values)):
        color_val = scalar_map.to_rgba(float(values[i]))
        color_list.append(color_val)

    # add a connection to a web visualization

    nx.draw_networkx_edges(graph,
                           pos=pos,
                           edge_color=color_list,
                           # style='dashed',
                           width=2.0)

    nx.draw_networkx_nodes(graph,
                           pos=pos,
                           nodelist=graph.nodes(),
                           node_color='b',
                           node_shape='x')

    nx.draw_networkx_labels(graph,
                            pos=pos,
                            edge_labels=edge_labels)

    if show:
        plt.title(title)
        plt.show()

    if save:
        ts = time.time()
        st = datetime.datetime.fromtimestamp(ts).strftime('%Y_%m_%d_%H_%M_%S')
        filename = "visualization_" + st + ".png"
        plt.savefig(filename)

def loads(critical=False):
    """
    This function lists the loads in the power system network.
    :param critical: Default value is set to False, which means all loads will be displayed in the network.
                     Set this value to True to see only the critical loads
    :return: gv.all_loads or gv.all_critical_loads
    """
    if not critical:
        return gv.all_loads
    else:
        return gv.all_critical_loads

# # #
# M #
# # #

def make_graph(all_edges):
    """

    :param all_edges: List of all instances of Edge objects created by the program
    :return: graph: NetworkX graph object,
             normally_open_edges: number of open edges, that can be closed later if necessary
    """
    graph = nx.Graph()
    total_graph = nx.Graph()

    for edge in all_edges:
        total_graph.add_edge(edge.from_node, edge.to_node)
        if edge.status != "0":
            graph.add_edge(edge.from_node, edge.to_node)
            gv.closed_edges_list.append(tuple((edge.from_node, edge.to_node)))
        else:
            gv.open_edges_list.append(tuple((edge.from_node, edge.to_node)))

    return graph, total_graph, gv.open_edges_list, gv.closed_edges_list

def make_path_graph(nodelist, **kwargs):
    """
    Create a graph based on a found path between a source and a generator
    :param nodelist:
    :return: path_graph: A NetworkX object that is a single path's graph, that can be further used for resiliency
                         analysis

    """

    path_graph = nx.Graph()
    i = 0
    while i < len(nodelist) - 1:
        path_graph.add_edge(nodelist[i], nodelist[i + 1])
        i += 1

    return path_graph

# # #
# P #
# # #

def preprocess(graph, node_dict, edge_dict):
    """

    :param graph:
    :param node_dict:
    :param edge_dict:
    :return:
    """

    gv.obj_nodes = []
    gv.obj_edges = []
    for key, value in node_dict.items():
        gv.obj_nodes.append(value)

    for key, value in edge_dict.items():
        gv.obj_edges.append(value)

    print("[i] Attempting to populate nodes and edges with values")

    for n in gv.obj_nodes:
        graph.node[n.name]['name'] = n.name
        graph.node[n.name]['load'] = n.load
        graph.node[n.name]['gen'] = n.gen
        graph.node[n.name]['lat'] = n.lat
        graph.node[n.name]['long'] = n.long
        graph.node[n.name]['kind'] = n.kind
        graph.node[n.name]['critical'] = n.critical

        try:
            if n.kind.upper() == "PV" or n.kind.upper() == "SWING":
                gv.all_sources[n.name] = n.gen
            else:
                try:
                    gv.all_loads[n.name] = n.load
                    if int(n.critical) > 5:
                        gv.all_critical_loads[n.name] = n.load
                except ValueError:
                    logging.error("No loads found in the network, while making the graph.")
        except ValueError:
            logging.error("No power resource found in the network, while making the graph.")

    for e in gv.obj_edges:
        try:
            graph[e.from_node][e.to_node]['water_risk'] = e.water_risk
            gv.water_risk_values.append(e.water_risk)
        except KeyError:
            print("[i] No edge between %s and %s exist in this topology." % (e.from_node, e.to_node))
            gv.water_risk_values.append(0)

        try:
            graph[e.from_node][e.to_node]['wind_risk'] = e.wind_risk
            gv.water_risk_values.append(e.wind_risk)
        except KeyError:
            print("[i] No edge between %s and %s exist in this topology." % (e.from_node, e.to_node))
            gv.water_risk_values.append(0)

        try:
            graph[e.from_node][e.to_node]['fire_risk'] = e.fire_risk
            gv.water_risk_values.append(e.fire_risk)
        except KeyError:
            print("[i] No edge between %s and %s exist in this topology." % (e.from_node, e.to_node))
            gv.water_risk_values.append(0)

# # #
# R #
# # #

def resiliency_downstream(graph, edgelist, event):
    """
    This function computes the resiliency of all downstream sections,
    mainly looking out for critical loads
    :param graph:
    :param edgelist: All downstream sections of the feeder, from perspective of an edge being analyzed
    :param event: dictionary describing the event magnitude
    :return:
    """

    risk_dict = {}

    for e in edgelist:
        for oe in gv.obj_edges:
            if e[0].lstrip() == oe.from_node.lstrip() and e[1].lstrip() == oe.to_node.lstrip():
                risk_dict[tuple((e[0], e[1]))] = (event["water_risk"] * float(oe.water_risk.lstrip())
                                                  + event["wind_risk"] * float(oe.wind_risk.lstrip())
                                                  + event["fire_risk"] * float(oe.fire_risk.lstrip())) / 30

    print("Risk per edge -->")
    print(risk_dict)

    # loads encountered

    # critical loads encountered

    # generators encountered

    # switches encountered

    pass

def resiliency_upstream(graph, edgelist, event):
    """
    This function computes the resiliency of all upstream sections,
    mainly looking out for generators
    :param edgelist: All upstream sections of the feeder, from persective of a feeder being analyzed
    :return:
    """
    print("Heat your ", edgelist)
    pass

def resiliency(analysis='nodal'):
    """
    This function helps compute the resiliency metric of the network of a
    node, or a network
    :param kwargs:
    :return:
    """

    # 0. what's the event?

    event = gv.event

    # 1. get the graphs

    g1 = gv.graph_collection[0]
    g2 = gv.graph_collection[1]
    nodes = g2.nodes()
    edges = g2.edges()

    # 2. for which node and edge are you doing the analysis?
    wg = nx.DiGraph()  # wg: working graph
    wg.add_edges_from(edges)

    for n in nodes:
        # Finding Downstream Edges
        print("Downstream Edges of %s -->" % n)
        downstream_edges = list(nx.dfs_edges(wg, n))
        resiliency_downstream(g2, downstream_edges, event)

        # Finding Upstream Edges
        print("Upstream Edges of %s -->" % n)
        upstream_edges = list(nx.edge_dfs(wg, n, orientation='reverse'))
        resiliency_upstream(g2, upstream_edges, event)

    # 3. track back from that edge to a source, or multiple sources

# # #
# S #
# # #

def sources():
    """
    This is a querying function that lists the power resources in a network
    :return: list of all power sources within a network
    """
    return gv.all_sources

def simple_show(graph):
    """
    Display the simple network representation of the graph
    :param graph: NetworkX graph object
    :return:
    """
    nx.draw(graph)
    plt.show()

def summary(graph):
    """
    Summarize all the important graph topological properties
    :param graph:
    :return:
    """
    temp_dict = {'degree_centrality': nx.degree_centrality(graph),
                 'betweeness': nx.betweenness_centrality(graph),
                 'resistance_centrality': nx.current_flow_closeness_centrality(graph)}

    return temp_dict

# # #
# V #
# # #


from vinfraclient.cmd.base import Lister, ShowOne
from vinfraclient.formatters import columns as fmt_columns
from vinfraclient.utils import find_resource

def _alert_arg(parser):
    parser.add_argument(
        "alert",
        type=int,
        metavar="<alert>",
        help="Alert ID"
    )

class ListAlert(Lister):
    _description = "List alert log entries"
    _default_fields = ['id', 'type', 'datetime', 'severity', 'enabled']
    _formatters = {'datetime': fmt_columns.DatetimeColumn}

    def configure_parser(self, parser):
        parser.add_argument(
            "--all",
            dest="all",
            action="store_true",
            help="Show both enabled and disabled alerts."
        )
        parser.add_argument(
            "--lang",
            type=str,
            default='en',
            help="Language of alert message. Supported values: en, de, es, ja, pt, ru, tr, zh"
        )

    def do_action(self, parsed_args):
        enabled = not parsed_args.all
        lang = parsed_args.lang
        alerts = self.app.vinfra.alerts.list(enabled=enabled, lang=lang)
        return alerts

class ShowAlert(ShowOne):
    _description = "Show details of the specified alert log entry."
    _formatters = {'datetime': fmt_columns.DatetimeColumn}

    def configure_parser(self, parser):
        _alert_arg(parser)

    def do_action(self, parsed_args):
        return find_resource(self.app.vinfra.alerts, parsed_args.alert)

class DeleteAlert(ShowOne):
    _description = "Remove an entry from the alert log."
    _formatters = {'datetime': fmt_columns.DatetimeColumn}

    def configure_parser(self, parser):
        _alert_arg(parser)

    def do_action(self, parsed_args):
        alert = find_resource(self.app.vinfra.alerts, parsed_args.alert)
        return alert.update(enabled=False)


import tkinter
import tkinter.messagebox

def caesar_cipher1():  # “加密”按钮激发函数
    c = mingwen.get("0.0", "end")[:-1]
    if c == '':
        tkinter.messagebox.showinfo('恺撒密码', '请输入明文。')
        return
    b = ""
    miwen.config(state="normal")
    miwen.delete("0.0", "end")
    for i in range(len(c)):
        if 'a' <= c[i] <= 'w' or 'A' <= c[i] <= 'W':
            b = b + chr(ord(c[i]) + 3)
        elif 'x' <= c[i] <= 'z' or 'X' <= c[i] <= 'Z':
            b = b + chr(ord(c[i]) - 23)
        else:
            b = b + c[i]
    miwen.insert("0.0", b)
    miwen.config(state="disabled")

def caesar_cipher2():  # “解密”按钮激发函数
    c = miwen.get('0.0', 'end')[:-1]
    if c == '':
        tkinter.messagebox.showinfo('恺撒密码', '请单击“加密”按钮。')
        return
    b = ''
    mingwen2.config(state="normal")
    mingwen2.delete('0.0', 'end')
    for i in range(len(c)):
        if 'd' <= c[i] <= 'z' or 'D' <= c[i] <= 'Z':
            b += chr(ord(c[i]) - 3)
        elif 'a' <= c[i] <= 'c' or 'A' <= c[i] <= 'C':
            b += chr(ord(c[i]) + 23)
        else:
            b += c[i]
    mingwen2.insert('0.0', b)
    mingwen2.config(state="disabled")

def caesar_cipher3():  # “对比”按钮激发函数
    b = mingwen.get('0.0', 'end')[:-1]
    c = mingwen2.get('0.0', 'end')[:-1]
    if b == '':
        tkinter.messagebox.showinfo('恺撒密码', '请输入明文。')
        return
    if c == '':
        tkinter.messagebox.showinfo('恺撒密码', '请单击“解密”按钮。')
        return
    if b == c:
        tkinter.messagebox.showinfo('恺撒密码', '解密正确！')
    else:
        tkinter.messagebox.showinfo('恺撒密码', '解密错误！')

root = tkinter.Tk()
root.title("恺撒加密")
root.geometry('300x330')
tkinter.Label(root, text='请输入明文', font=('Arial', 10)).pack()
mingwen = tkinter.Text(root, width=300, height=4)
mingwen.pack()
mingwen.focus_set()
tkinter.Button(root, text="加密", command=caesar_cipher1, relief="solid", width=10).pack()
tkinter.Label(root, text='恺撒密文', font=('Arial', 10)).pack()
miwen = tkinter.Text(root, width=300, height=4)
miwen.pack()
tkinter.Button(root, text='解密', command=caesar_cipher2, relief='solid', width=10).pack()
tkinter.Label(root, text='解密得到的凯撒明文', font=('Arial', 10)).pack()
mingwen2 = tkinter.Text(root, width=300, height=4, state="disabled")
mingwen2.pack()
tkinter.Button(root, text='对比', command=caesar_cipher3, relief='solid', width=10).pack()
root.mainloop()

第2学期/【第19课】加密与解密/恺撒密码.py


from dataclasses import dataclass

def bin8(value: int):
    """
    Convert 8-bit register value to binary representation.
    """
    return ("0"*8 + bin(value)[2:])[-8:]

def metronome_pattern(bar_length):
    return [3, 0] + [1, 0] * (bar_length - 1)

def timing_grade(time, target, margin):
    error = abs(target-time)
    if error <= margin:
        return 1.0
    else:
        return 0

@dataclass
class RegRecording:
    data: int
    time: int
    tainted: bool = False

    def timing_grade(self, target, margin):
        return timing_grade(self.time, target, margin)

def bitmask_history(history, bitmask: int):
    first = history[0]
    newhist = [RegRecording(first.data & bitmask, first.time, first.data & bitmask != first.data)]
    for n in history[1:]:
        if n.data & bitmask == newhist[-1].data:
            newhist[-1].time += n.time
            if n.data & bitmask != n.data:
                newhist[-1].tainted = True
        else:
            newhist.append(RegRecording(n.data & bitmask, n.time, n.data & bitmask != n.data))
    return newhist

def prefix_match(sequence, target):
    out = []
    for i, expected in enumerate(target):
        if i >= len(sequence):
            break
        if sequence[i].data != expected:
            break
        out.append(sequence[i])
    return out

def get_longest_match(sequence, target):
    prefixes = [prefix_match(sequence[i:], target) for i in range(len(sequence))]
    if not prefixes:
        return -1, []
    # Reversed because we want to prefer the latest longest match.
    # For example, if we don't use the latest match in 2X speed test, we might incorrectly
    # detect a timing error.
    maxi = max(reversed(range(len(prefixes))), key=lambda i: len(prefixes[i]))
    return maxi, prefixes[maxi]

class ReportSection:
    def __init__(self, name: float, max_grade: float):
        self.name = name
        self.max_grade = max_grade
        self.grade = 0.0

    def grade_str(self) -> str:
        if self.max_grade > 0:
            return "%.1f / %.1f" % (self.grade, self.max_grade)
        else:
            return "%.1f" % self.grade

class Report:
    def __init__(self):
        self.grade_log = []

    def add_section(self, name, grade):
        new_section = ReportSection(name, grade)
        self.grade_log.append(new_section)
        return new_section

    def report_str(self):
        if len(self.grade_log) == 0:
            self.add_section("Failed to execute tests", 0.0)
        grade_items = [g.grade_str() for g in self.grade_log]
        f = "{0:>" + str(max([len(s) for s in grade_items])) + "}  {1}"
        grade_report = "\n".join([f.format(g, r.name) for g, r in zip(grade_items, self.grade_log)])

        total_grade = sum([g.grade for g in self.grade_log])
        max_grade = sum([g.max_grade for g in self.grade_log])
        return f"GRADE\n{grade_report}\nFINAL GRADE: {total_grade:.1f}/{max_grade:.1f}"

def record_porta(m, max_history: int, max_cycles: int, max_flicker: int = 1000):
    flickers = []
    # Watch writes to this register
    m.watch("PORTA W")
    m.watch("LATA W")
    history = []
    # Since PORTA is output, we need to read from LATCH
    value = m.get("LATA")
    current = RegRecording(value, 0)
    cycles = 0
    while len(history) < max_history:
        m.run()
        value = m.get("LATA")
        time = m.stopwatch()
        current.time += time
        cycles += time
        if value != current.data:
            print("PORTA changed to", str(value) + " (" + bin8(value) + ") after", str(time/1e6) + "s", end = " ")
            if current.time > max_flicker:  # Don't record if too short
                history.append(current)
            elif len(history) > 1:  # Ignore flickers at the start
                flickers.append(current)
                print("(FLICKER)", end="")
            print()
            current = RegRecording(value, 0)
        if cycles > max_cycles:
            if current.time > max_flicker:  # Don't record if too short
                history.append(current)
            break
    m.clear_breakpoints()
    return history

def click_button(m, pin):
    """
    Press the button, wait 10ms, release the button
    """
    print("Pressing & releasing "+ pin.upper() + "...")
    m.exec("write pin " + pin + " high")
    m.stepi(50_000)
    m.exec("write pin " + pin + " low")
    m.stepi(50_000)

def hold_button(m, pin):
    """
    Press the button
    """
    print("Holding "+ pin.upper() + "...")
    m.exec("write pin " + pin + " high")

def release_button(m, pin):
    """
    Release the button
    """
    print("Releasing "+ pin.upper() + "...")
    m.exec("write pin " + pin + " low")


idade = int(input())
maior = 0
soma = 0
n = 0
velho = 0

while idade >= 0:
    n += 1
    soma += idade

    if idade >= 18:
        maior += 1

    if idade > 75:
        velho += 1

    idade = int(input())

media = soma / n
idoso = (velho / n) * 100

print(f"{media:.2f}")
print(maior)
print(f"{idoso:.2f}%")

Exercises C - Repetition/C020 - Idades.py


# Section12-1
# 파이썬 데이터베이스 연동(SQLite)
# 테이블 생성 및 삽입

import sqlite3
import datetime

# 삽입 날짜 생성
now = datetime.datetime.now()
print('now : ', now)

nowDatetime = now.strftime('%Y-%m-%d %H:%M:%S')
print('nowDatetime : ',nowDatetime)

# sqlite3
print('sqlite3.version : ', sqlite3.version)
print('sqlite3.sqlite_version : ',sqlite3.sqlite_version)

# DB 생성 & Auto Commit(Rollback)
conn = sqlite3.connect('D:\Study\IT_Skill\패스트캠퍼스\Python\python_basic/resource/database.db', isolation_level=None)

# Cursor
c = conn.cursor()
print('Cursor Type ', type(c))

# 테이블 생성(Data Type : TEXT, NUMERIC INTEGER REAL BLOB)
c.execute("CREATE TABLE IF NOT EXISTS users(id INTEGER PRIMARY KEY, username text, email text \
,phone text, website text, regdata text)") # 테이블이 없으면 만들겠다

# 테이블 삽입
#c.execute("INSERT INTO users VALUES(1, 'Kim', 'Kim@naver.com', '010-1234-5678', \
    #'Kim.com', ?)", (nowDatetime,)) # nowDatetime 이 ? 에 매칭돼 들어감
#c.execute("INSERT INTO users(id, username, email, phone, website, regdata) VALUES(?,?,?,?,?,?)",(2, 'Lee', 'Lee@naver.com', '010-1234-5678', 'Lee.com', nowDatetime))

# Many 삽입(튜플, 리스트)
userList = (
    (3, 'Park', 'Park@naver.com', '010-0000-0003', 'Park.com', nowDatetime),
    (4, 'Choi', 'Choi@naver.com', '010-0000-0004', 'Choi.com', nowDatetime),
    (5, 'Jung', 'Jung@naver.com', '010-0000-0005', 'Jung.com', nowDatetime)
)

# c.executemany("INSERT INTO users(id, username, email, phone, website, regdata) VALUES(?,?,?,?,?,?)", userList)

# 테이블 데이터 삭제
# conn.execute("DELETE FROM users")
# print("users db deleted : ", conn.execute("DELETE FROM users").rowcount) # 데이터를 지운 후 몇개를 지웠는지 알려준다

# 커밋 : isolation_level = None 일 경우 자동 반영(오토 커밋)

# 롤백
# conn.rollback()

# 접속 해제
# conn.close()


ano = int(input('Informe o ano de seu nascimento:'))
alistar = 2018 - ano
if alistar < 18:
    falta = 18 - alistar
    print('Falta:{} ano para voce se alistar'.format(falta))
elif alistar == 18:
    falta = 18 - alistar
    print('Ja esta na hora de voce se alistar.')
elif alistar > 18:
    falta = alistar - 18
    print('O tempo ja estourou para o alistamento em:{} anos.'.format(falta))


import os
import json

from collections import namedtuple
from tile2net.tileseg.config import cfg
from runx.logx import logx
from tile2net.tileseg.datasets.base_loader import BaseLoader
from tile2net.tileseg.datasets.utils import make_dataset_folder
from tile2net.tileseg.datasets import uniform

Label = namedtuple( 'Label' , [

    'name'        , # The identifier of this label, e.g. 'car', 'person', ... .
    # We use them to uniquely name a class

    'id'          , # An integer ID that is associated with this label.
    # The IDs are used to represent the label in ground truth images
    # An ID of -1 means that this label does not have an ID and thus
    # is ignored when creating ground truth images (e.g. license plate).
    # Do not modify these IDs, since exactly these IDs are expected by the
    # evaluation server.

    'trainId'     , # Feel free to modify these IDs as suitable for your method. Then create
# ground truth images with train IDs, using the tools provided in the
# 'preparation' folder. However, make sure to validate or submit results
# to our evaluation server using the regular IDs above!
# For trainIds, multiple labels might have the same ID. Then, these labels
# are mapped to the same class in the ground truth images. For the inverse
# mapping, we use the label that is defined first in the list below.
# For example, mapping all void-type classes to the same ID in training,
# might make sense for some approaches.
# Max value is 255!
    'color'       , # The color of this label
] )

labels = [
    #       name                     id    trainId     color
    Label(  'Sidewalk'             ,  1 ,        0 ,  (0, 0, 255)),
    Label(  'Road'                 ,  2 ,        1 ,  (0, 128, 0)),
    Label(  'Crosswalk'            ,  3 ,        2 ,  (255, 0, 0)),
    Label(  'Background'           ,  4 ,        3 ,  (0, 0, 0)),
    ]

name2label      = { label.name    : label for label in labels           }
# id to label object
id2label        = { label.id      : label for label in labels           }
# trainId to label object
trainId2label   = { label.trainId : label for label in reversed(labels) }
# label2trainid
label2trainid   = { label.id      : label.trainId for label in labels   }
# trainId to label object
trainId2name   = { label.trainId : label.name for label in labels   }
trainId2color  = { label.trainId : label.color for label in labels      }

class Loader(BaseLoader):
    num_classes = 4
    ignore_label = -1
    trainid_to_name = {}
    color_mapping = []

    def __init__(self, mode, quality='semantic', joint_transform_list=None,
                 img_transform=None, label_transform=None, eval_folder=None):

        super(Loader, self).__init__(quality=quality,
                                     mode=mode,
                                     joint_transform_list=joint_transform_list,
                                     img_transform=img_transform,
                                     label_transform=label_transform)

        root = cfg.DATASET.SATELLITE_DIR
        # config_fn = os.path.join(root, 'config.json')
        # self.fill_colormap_and_names(config_fn)
        self.id_to_trainid = label2trainid
        self.trainid_to_name = trainId2name
        self.fill_colormap()

        ######################################################################
        # Assemble image lists
        ######################################################################
        if mode == 'folder':
            self.all_imgs = make_dataset_folder(eval_folder)
        elif mode =='test':
            self.all_imgs = make_dataset_folder(eval_folder, testing=True)
        else:
            splits = {'train': 'train',
                      'val': 'val',
                      'test': 'tests'}
            split_name = splits[mode]
            # img_ext = 'png'
            # mask_ext = 'png'
            img_ext = '*'
            mask_ext = '*'
            img_root = os.path.join(root, split_name, 'images')
#            print(img_root)
            mask_root = os.path.join(root, split_name, 'annotations')
            self.all_imgs = self.find_images(img_root, mask_root, img_ext,
                                             mask_ext)
        logx.msg('all imgs {}'.format(len(self.all_imgs)))
        self.fine_centroids = uniform.build_centroids(self.all_imgs,
                                                      self.num_classes,
                                                      self.train,
                                                      cv=cfg.DATASET.CV,
                                                      id2trainid=self.id_to_trainid)
        self.centroids = self.fine_centroids
#        print('centroids', self.centroids)
        self.build_epoch()

    def fill_colormap(self):
        palette = [0, 0, 255,
                   0, 128, 0,
                   255, 0, 0,
                   0, 0, 0]

        zero_pad = 256 * 3 - len(palette)
        for i in range(zero_pad):
            palette.append(0)
        self.color_mapping = palette


import sys
sys.path.append('C:\\Users\\Ruedi\\OneDrive\\Learning\\Learning\\World Bank')
import GUI_Plots_Pannel
import GUI_ListPannel
import WorldBank

from PyQt5.QtWidgets import QApplication, QWidget, QHBoxLayout

class WIN( QWidget ):

    def __init__(self, parent = None):
        super(WIN, self).__init__(parent)
        self.worldBank = WorldBank.WorldBank()
        self.showFullScreen()
        self.setWindowTitle( "World Bank GUI" )

        layout = QHBoxLayout()
        self.setLayout(layout)

        self.plots_Pannel = GUI_Plots_Pannel.GUI_Plots_Pannel( self.worldBank )
        self.listPannel = GUI_ListPannel.GUI_List_Pannel( self.worldBank, self.plots_Pannel )

        layout.addLayout( self.listPannel, 1 )
        layout.addLayout( self.plots_Pannel, 5 )

        self.show()

if __name__ == '__main__':
    app = QApplication(sys.argv)
    win = WIN()
    sys.exit(app.exec_())


# Importamos la librería para crear ventanas de Tk
from tkinter import *

# Le asignamos a una variable la raiz de las ventanas
raiz = Tk()
# Le ponemos un tiutlo a la ventana
raiz.title("Ventana de pruebas")
# si se le pasa resizable con los parametros True o False se controla el modificat manualmente el alto y el ancho; endonde el primer parametro es weigrh y el segundo es heigh.
# raiz.resizable(True, False)
# Para agregar un icono a la ventana
raiz.iconbitmap("bombilla3.icns")
# Con geometry() se le puede dar un tamaño definido a la ventana en cuanto abre. Aunque la raiz siempre toma el tamaño de lo que contiene
# raiz.geometry("650x350")
# Podemos por ejemplo cambiar el color de la ventana con config()
raiz.config(bg="blue")
# Creamos el Frame
miFrame = Frame()
# Empacamos le frame dentro de la ventana
miFrame.pack()
# le ponemos un color de fondo al frame
miFrame.config(bg="red")
# le damos un tamaño especifico al frame
miFrame.config(width="650", heigh="350")

miFrame.config(bd="35")

miFrame.config(relief="sunken")

miFrame.config(cursor="pirate")

# Iniciamos la ventana para mostrarla colocandola en un bucle
raiz.mainloop()


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

import pandas as pd
import os

df = pd.read_pickle(os.path.join('..', 'data_frame.pickle'))

# Smaller object for easier vis
small_df = df.iloc[49980:50019, :].copy()

# Basic Excel
small_df.to_excel("basic.xlsx")
small_df.to_excel("no_index.xlsx", index=False)
small_df.to_excel("columns.xlsx", columns=["artist", "title", "year"])

# Multiple worksheets
writer = pd.ExcelWriter('multiple_sheets.xlsx', engine='xlsxwriter')
small_df.to_excel(writer, sheet_name="Preview", index=False)
df.to_excel(writer, sheet_name="Complete", index=False)
writer.save()

# Conditional formatting
artist_counts = df['artist'].value_counts()
artist_counts.head()
writer = pd.ExcelWriter('colors.xlsx', engine='xlsxwriter')
artist_counts.to_excel(writer, sheet_name="Artist Counts")
sheet = writer.sheets['Artist Counts']
cells_range = 'B2:B{}'.format(len(artist_counts.index))
sheet.conditional_format(cells_range, {'type': '2_color_scale',
                              'min_value': '10',
                              'min_type': 'percentile',
                              'max_value': '99',
                              'max_type': 'percentile'})
writer.save()

# SQL
import sqlite3

with sqlite3.connect('my_database.db') as conn:
    small_df.to_sql('Tate', conn)

# import sqlalchemy as sa
# with sa.create_engine('postgresql://localhost/my_data') as conn:
#     small_df.to_sql('Tate', conn)

# JSON
small_df.to_json('default.json')
small_df.to_json('table.json', orient='table')


# coding: utf-8

import numpy as np
import random

class Osero():
    def __init__(self):
        self.n_rows=8
        self.n_cols=8
        self.cells=np.zeros((self.n_rows,self.n_cols))
        self.blank=0
        self.white=1
        self.black=2

    def reset(self):
        self.cells[3][3]=self.white
        self.cells[3][4]=self.black
        self.cells[4][3]=self.black
        self.cells[4][4]=self.white

    def flip_able_man(self,now_state,current_player):
        self.now_state=now_state
        self.current_player=current_player
        dir_list=[-1,0,1]
        self.flip_able=[]
        for dx in dir_list:
            for dy in dir_list:
                temp=[]
                depth=0
                while True:
                    depth+=1
                    rx=self.now_state[0]+dx*depth
                    ry=self.now_state[1]+dy*depth

                    if 0<=rx<8 and 0<=ry<8:
                        piece=self.cells[rx][ry]

                        if piece==self.blank:
                            break
                        elif piece==self.current_player:
                            if temp!=[]:
                                self.flip_able.extend(temp)
                        else:
                            temp.append([rx,ry])
                    else:
                        break
        return self.flip_able

    def flip(self):
        for i in range(len(self.flip_able)):
            self.cells[self.flip_able[i][0]][self.flip_able[i][1]]=self.current_player

        self.cells[self.now_state[0]][self.now_state[1]]=self.current_player
        return self.cells

    def show_board(self):
        self.board=[]
        for i in range(self.n_rows):
            for j in range(self.n_cols):
                pi=self.cells[i][j]
                if pi==self.blank:
                    self.board.append('*')
                elif pi==self.white:
                    self.board.append('○')
                else:
                    self.board.append('●')

        self.board=np.array(self.board).reshape(self.n_rows,self.n_cols)
        print(self.board)

    def End(self,player):
        possible=[]
        for i in range(self.n_rows):
            for j in range(self.n_cols):
                pi=self.cells[i][j]
                if pi!=self.blank:
                    if pi!=player:
                        possible.append([i,j])
        if len(possible)==0:
            return True
        else:
            return False
    def possible(self,player):
        self.possible=[]
        for i in range(self.n_rows):
            for j in range(self.n_cols):
                pi=self.cells[i][j]
                if pi!=self.blank:
                    if pi!=player:
                        self.possible.append([i,j])
        return self.possible

    def player_change(self,player):
        if player==self.white:
            return self.black
        else:
            return self.white

    def winner(self):
        color_white=0
        color_black=0
        for i in range(self.n_rows):
            for j in range(self.n_cols):
                if self.cells[i][j]==self.white:
                    color_white+=1
                elif self.cells[i][j]==self.black:
                    color_black+=1
                else:
                    color_white+=0
                    color_black+=0

        if color_white>color_black:
            print('winner:white')
        elif color_white==color_black:
            print('on drow')
        else:
            print('winner:black')

    def show_index(self):
        def index_to_axis(index):
            r=int(index/8)
            c=index%8
            return [r,c]
        index_list=list(np.arange(0,self.n_rows*self.n_cols))
        axis_list=[]

        for i in range(0,self.n_rows*self.n_cols,self.n_rows):
            ind=index_list[i:i+self.n_rows]
            bb=[]
            for j in range(len(ind)):
                bb.append(index_to_axis(ind[j]))
            axis_list.append(bb)

        for i in range(self.n_rows):
            print(axis_list[i])

    def get_enables(self,color):
        """置ける位置のリストを返す関数"""
        result=[]
        enable_actions=np.arange(0,self.n_rows*self.n_cols)
        for action in enable_actions:
            r,c=self.index2axis(action)
            if self.cells[r][c]==self.blank:
                    result.append([r,c])
        return result

    #一次元のインデックスを二次元に変換
    def index2axis(self,index):
        r=int(index/8)
        c=index%8
        return r,c
    #対戦者同士の得点を算出する関数
    def get_score(self,player):
        score=0
        for i in range(self.n_rows):
            for j in range(self.n_cols):
                pi=self.cells[i][j]
                if pi==self.player:
                    score+=1
                else:
                    score+=0
        return score


import pygame
from tiles import Tile, AnimatedTile
from support import import_folder
from settings import screen_ratio

class Enemy(Tile):

	def __init__(self, width, height, x, y, direction, speed, surface):
		super().__init__(width, height, x, y)
		self.direction = direction
		self.speed = int(screen_ratio * speed)
		self.image = surface

	# Move enemy. If direction is 0 (horizontal), move along x axis.
	# If direction is 1 (vertical), move along y axis
	def move(self):
		if self.direction == 0:
			self.rect.x += self.speed
		elif self.direction == 1:
			self.rect.y += self.speed

	# Reverse enemy direction when they collide with constraints.
	# If enemy direction is horizontal, flip image
	def reverse_direction(self):
		self.speed *= -1
		if self.direction == 0:
			self.image = pygame.transform.flip(self.image, True, False)

	def update(self, shift):
		self.rect.x += shift
		self.move()

class AnimatedEnemy(Enemy):

	def __init__(self, width, height, x, y, direction, speed, surface, path_index):
		super().__init__(width, height, x, y, direction, speed, surface)
		self.path = '../graphics/enemies/' + str(path_index)
		self.frames = import_folder(self.path)
		self.frame_index = 0
		self.image = self.frames[self.frame_index]
		self.width = width
		self.height = height

	def animate(self):

		self.frame_index += 0.15
		if self.frame_index >= len(self.frames):
			self.frame_index = 0
		self.image = self.frames[int(self.frame_index)]
		self.image = pygame.transform.scale(self.image, (self.width, self.height))
		print(self.direction)
		if self.speed > 0:
			self.image = pygame.transform.flip(self.image, True, False)

	def update(self, shift):
		self.rect.x += shift
		self.animate()
		self.move()


import tkinter as tk
from tkinter import ttk
from tkinter import messagebox

Window=tk.Tk()
Window.geometry("500x400")
Window.title("digital asistance")

def buttonFunction():
    print("push button")

    #label yazı değiştirme
    label.config(text="merhaba dünya",font="Times 20", bg="red",fg="yellow")

    #entry
    value=entry.get()
    label.configure(text=value)
    entry.configure(state="disabled")

    #messagebox
    message_box=messagebox.showinfo(title="info",message="information")
    message_box=messagebox.askokcancel(title="info",message="information")
    message_box=messagebox.askretrycancel(title="info",message="information")
    message_box=messagebox.askquestion(title="info",message="information",)
    print(message_box)

#button
button=tk.Button(Window,text="button",activebackground="green",bg="yellow",fg="purple",activeforeground="orange",height=10,width=200,
                 command=buttonFunction)
button.pack()
#label
label=tk.Label(Window,text="hello world",font="Times 16", fg="black",bg="white",wraplength=50)
label.pack(side=tk.RIGHT,padx=10)

#entry
entry=tk.Entry(Window,width=50)
entry.pack(side=tk.LEFT,padx=10)

Window.mainloop()


import cv2

# Aquí coloca la ruta de la imagen con la cara a detectar
imagenRuta = 'imagen.jpeg'

# Cargar el modelo pre-entrenado para detección facial
face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_frontalface_default.xml')

# Cargar la imagen en la que deseas realizar el reconocimiento facial
image = cv2.imread( imagenRuta )

# Convertir la imagen a escala de grises
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

# Detectar caras en la imagen
faces = face_cascade.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=5, minSize=(30, 30))

# Dibujar un rectángulo alrededor de cada cara detectada
for (x, y, w, h) in faces:
    cv2.rectangle(image, (x, y), (x + w, y + h), (0, 255, 0), 2)

# Mostrar la imagen con las caras marcadas
cv2.imshow("Reconocimiento Facial", image)

# Esperar a que el usuario presione una tecla y luego cerrar la ventana
cv2.waitKey(0)
cv2.destroyAllWindows()


import xml.etree.ElementTree as etree

""" Must test this found at http://stackoverflow.com/questions/127606/editing-xml-as-a-dictionary-in-python

USAGE :

tree = etree.parse('test.xml')
root = tree.getroot()

pydict = xml_to_dict(root)

"""

def xml_to_dict(el):
  d={}
  if el.text:
    d[el.tag] = el.text
  else:
    d[el.tag] = {}
  children = el.getchildren()
  if children:
    d[el.tag] = map(xml_to_dict, children)
  return d


from module import obo2csv
from configure import obo_url,num_threads
excludeGO = "GO:0005515,GO:0005488,GO:0003674,GO:0008150,GO:0005575"
#excludeGO = ""
import sys
import os
import multiprocessing as mp
from multiprocessing import Pool
from contextlib import closing

def get_obo_dict():  # read obo_dict

    fp = open(obo_url, 'r')
    obo_txt = fp.read()
    fp.close()
    obo_dict = obo2csv.parse_obo_txt(obo_txt)
    return obo_dict

## global variables for multiprocessing
obo_dict = get_obo_dict()

def get_obsolete(obo_dict): # get obsolete terms

    return obo_dict.obsolete()

def find_parents(obo_dict, GOterm): # find parents

    obsolete_list=get_obsolete(obo_dict)

    if(GOterm in obsolete_list):
        return []
    else:
        if(obo_dict.is_a(GOterm, direct=False, name=False, number=False)==""):
            return []
        parent_term_list = obo_dict.is_a(GOterm, direct=False, name=False, number=False).split()
        return list(set(parent_term_list)-set(excludeGO.split(",")))

def find_parents_from_file(originfile, new_file):  # find parents from file

    f=open(originfile, "r")
    text=f.read()
    f.close()

    type=""
    temp_dict=dict()

    for line in text.splitlines():
        values=line.strip().split()
        term=values[0]
        type=values[1]
        pro=float(values[2])
        if (pro >= 0.01):
            temp_dict[term] = pro

    new_dict = dict()
    for term in temp_dict:
        parent_list = find_parents(obo_dict, term)
        for parent in parent_list:
            if (parent not in new_dict or temp_dict[term] > new_dict[parent]):
                new_dict[parent] = temp_dict[term]

    # sort the new_dict
    result_list = [(new_dict[term], term) for term in new_dict]
    result_list = sorted(result_list, reverse=True)

    f = open(new_file, "w")
    for value, term in result_list:
        f.write(term + " " + type + " " + str(value) + "\n")
    f.flush()
    f.close()

    # f=open(new_file, "w")
    # for term in new_dict:
    #     f.write(term+" "+type+" "+str(new_dict[term])+"\n")
    # f.flush()
    # f.close()

def sort_result(originfile):  # sort result

    f = open(originfile, "r")
    text = f.read()
    f.close()

    temp_dict = dict()

    for line in text.splitlines():
        values = line.strip().split()
        term = values[0]
        type = values[1]
        pro = float(values[2])
        if(pro>=0.01):
            temp_dict[term] = pro

    result_list=[(temp_dict[term], term) for term in temp_dict]
    result_list = sorted(result_list, reverse=True)

    f=open(originfile, "w")
    for value, term in result_list:
        f.write(term+" "+type+" "+str(value)+"\n")
    f.flush()
    f.close()

def multiprocess_find_parents_from_file(args_list):  # multiprocess
    result_file, result_file_new = args_list
    find_parents_from_file(result_file, result_file_new)

if __name__=="__main__":

    workdir = sys.argv[1]
    type = sys.argv[2]
    name_list = os.listdir(workdir)

    args_list = []
    for name in name_list:
        result_file = workdir+"/"+name+"/"+sys.argv[3]+"_"+type
        result_file_new = workdir+"/"+name+"/"+sys.argv[3]+"_"+type+"_new"
        args_list.append((result_file, result_file_new))
        #find_parents_from_file(result_file, result_file+"_new", obo_dict)

    with closing(Pool(processes=num_threads)) as pool:
        pool.map(multiprocess_find_parents_from_file, args_list)
        pool.close()
        pool.join()


# 과제 1 - 맛집 고르기
#
# 구현 내용
#
# 처음 파이썬 파일을 실행 시키면, 한식, 중식, 일식 중 한 가지를 고르라는 내용이 나옵니다.
# 그 중에서 한 가지를 고르면 식당 이름을 하나 임의로 추천해 줍니다.

import random
input_q = input ("한식,중식,일식 중 무엇을 고르시겠습니까?")

korea = ['천리집', '함지박', '김밥천국', '비채나', '일호식', '밍글스']
chinese = ['골드피쉬', '쮸즈', '미스터서왕만두', '포담', '쟈니덤플링', '일일향']
japanese = ['정돈', '이치에', '오가와', '갓포아키', '히메시야', '토야']

if input_q == "한식":
    print (random .choice(korea))
elif input_q == "중식":
    print (random.choice(chinese))
else:
    print (random.choice(japanese))


from sensor.logger import logging
from sensor.exception import SensorException
import sys,os

def test_logg():
     try:
          logging.info("start of the command")
          c = 3/0
          print(c)
          logging.info("end of the command")
     except Exception as e:
          logging.debug("degbus")
          raise SensorException(e,sys)

if __name__=="__main__":
     try:
        test_logg()
     except Exception as e:
          print(e)


import datetime
from PyQt4.QtCore import Qt
from PyQt4.QtGui import QColor, QGraphicsDropShadowEffect, QLabel

class Log():

	def __init__(self, name="MAIN()", level="error"):
		self.level = level
		self.name = name

	def log(self, message, lvl):
		ts = "{:%x %X} ".format(datetime.datetime.now())
		nm = "{:<20}".format(self.name)

		if lvl == "debug":
			tag = "{:^16}".format("DEBUG")
		elif lvl == "info":
			tag = "{:^16}".format("INFO")
		elif lvl == "warning":
			tag = "{:^16}".format("-WARNING-")
		elif lvl == "error":
			tag = "{:*^16}".format("ERROR")

		if self.level == "debug":
			print (ts + nm + tag + message)

		elif self.level == "info":
			if lvl == "info" or lvl == "warning" or lvl == "error":
				print (ts + nm + tag + message)

		elif self.level == "warning":
			if lvl == "warning" or lvl == "error":
				print (ts + nm + tag + message)

		elif self.level == "error":
			if lvl == "error":
				print (ts + nm + tag + message)

	def debug(self, message):
		self.log(message, "debug")

	def info(self, message):
		self.log(message, "info")

	def warning(self, message):
		self.log(message, "warning")

	def error(self, message):
		self.log(message, "error")

def align(gridnum):
	if gridnum == 1:
		return (Qt.AlignLeft | Qt.AlignTop)
	elif gridnum == 2:
		return (Qt.AlignHCenter | Qt.AlignTop)
	elif gridnum == 3:
		return (Qt.AlignRight | Qt.AlignTop)
	elif gridnum == 4:
		return (Qt.AlignLeft | Qt.AlignVCenter)
	elif gridnum == 5:
		return (Qt.AlignHCenter | Qt.AlignVCenter)
	elif gridnum == 6:
		return (Qt.AlignRight | Qt.AlignVCenter)
	elif gridnum == 7:
		return (Qt.AlignLeft | Qt.AlignBottom)
	elif gridnum == 8:
		return (Qt.AlignHCenter | Qt.AlignBottom)
	elif gridnum == 9:
		return (Qt.AlignRight | Qt.AlignBottom)
	else:
		return (Qt.AlignHCenter | Qt.AlignVCenter)

def createTextLabel(page, frameName, properties):
	textLabel = QLabel(page)
	textLabel.setObjectName(frameName+properties['name'])
	textLabel.setStyleSheet("#"+frameName+properties['name']+"{ font-family:"+properties['font']+"; color: "+
		properties['color'] + "; background-color: transparent; font-size: "+
		properties['fontsize']+"px; "+
		properties['fontattr']+"}")
	textLabel.setAlignment(align(properties['alignment']))
	if properties['shadow']:
		textEffect = QGraphicsDropShadowEffect()
		textEffect.setOffset(properties['shadow']['offset'])
		textEffect.setBlurRadius(properties['shadow']['blur'])
		textEffect.setColor(QColor(properties['shadow']['color']))
		textLabel.setGraphicsEffect(textEffect)
	textLabel.setGeometry(properties['location'][0], properties['location'][1], properties['location'][2], properties['location'][3])

	return textLabel

def createImageLabel(page, frameName, properties):
	imageLabel = QLabel(page)
	imageLabel.setObjectName(frameName+properties['name'])
	imageLabel.setStyleSheet("#"+frameName+properties['name']+" { background-color: transparent; }")
	if properties['shadow']:
		textEffect = QGraphicsDropShadowEffect()
		textEffect.setOffset(properties['shadow']['offset'])
		textEffect.setBlurRadius(properties['shadow']['blur'])
		textEffect.setColor(QColor(properties['shadow']['color']))
		imageLabel.setGraphicsEffect(textEffect)
	imageLabel.setGeometry(properties['location'][0], properties['location'][1], properties['location'][2], properties['location'][3])

	return imageLabel


import sys
import os

from flask import Flask, request, jsonify, redirect, url_for

app = Flask(__name__)

#@app.route("/", methods=['GET','POST', 'PUT', 'DELETE', 'PATCH','OPTIONS'])
@app.route("/", methods=['GET','POST', 'PUT', 'DELETE', 'PATCH','OPTIONS'])
def home():
   return printAndReturnRequest(request)

@app.route("/<string:query>", methods=['GET','POST', 'PUT', 'DELETE', 'PATCH','OPTIONS'])
def homeQuery(query):
    print("Query: %s" % query)
    return printAndReturnRequest(request)

def printAndReturnRequest(request):
    headers = ""
    for i in request.headers.keys():
      headers+= "\t%s: %s \n" % (i, request.headers[i])
    print("Headers: \n%s" % (headers))
    print(request.json)
    return jsonify(headers=headers, body=request.json)

if __name__ == "__main__":
    app.run(host="0.0.0.0", debug=True, port=os.environ.get("LISTEN_PORT","80"))