from abc import ABC, abstractmethod

class EncoderBase(ABC):
    """An abstract class for encoders"""

    @classmethod
    @abstractmethod
    def mode_indicator(cls):
        """Mode indicator defined in the Table 2.

        Returns:
            str: Mode indicator like "001".

        """
        raise NotImplementedError()

    @classmethod
    @abstractmethod
    def encode(cls, data, character_count_indicator_length):
        """Encodes data and returns it.

        Args:
            data (str): Data to encode.
            character_count_indicator_length: (int): Number of bits of character
                count indicator defined in the Table 3.

        Returns:
            str: Encoded binary as string.

        Raises:
            IllegalCharacterError: If the data includes illegal character.

        """
        if not cls.is_valid_characters(data):
            raise IllegalCharacterError

        res = cls.mode_indicator()
        res += bin(cls.characters_num(data))[2:].zfill(character_count_indicator_length)
        res += cls._encoded_bits(data)
        return res

    @classmethod
    @abstractmethod
    def _encoded_bits(cls, data):
        """Encodes data and returns it.

        This method encodes the raw data without the meta data like the mode
        indicator, the number of data characters and so on.

        Args:
            data (str): Data to encode.

        Returns:
            str: Encoded binary as string.

        """
        raise NotImplementedError()

    @classmethod
    @abstractmethod
    def length(cls, data):
        """Compute the length of the encoded bits.

        Args:
            data (str): Data to encode.

        Returns:
            int: The length of the encoded bits.

        """
        raise NotImplementedError()

    @classmethod
    @abstractmethod
    def characters_num(cls, data):
        """Returns the number of the characters of the data.

        Args:
            data (str): The data to encode.

        Returns:
            int: The number of the characters of the data.

        """
        raise NotImplementedError()

    @classmethod
    @abstractmethod
    def is_valid_characters(cls, data):
        """Checks whether the data does not include invalid character.

        Args:
            data (str): Data to validate.

        Returns:
            bool: Validation result.

        """
        raise NotImplementedError()

class IllegalCharacterError(ValueError):
    "A class represents an error raised when the given data includes illegal character."
    pass


import sys
import math

#获取基准点的下标,基准点是p[k]
def get_leftbottompoint(p):
    k = 0
    for i in range(1, len(p)):
        if p[i][1] < p[k][1] or (p[i][1] == p[k][1] and p[i][0] < p[k][0]):
            k = i
    return k

#叉乘计算方法
def multiply(p1, p2, p0):
    return (p1[0] - p0[0]) * (p2[1] - p0[1]) - (p2[0] - p0[0]) * (p1[1] - p0[1])

#获取极角，通过求反正切得出，考虑pi/2的情况
def get_arc(p1, p0):
    # 兼容sort_points_tan的考虑
    if (p1[0] - p0[0]) == 0:
        if ((p1[1] - p0[1])) == 0:
            return -1;
        else:
            return math.pi / 2
    tan = float((p1[1] - p0[1])) / float((p1[0] - p0[0]))
    arc = math.atan(tan)
    if arc >= 0:
        return arc
    else:
        return math.pi + arc

#对极角进行排序,排序结果list不包含基准点
def sort_points_tan(p, pk):
    p2 = []
    for i in range(0, len(p)):
        p2.append({"index": i, "arc": get_arc(p[i], pk)})
    #print('排序前:',p2)
    p2.sort(key=lambda k: (k.get('arc')))
    #print('排序后:',p2)
    p_out = []
    for i in range(0, len(p2)):
        p_out.append(p[p2[i]["index"]])
    return p_out

def graham_scan(p):
    p=list(set(p))
    #print('全部点:',p)
    k = get_leftbottompoint(p)
    pk = p[k]
    p.remove(p[k])
    #print('排序前去除基准点的所有点:',p,'基准点:',pk)

    p_sort = sort_points_tan(p, pk)   #按与基准点连线和x轴正向的夹角排序后的点坐标
    #print('其余点与基准点夹角排序:',p_sort)
    p_result = [pk,p_sort[0]]

    top = 2
    for i in range(1, len(p_sort)):
        #####################################
        #叉乘为正,向前递归删点;叉乘为负,序列追加新点
        while(multiply(p_result[-2], p_sort[i],p_result[-1]) > 0):
            p_result.pop()
        p_result.append(p_sort[i])
    return p_result

if __name__ == '__main__':
    test_case = int(sys.stdin.readline())
    for index in range(test_case):
        size = int(sys.stdin.readline())
        str_arr = sys.stdin.readline().split()
        points = []
        point = {}
        i = 0
        for i in range(size):
            points.append((int(str_arr[2*i]),int(str_arr[2*i+1])))

        list_1 = graham_scan(points)
        # new_s_2 = sorted(list_1, key=lambda e: (e.__getitem__('x')))

        if len(list_1) <= 0:
            print('-1')
        else:
            # for i in range(len(new_s_2)-1):
            #     print(str(new_s_2[i]['x'])+" "+str(new_s_2[i]['y']),end=', ')
            # print(str(new_s_2[-1]['x'])+" "+str(new_s_2[-1]['y']))
            list_1.sort()
            print(', '.join(str(point[0]) + ' ' + str(point[1]) for point in list_1))


import math

from XLTTM import cal_speed_stone_left, cal_speed_stone_right
from XLTTM import cal_steering, cal_speed
from XLTTM import cal_steering_right, cal_steering_left
from settings import *
from tilemap import collide_hit_rect

vec = pg.math.Vector2

def collide_with_walls(sprite, group, dir):
    if dir == 'x':
        hits = pg.sprite.spritecollide(sprite, group, False, collide_hit_rect)
        if hits:
            if hits[0].rect.centerx > sprite.hit_rect.centerx:
                sprite.pos.x = hits[0].rect.left - sprite.hit_rect.width / 2.0
            if hits[0].rect.centerx < sprite.hit_rect.centerx:
                sprite.pos.x = hits[0].rect.right + sprite.hit_rect.width / 2.0
            sprite.vel.x = 0
            sprite.hit_rect.centerx = sprite.pos.x
    if dir == 'y':
        hits = pg.sprite.spritecollide(sprite, group, False, collide_hit_rect)
        if hits:
            if hits[0].rect.centery > sprite.hit_rect.centery:
                sprite.pos.y = hits[0].rect.top - sprite.hit_rect.height / 2.0
            if hits[0].rect.centery < sprite.hit_rect.centery:
                sprite.pos.y = hits[0].rect.bottom + sprite.hit_rect.height / 2.0
            sprite.vel.y = 0
            sprite.hit_rect.centery = sprite.pos.y

class Player(pg.sprite.Sprite):
    def __init__(self, game, x, y):
        self.groups = game.all_sprites
        pg.sprite.Sprite.__init__(self, self.groups)
        self.game = game
        self.image = game.player_img
        self.rect = self.image.get_rect()
        self.hit_rect = PLAYER_HIT_RECT
        self.rect.x = x
        self.rect.y = y
        self.hit_rect.center = self.rect.center
        self.pos = vec(x, y)
        self.vel = vec(0, 0)
        self.acc = vec(0, 0)
        self.path = []
        self.player_speed = PLAYER_SPEED
        self.rot_speed = 0
        self.rot = 0
        self.angle = 0
        self.index = 0
        self.closest_stone = None

    # def get_keys(self):
    #     self.rot_speed = 0
    #     self.vel = vec(0, 0)
    #     keys = pg.key.get_pressed()
    #     if keys[pg.K_LEFT] or keys[pg.K_a]:
    #         self.rot_speed = PLAYER_ROT_SPEED
    #     if keys[pg.K_RIGHT] or keys[pg.K_d]:
    #         self.rot_speed = -PLAYER_ROT_SPEED
    #     if keys[pg.K_UP] or keys[pg.K_w]:
    #         self.vel = vec(PLAYER_SPEED, 0).rotate(-self.rot)
    #     if keys[pg.K_DOWN] or keys[pg.K_s]:
    #         self.vel = vec(-PLAYER_SPEED / 2, 0).rotate(-self.rot)

    def distance(self, dest):
        distance = math.sqrt((dest.x - self.pos.x) ** 2 + (dest.y - self.pos.y) ** 2)
        return distance

    def get_distance_walls(self):
        list_expected_walls = []
        list_walls = []
        for wall in self.game.walls:
            axis_x = math.fabs(wall.x - self.pos.x)
            axis_y = math.fabs(wall.y - self.pos.y)
            distance = math.sqrt(axis_x ** 2 + axis_y ** 2)
            list_walls.append({"wall": wall, "distance": distance})
        list_walls.sort()
        walls = list_walls[:4]
        for wall in walls:
            axis_x = math.fabs(wall["wall"].x - self.pos.x)
            axis_y = math.fabs(wall["wall"].y - self.pos.y)
            # print wall["wall"].id, axis_x, axis_y, wall["wall"].width, wall["wall"].height
            if axis_x <= wall["wall"].width / 2.0:
                list_expected_walls.append({"wall": wall["wall"], "distance": axis_y - wall["wall"].height / 2.0})
            elif axis_y <= wall["wall"].height / 2.0:
                list_expected_walls.append({"wall": wall["wall"], "distance": axis_x - wall["wall"].width / 2.0})
            else:
                continue
        if len(list_expected_walls) >= 2:
            left = right = None
            list_expected_walls.sort()
            rot0 = (list_expected_walls[0]["wall"].pos - self.pos).angle_to(vec(self.path[self.index] - self.pos))
            rot1 = (list_expected_walls[1]["wall"].pos - self.pos).angle_to(vec(self.path[self.index] - self.pos))
            if rot0 % 360 > 0 and rot0 % 360 < 180:
                left = list_expected_walls[0]
            else:
                right = list_expected_walls[0]
            if rot1 % 360 > 180 and rot1 % 360 < 360:
                right = list_expected_walls[1]
            else:
                left = list_expected_walls[1]
            return left["distance"], right["distance"]
        else:
            return 0.5, 0.5

    def get_distance_traffic(self):
        axis_x = math.fabs(self.pos.x - self.game.traffic_light.x)
        axis_y = math.fabs(self.pos.y - self.game.traffic_light.y)
        if axis_x <= self.game.traffic_light.width / 2.0 and axis_y > self.game.traffic_light.height / 2.0:
            return axis_y - self.game.traffic_light.height / 2.0 - self.rect.w / 2.0
        elif axis_y <= self.game.traffic_light.height / 2.0 and axis_x > self.game.traffic_light.width / 2.0:
            return axis_x - self.game.traffic_light.width / 2.0 - self.rect.w / 2.0
        elif axis_y <= self.game.traffic_light.height / 2.0 and axis_x <= self.game.traffic_light.width / 2.0:
            return 0
        else:
            return axis_x - self.game.traffic_light.width / 2.0 - self.rect.w / 2.0

    def get_min_distance_stone(self, dest):
        distance_two_stones = 200
        angle = (dest - self.pos).angle_to(dest - self.pos)
        list_stones = []
        closest_stone = None
        min = self.distance(dest)
        for stone in self.game.stones:
            rot_stone = (stone.pos - self.pos).angle_to(dest - self.pos)
            distance = self.distance(stone) - stone.rect.w / 2.0 - self.rect.w / 2.0
            if distance >= 100:
                continue
            if math.fabs(angle - rot_stone) < 90:
                list_stones.append({"stone": stone, "distance": distance})
                if distance <= min:
                    min = distance
                    closest_stone = stone
        if len(list_stones) >= 2:
            list_stones.sort()
            stone1 = list_stones[0]
            stone2 = list_stones[1]
            rot1 = (stone1["stone"].pos - self.pos).angle_to(dest - self.pos)
            rot2 = (stone2["stone"].pos - self.pos).angle_to(dest - self.pos)
            if rot1 * rot2 < 0:
                axis_x = math.fabs(stone1["stone"].pos.x - stone2["stone"].pos.x) - stone1["stone"].rect.w
                axis_y = math.fabs(stone1["stone"].pos.y - stone2["stone"].pos.y) - stone1["stone"].rect.h
                distance_two_stones = max(axis_x, axis_y)
        if min == self.distance(dest):
            min = 200
        return closest_stone, min, distance_two_stones

    def get_deviation(self, deviation1, deviation2):
        deviation = None
        if deviation1 == None:
            if deviation2 == None:
                deviation = 0.5
            else:
                deviation = deviation2
        else:
            if deviation2 == None:
                deviation = deviation1
            else:
                if (deviation1 < 0.5 and deviation2 < 0.5):
                    deviation = min(deviation1, deviation2)
                elif deviation1 > 0.5 and deviation2 > 0.5:
                    deviation = max(deviation1, deviation2)
                elif deviation2 == 0.5:
                    deviation = deviation1
                else:
                    deviation = deviation2
        return deviation

    def get_velocity(self, vel1, vel2):
        vel = None
        if vel1 == None:
            if vel2 == None:
                vel = 1
            else:
                vel = vel2
        else:
            if vel2 == None:
                vel = vel1
            else:
                vel = min(vel1, vel2)
        return vel

    def update(self):
        distance_two_stones = nearest_stone = None
        distance_stone = None
        deviation = vel = None
        deviation2 = deviation1 = None
        vel2 = vel1 = None
        left_right_stone = None
        # print self.rot
        status_light = self.game.traffic_light.light_status
        left_wall, right_wall = self.get_distance_walls()
        sum = left_wall + right_wall
        dev = left_wall * 1.0 / (right_wall + left_wall)
        distance_traffic_light = self.get_distance_traffic()
        nearest_stone, distance_stone, distance_two_stones = self.get_min_distance_stone(self.path[self.index])
        if distance_two_stones >= 40:
            distance_two_stones = 200
        if nearest_stone:
            self.closest_stone = nearest_stone
            angle_car_stone = (self.closest_stone.pos - self.pos).angle_to(self.path[self.index] - self.pos)
            distance_car_stone = self.distance(self.closest_stone)
            height = round(distance_car_stone * round(math.sin(math.radians(angle_car_stone)), 2), 2)
            left = WIDTH_PATH / 2 - height - self.closest_stone.rect.w / 2.0
            right = WIDTH_PATH - left - self.closest_stone.rect.w
            if left > right:
                left_right_stone = "right"
            else:
                left_right_stone = "left"
        deviation1 = cal_steering(dev)
        vel1 = cal_speed(status_light, distance_traffic_light, dev)
        if left_right_stone == "left":
            deviation2 = cal_steering_left(dev, distance_stone)
            vel2 = cal_speed_stone_left(dev, distance_stone, distance_two_stones / 4.0)
        elif left_right_stone == "right":
            deviation2 = cal_steering_right(dev, distance_stone)
            vel2 = cal_speed_stone_right(dev, distance_stone, distance_two_stones / 4.0)
        else:
            deviation2 = None
            vel2 = None

        vel = self.get_velocity(vel1, vel2)
        deviation = self.get_deviation(deviation1, deviation2)

        self.player_speed = vel * 100
        angle = (math.asin(math.fabs((deviation - 0.5) / 0.5))) * 180 / math.pi

        if deviation > 0.5:
            self.rot = (self.path[self.index] - self.pos).angle_to(vec(1, 0)) + angle * (-1)
        else:
            self.rot = (self.path[self.index] - self.pos).angle_to(vec(1, 0)) + angle
        if self.player_speed >= 2:
            self.image = pg.transform.rotate(self.game.player_img, self.rot)
            self.rect = self.image.get_rect()
            self.rect.center = self.pos
            self.hit_rect.center = self.pos
        distance = self.distance(self.path[self.index])
        self.move(distance)
        if distance <= 30:
            self.index += 1
            if self.index == len(self.path) - 1:
                self.rot = (self.path[self.index] - self.pos).angle_to(vec(1, 0))
                self.image = pg.transform.rotate(self.game.player_img, self.rot)
                self.rect = self.image.get_rect()
                self.rect.center = self.pos
            if self.index == len(self.path):
                self.game.playing = False

    def move(self, distance):
        if distance < 30:
            self.acc = vec(self.player_speed / 2, 0).rotate(-self.rot)
        else:
            self.acc = vec(self.player_speed, 0).rotate(-self.rot)
        self.acc += self.vel * -1
        self.vel += self.acc * self.game.dt
        self.pos += self.vel * self.game.dt + self.acc * self.game.dt
        self.hit_rect.centerx = self.pos.x
        collide_with_walls(self, self.game.walls, 'x')
        self.hit_rect.centery = self.pos.y
        collide_with_walls(self, self.game.walls, 'y')
        self.rect.center = self.pos

class Flag(pg.sprite.Sprite):
    def __init__(self, game, x, y):
        self.groups = game.all_sprites
        pg.sprite.Sprite.__init__(self, self.groups)
        self.game = game
        self.image = game.flag_img
        self.rect = game.flag_img.get_rect()
        self.pos = vec(x, y)
        self.rect.x = x
        self.rect.y = y
        self.hit_rect = PLAYER_HIT_RECT
        self.hit_rect.center = self.rect.center

class Traffic_light(pg.sprite.Sprite):
    def __init__(self, game, x, y, w, h):
        self.groups = game.all_sprites
        pg.sprite.Sprite.__init__(self, self.groups)
        self.game = game
        self.width = w
        self.height = h
        self.rect = pg.Rect(x, y, w, h)
        self.image = pg.Surface((w, h))
        self.image.fill(LIGHTGREY)
        self.pos = vec(x + w / 2.0, y + h / 2.0)
        self.rect.x = x
        self.rect.y = y
        self.x = x + w / 2.0
        self.y = y + h / 2.0
        self.hit_rect = PLAYER_HIT_RECT
        self.hit_rect.center = self.rect.center
        self.light_status = None

class Stone(pg.sprite.Sprite):
    def __init__(self, game, id, x, y, w, h):
        self.groups = game.all_sprites, game.stones
        pg.sprite.Sprite.__init__(self, self.groups)
        self.game = game
        self.id = id
        self.image = game.stone_img
        self.rect = self.image.get_rect()
        self.rect.x = x
        self.rect.y = y
        self.pos = vec(self.rect.x + self.rect.w / 2.0, self.rect.y + self.rect.h / 2.0)
        self.x = self.rect.x + self.rect.w / 2.0
        self.y = self.rect.y + self.rect.h / 2.0
        self.hit_rect = self.rect
        self.hit_rect.center = self.rect.center

class Obstacle(pg.sprite.Sprite):
    def __init__(self, game, id, x, y, w, h):
        self.groups = game.walls
        pg.sprite.Sprite.__init__(self, self.groups)
        self.game = game
        self.id = id
        self.rect = pg.Rect(x, y, w, h)
        self.x = x + w / 2.0
        self.y = y + h / 2.0
        self.pos = vec(self.x, self.y)
        self.rect.x = x
        self.rect.y = y
        self.width = w
        self.height = h


import nltk
import numpy as np
import logging
from gensim.models.word2vec import Word2Vec
import re
from pyrouge import Rouge155
import os

class TrainWord2vec(object):

    @staticmethod
    def train_word2_vec(documents):
        logging.basicConfig(format='%(asctime)s : %(levelname)s : %(message)s', level=logging.INFO)
        doc_list = []
        for doc in documents:
            tokens = nltk.word_tokenize(doc)
            doc_list.append(tokens)

        model = Word2Vec(doc_list, size=100, window=5, min_count=0, workers=4)
        model.save('./word2vec_model.d2v')
        return model

class Postprocess(object):

    """
    This Class obtains summaries from output results obtained from
    each summarisation system
    """

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

    def get_results(self, salience_scores):
        # Collects and sorts sentence results by score

        salience_scores = list(salience_scores)
        entries = self.pre.test_entries

        for e in entries:
            results = []

            for sent in e.sentences:
                results.append((sent, salience_scores.pop(0)[0]))

            assert(results is not [])

            e.output = sorted(results, key=lambda y: y[1], reverse=True)

    def calculate_rouge(self, alpha):
        # Calculates ROUGE-1 and ROUGE-2 scores between all generated
        # summaries and the gold standard summaries

        r = Rouge155("ROUGE-1.5.5", rouge_args="-e ROUGE-1.5.5/data -a -n 2 -u -c 95 -x -r 1000 -f A -p 0.5 -t 0")

        r.system_dir = 'system_summaries'
        r.model_dir = 'model_summaries'
        r.system_filename_pattern = 'system_sum.(\d+).txt'
        r.model_filename_pattern = 'model_sum.[A-Z].#ID#.txt'

        # Writing model summaries
        list(map(os.unlink, (os.path.join("model_summaries", f) for f in os.listdir("model_summaries"))))
        for x in range(len(self.pre.test_entries)):
            entry = self.pre.test_entries[x]
            model_sum = entry.summary
            sentences = nltk.sent_tokenize(model_sum)
            file = open("model_summaries/model_sum.A." + str(x) + ".txt", "w+")
            for s in sentences:
                file.write(s + "\n")
            file.close()

        # Calculating ROUGE for CNN
        list(map(os.unlink, (os.path.join("system_summaries", f) for f in os.listdir("system_summaries"))))

        for x in range(len(self.pre.test_entries)):
            entry = self.pre.test_entries[x]

            sentences = nltk.sent_tokenize(entry.generated_sum)
            file = open("system_summaries/system_sum." + str(x) + ".txt", "w+")
            for s in sentences:
                file.write(s + "\n")
            file.close()

        results_cnn = r.convert_and_evaluate()

        # Calculating ROUGE for TextRank
        list(map(os.unlink, (os.path.join("system_summaries", f) for f in os.listdir("system_summaries"))))
        r = Rouge155("ROUGE-1.5.5", rouge_args="-e ROUGE-1.5.5/data -a -n 2 -u -c 95 -x -r 1000 -f A -p 0.5 -t 0")

        r.system_dir = 'system_summaries'
        r.model_dir = 'model_summaries'
        r.system_filename_pattern = 'system_sum.(\d+).txt'
        r.model_filename_pattern = 'model_sum.[A-Z].#ID#.txt'

        for x in range(len(self.pre.test_entries)):
            entry = self.pre.test_entries[x]

            sentences = nltk.sent_tokenize(entry.text_rank_sum)
            file = open("system_summaries/system_sum." + str(x) + ".txt", "w+")
            for s in sentences:
                file.write(s + "\n")
            file.close()

        results_tr = r.convert_and_evaluate()

        # Calculating ROUGE for combined extension
        list(map(os.unlink, (os.path.join("system_summaries", f) for f in os.listdir("system_summaries"))))
        r = Rouge155("ROUGE-1.5.5", rouge_args="-e ROUGE-1.5.5/data -a -n 2 -u -c 95 -x -r 1000 -f A -p 0.5 -t 0")

        r.system_dir = 'system_summaries'
        r.model_dir = 'model_summaries'
        r.system_filename_pattern = 'system_sum.(\d+).txt'
        r.model_filename_pattern = 'model_sum.[A-Z].#ID#.txt'

        for x in range(len(self.pre.test_entries)):
            entry = self.pre.test_entries[x]

            sentences = nltk.sent_tokenize(entry.combined_sum)
            file = open("system_summaries/system_sum." + str(x) + ".txt", "w+")
            for s in sentences:
                file.write(s + "\n")
            file.close()

        results_combined = r.convert_and_evaluate()

        # Calculating ROUGE for control case
        list(map(os.unlink, (os.path.join("system_summaries", f) for f in os.listdir("system_summaries"))))
        r = Rouge155("ROUGE-1.5.5", rouge_args="-e ROUGE-1.5.5/data -a -n 2 -u -c 95 -x -r 1000 -f A -p 0.5 -t 0")

        r.system_dir = 'system_summaries'
        r.model_dir = 'model_summaries'
        r.system_filename_pattern = 'system_sum.(\d+).txt'
        r.model_filename_pattern = 'model_sum.[A-Z].#ID#.txt'

        for x in range(len(self.pre.test_entries)):
            entry = self.pre.test_entries[x]

            sentences = nltk.sent_tokenize(entry.control_sum)
            file = open("system_summaries/system_sum." + str(x) + ".txt", "w+")
            for s in sentences:
                file.write(s + "\n")
            file.close()

        results_control = r.convert_and_evaluate()

        print("\nCNN Scores:\n", results_cnn, "\n")
        print("TextRank Scores:\n", results_tr, "\n")
        print("Combined Scores:\n", results_combined, "\n")
        print("Control case scores\n", results_control)

    def get_summary_sentences(self, word_count):
        # Collects first sentences filling the desired word count

        for entry in self.pre.test_entries:
            sentences = entry.output
            count = word_count
            new_output = []
            for tup in sentences:
                length = len(nltk.word_tokenize(tup[0]))
                if count < 0:
                    break
                else:
                    new_output.append(tup)
                    count -= length

            assert(count < 0)

            entry.output = new_output

    def return_summaries(self):
        # Outputs summary to entry object

        for entry in self.pre.test_entries:
            summary = ""
            sents = [tup[0] for tup in entry.output]
            for sent in sents:
                # if re.search('[a-zA-Z0-9]', sent) is not None:
                #     index = None
                #     for i in range(len(sent)):
                #         if sent[i].isalnum():
                #             index = i
                #             break
                #     new_sent = sent[index:]
                #     summary += new_sent + " "
                summary += sent + " "

            assert(len(nltk.word_tokenize(summary)) >= 100)

            entry.generated_sum = summary


__author__ = 'chywoo.park'

import os
import re
import  psutil

def check_file_list(files):
    """
    Check if specified files exist or not in current directory.

    :type files: list
    :param files: File list to check
    :return: File list found
    :rtype: list
    """
    listdir = os.listdir(".")

    file_list = []
    not_exist_list = []

    for f in listdir:
        if os.path.isfile(f):
            file_list.append(f)

    for file in files:
        if file not in file_list:
            not_exist_list.append(file)

    if len(not_exist_list) == 0:
        return None
    else:
        return not_exist_list

def check_dir_list(dirs):
    """
    Check if specified files exist or not in current directory.

    :type dirs: list
    :param dirs: Directory list to check
    :return: File list found
    :rtype: list
    """
    listdir = os.listdir(".")

    file_list = []
    not_exist_list = []

    for f in listdir:
        if os.path.isdir(f):
            file_list.append(f)

    for file in dirs:
        if file not in file_list:
            not_exist_list.append(file)

    if len(not_exist_list) == 0:
        return None
    else:
        return not_exist_list

def grep(pattern, file, trim=False):
    """
    Search pattern in specified file.

    :type trim: bool
    :type file: str
    :type pattern: str
    :param pattern: Regular expression pattern
    :param file: File to find pattern.
    :param trim: Trim result string
    :return: list of found
    :rtype: list
    """
    if file is None or pattern is None:
        return None

    found_list = []

    f = open(file, "r")

    for line in f.readlines():
        if re.findall(r'^.*%s.*?$' % pattern, line, flags=re.M):
            if trim is True:
                line = line.strip()
            found_list.append(line)
    f.close()

    if len(found_list) == 0:
        return None
    else:
        return found_list

def kill(pid):
    """
    Kill process specified by pid paramter

    :param pid: Process ID to kill
    """
    p = psutil.Process(pid)

    try:
        p.kill()
    except Exception:
        pass

def killall(name, params=None):
        """
        Kill process specified by parameters.

        :type name: Process name to kill
        """
        for ps in psutil.process_iter():
            cmdline = ""
            try:
                if ps.name() != name:
                    continue

                if params:
                    cmdline = ps.cmdline()
            except psutil.AccessDenied:
                continue

            ps_found = True

            if params:  # If you want to compare command line
                check_list = []
                if params is list:
                    check_list = params
                elif params is str:
                    check_list = str.split(",")
                else:
                    check_list.append(str(params))

                # Compare command line's parameters
                for item in check_list:
                    ps_found = False

                    for param in cmdline:
                        if param.find(item):
                            ps_found = True
                            break

                    if ps_found is False:   # Process is not found.
                        break

            if ps_found:
                try:
                    ps.kill()
                except Exception:
                    pass


import random

cellSet = set()
validInp = False
while validInp != True:
    print("Please choose dataset size:")
    print("small")
    print("medium")
    print("large")

    userInp = input()

    if userInp == "small":
        size = random.randint(100, 500)
        validInp = True
    elif userInp == "medium":
        size = random.randint(1000, 2500)
        validInp = True
    elif userInp == "large":
        size = random.randint(5000, 10000)
        validInp = True
size = 8313
print(size)
# numValCells = random.randint(0, size*size)

print("Please enter the precentage of non-None cells in the dataset:")
print("(enter a percentage between 0 and 1)")
valPercentage = input()

numValCells = round(float(valPercentage) * (size*size))
f = open("large-0.9-data.txt", "w")
f.write(str(size) + " " + str(size) + " " +
        str(round(random.uniform(-9.99, 10), 2)) + "\n")
numValCells -= 1

while numValCells != 0:
    randRow = random.randint(0, size-1)
    randCol = random.randint(0, size-1)
    if (randRow, randCol) not in cellSet:
        f.write(str(randRow) + " " + str(randCol) + " " +
                str(round(random.uniform(-9.99, 10), 2)) + "\n")
        cellSet.add((randRow, randCol))
        numValCells -= 1
f.close()


"""
Suppose you work for a wildlife conservation organization.
You are working on creating a system to educate the general public
about different animals and get them more interested in conservation.

Create a Tiger class that inherits from the Cat classand has a new coat pattern attribute.

Change the behavior of instances of the Tiger class to include this coat pattern fact when they're printed.

The steps are as follows:

Go to your main.py file.

Define the Tiger class that inherits from the Cat class. Override its initializer and add a coat_pattern attribute with the value "striped".

Override the __str__() method and modify it to include mention of the coat pattern.

At the bottom of the script we have initialized an instance of the Tiger class and called print on the instance, which should display facts about the tiger.

(OUTPUT):

The tiger weighs 310kg, has a lifespan of 26 years and can run at a maximum speed of 65kph. It also has a striped coat.

"""

class Cat:
    def __init__(self, mass, lifespan, speed):
        self.mass_in_kg = mass
        self.lifespan_in_years = lifespan
        self.speed_in_kph = speed

    def vocalize(self):
        print("Chuff")

    def __str__(self):
        return f"The {type(self).__name__.lower()} "\
            f"weighs {self.mass_in_kg}kg,"\
            f" has a lifespan of {self.lifespan_in_years} years and "\
            f"can run at a maximum speed of {self.speed_in_kph}kph."

# Write your Tiger class here

class Tiger(Cat):

    def __init__(self, mass, lifespan, speed, coat):
        self.mass_in_kg = mass
        self.lifespan_in_years = lifespan
        self.speed_in_kph = speed
        self.coat_pattern = coat

    def __str__(self):
        return f"The {type(self).__name__.lower()} "\
            f"weighs {self.mass_in_kg}kg,"\
            f" has a lifespan of {self.lifespan_in_years} years and "\
            f"can run at a maximum speed of {self.speed_in_kph}kph."\
            f" It also has a {self.coat_pattern} coat"

"""
# This code is used to test your class

if __name__ == '__main__':
    tiger = Tiger(310, 26, 65)
    print(tiger)

class MovingSprite(Sprite):

    def __init__(self, image, speed):

        self.speed = speed
        super().__init__(image)

"""

tiger = Tiger(310, 2, 65, "striped")
print(tiger.__str__())


#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 2017/1/11 下午1:38
# @Author  : Rain
# @Desc    : 服务项类别接口
# @File    : service_category_resource.py

from app.models import ServiceItemCategory, ServiceItemCategorySchema, Const, PaginationSchema
from flask_restful import Resource, reqparse
from app.utils.utils import merge, safe_session
from app import admin_manager, db
from flask import current_app
from marshmallow import fields

parser = reqparse.RequestParser()
parser.add_argument('name', type=str, location='json', store_missing=False)
parser.add_argument('description', type=str, location='json', store_missing=False)

search_parser = reqparse.RequestParser()
search_parser.add_argument('page', type=int, default=1, location='args', store_missing=True)

class ServiceCategoryResource(Resource):
    method_decorators = [admin_manager.login_required()]

    def get(self, sid):
        sc = ServiceItemCategory.query.get_or_404(sid)

        schema = ServiceItemCategorySchema()
        result = schema.dump(sc).data

        return {Const.RESULT_KEY: result}, Const.STATUS_OK

    def post(self, sid):

        sc = ServiceItemCategory.query.get_or_404(sid)
        args = parser.parse_args()
        merge(sc, args)

        with safe_session(db):
            db.session.add(sc)

        return {Const.MESSAGE_KEY: '服务包类别修改成功'}, Const.STATUS_OK

class ServiceCategoryListResource(Resource):
    method_decorators = [admin_manager.login_required()]

    def get(self):
        args = search_parser.parse_args()
        page = args.get('page')
        per_page = current_app.config['ITEM_COUNT_PER_PAGE']

        pagination = ServiceItemCategory.query.paginate(page, per_page=per_page, error_out=False)

        schema = PaginationSchema()
        schema.declared_fields['items'] = fields.Nested(ServiceItemCategorySchema, many=True)

        data = schema.dump(pagination).data

        return {Const.RESULT_KEY: data}, Const.STATUS_OK

    def post(self):
        sc = ServiceItemCategory()
        args = parser.parse_args()
        merge(sc, args)

        with safe_session(db):
            db.session.add(sc)

        return {Const.MESSAGE_KEY: '服务包类别创建成功'}, Const.STATUS_OK


import os

import numpy as np
import xarray as xr
from mpas_tools.io import write_netcdf
from pyremap import LatLonGridDescriptor, MpasCellMeshDescriptor, Remapper

from compass.io import symlink
from compass.ocean.tests.global_ocean.files_for_e3sm.files_for_e3sm_step import (  # noqa: E501
    FilesForE3SMStep,
)

class RemapIcebergClimatology(FilesForE3SMStep):
    """
    A step for for remapping iceberg freshwater fluxes from a climatology from
    Merino et al. (2016) to the current MPAS mesh
    """
    def __init__(self, test_case):
        """
        Create a new step

        Parameters
        ----------
        test_case : compass.TestCase
            The test case this step belongs to
        """
        super().__init__(test_case,
                         name='remap_iceberg_climatology',
                         ntasks=512, min_tasks=1)

        self.add_input_file(
            filename='Iceberg_Interannual_Merino.nc',
            target='Iceberg_Interannual_Merino.nc',
            database='initial_condition_database')

        self.add_output_file(filename='Iceberg_Climatology_Merino_MPAS.nc')

    def run(self):
        """
        Run this step of the test case
        """
        super().run()
        logger = self.logger
        config = self.config
        ntasks = self.ntasks

        in_filename = 'Iceberg_Interannual_Merino.nc'

        prefix = 'Iceberg_Climatology_Merino'
        suffix = f'{self.mesh_short_name}.{self.creation_date}'

        remapped_filename = f'{prefix}_MPAS.nc'
        dest_filename = f'{prefix}.{suffix}.nc'

        parallel_executable = config.get('parallel', 'parallel_executable')

        mesh_filename = 'restart.nc'
        mesh_short_name = self.mesh_short_name
        if self.with_ice_shelf_cavities:
            land_ice_mask_filename = 'initial_state.nc'
        else:
            land_ice_mask_filename = None

        remap_iceberg_climo(in_filename, mesh_filename, mesh_short_name,
                            land_ice_mask_filename, remapped_filename,
                            logger=logger, mpi_tasks=ntasks,
                            parallel_executable=parallel_executable)

        symlink(
            os.path.abspath(remapped_filename),
            f'{self.seaice_inputdata_dir}/{dest_filename}')

def remap_iceberg_climo(in_filename, mesh_filename, mesh_name,
                        land_ice_mask_filename, out_filename, logger,
                        mapping_directory='.', method='conserve', mpi_tasks=1,
                        parallel_executable=None):
    """
    Remap iceberg freshwater fluxes from a climatology from
    Merino et al. (2016) to the current MPAS mesh

    Parameters
    ----------
    in_filename : str
        The original Merino et al. iceberg freshwater flux climatology file

    mesh_filename : str
        The MPAS mesh

    mesh_name : str
        The name of the mesh (e.g. oEC60to30wISC), used in the name of the
        mapping file

    land_ice_mask_filename : str
        A file containing the variable ``landIceMask`` on the MPAS mesh

    out_filename : str
        The iceberg freshwater fluxes remapped to the MPAS mesh

    logger : logging.Logger
        A logger for output from the step

    mapping_directory : str
        The directory where the mapping file should be stored (if it is to be
        computed) or where it already exists (if not)

    method : {'bilinear', 'neareststod', 'conserve'}, optional
        The method of interpolation used, see documentation for
        `ESMF_RegridWeightGen` for details.

    mpi_tasks : int, optional
        The number of MPI tasks to use to compute the mapping file

    parallel_executable : {'srun', 'mpirun'}, optional
        The name of the parallel executable to use to launch ESMF tools.
        But default, 'mpirun' from the conda environment is used
    """

    name, ext = os.path.splitext(in_filename)
    monotonic_filename = f'{name}_monotonic_lon{ext}'

    ds = xr.open_dataset(in_filename)
    # latitude and longitude are actually 1D
    ds['lon'] = ds.longitude.isel(y=0)
    ds['lat'] = ds.latitude.isel(x=0)
    ds = ds.drop_vars(['latitude', 'longitude'])
    ds = ds.rename(dict(x='lon', y='lat'))
    # the first and last longitudes are zeroed out!!!
    ds = ds.isel(lon=slice(1, ds.sizes['lon'] - 1))

    lon_indices = np.argsort(ds.lon)
    # make sure longitudes are unique
    lon = ds.lon.isel(lon=lon_indices).values
    lon, unique_indices = np.unique(lon, return_index=True)
    lon_indices = lon_indices[unique_indices]
    ds = ds.isel(lon=lon_indices)

    ds.to_netcdf(monotonic_filename)
    logger.info('Creating the source grid descriptor...')
    src_descriptor = LatLonGridDescriptor.read(fileName=monotonic_filename)
    src_mesh_name = src_descriptor.meshName

    logger.info('Creating the destination MPAS mesh descriptor...')
    dst_descriptor = MpasCellMeshDescriptor(mesh_filename, mesh_name)

    mapping_filename = \
        f'{mapping_directory}/map_{src_mesh_name}_to_{mesh_name}_{method}.nc'

    logger.info(f'Creating the mapping file {mapping_filename}...')
    remapper = Remapper(src_descriptor, dst_descriptor, mapping_filename)

    remapper.build_mapping_file(method=method, mpiTasks=mpi_tasks,
                                tempdir=mapping_directory, logger=logger,
                                esmf_parallel_exec=parallel_executable)

    logger.info('Remapping...')
    name, ext = os.path.splitext(out_filename)
    remap_filename = f'{name}_after_remap{ext}'
    remapper.remap_file(inFileName=monotonic_filename,
                        outFileName=remap_filename,
                        logger=logger)

    ds = xr.open_dataset(remap_filename)
    logger.info('Removing lat/lon vertex variables...')
    drop = [var for var in ds if 'nv' in ds[var].dims]
    ds = ds.drop_vars(drop)
    logger.info('Renaming dimensions and variables...')
    rename = dict(ncol='nCells',
                  month='Time',
                  Icb_flux='bergFreshwaterFluxData')
    ds = ds.rename(rename)
    logger.info('Adding xtime...')
    xtime = []
    for time_index in range(ds.sizes['Time']):
        time_str = f'0000-{time_index + 1:02d}-15_00:00:00'
        xtime.append(time_str)
    ds['xtime'] = ('Time', np.array(xtime, 'S64'))

    logger.info('Fix masking...')
    field = 'bergFreshwaterFluxData'
    # zero out the field where it's currently NaN
    ds[field] = ds[field].where(ds[field].notnull(), 0.)

    if land_ice_mask_filename is not None:
        logger.info('Masking out regions under ice shelves...')
        ds_mask = xr.open_dataset(land_ice_mask_filename)
        no_land_ice_mask = 1 - ds_mask.landIceMask
        if 'Time' in no_land_ice_mask.dims:
            no_land_ice_mask = no_land_ice_mask.isel(Time=0, drop=True)

        #  mask only to regions without land ice
        ds[field] = ds[field] * no_land_ice_mask

    logger.info(f'Writing to {out_filename}...')
    write_netcdf(ds, out_filename)

    logger.info('done.')


from django import forms

from .models import Student
# 初步实现如下  由于大部分相等，故采用简单方法
# class StudentForm(forms.Form):
#     SEX_ITEMS = [
#         (1, '男'),
#         (2, '女'),
#         (3, '未知')
#     ]
#     STAUTS_ITEMS = [
#         (0, '申请中'),
#         (1, '已通过'),
#         (2, '已拒绝'),
#     ]
#
#     name = forms.CharField(max_length=128, verbose_name='姓名')
#     sex = forms.IntegerField(choices=SEX_ITEMS, verbose_name='性别')
#     profession = forms.CharField(max_length=128, verbose_name='职业')
#     email = forms.EmailField(max_length=128, verbose_name='邮箱')
#     qq = forms.CharField(max_length=128, verbose_name='QQ')
#     phone = forms.CharField(max_length=128, verbose_name='手机')
#
#     status = forms.IntegerField(choices=STAUTS_ITEMS, default=0, verbose_name='审核状态')
#     created_time = forms.DateTimeField(auto_now_add=True, editable=False, verbose_name='创建时间')

class StudentForm(forms.ModelForm):

    # def clean_qq(self):
    #     # 把qq更改类型
    #     clean_data = self.cleaned_data['qq']
    #     if not clean_data.isdight():                        # 设置格式验证，可以使re
    #         raise forms.ValidationError('必须全部是数字！')
    #
    #     return int(clean_data)

    class Meta:
        model = Student
        fields = (
            'name', 'sex', 'profession', 'email', 'qq', 'phone', 'status'
        )


import logging
import logging.handlers
import os
from datetime import timedelta
from datetime import date
from datetime import datetime
from decimal import Decimal

LOG_LEVELS = {
  'INFO' : 20,
  'DEBUG' : 10,
  'WARNING' : 30,
  'ERROR' : 40,
  'CRITICAL' : 50
}

log_level =  LOG_LEVELS.get(os.environ.get("LOG_LEVEL","INFO"))
logger_filename = os.environ.get("LOG_FILE_NAME", None)
logger = None

def init_log():
  global logger

  if not logger:
    streamHandler = logging.StreamHandler()
    streamHandler.setLevel(log_level)
    formatter = logging.Formatter('[%(levelname)s] - %(asctime)s : %(message)s', datefmt='%Y/%m/%d %H:%M:%S')
    streamHandler.setFormatter(formatter)

    logger = logging.getLogger()
    logger.addHandler(streamHandler)

    if logger_filename is not None:
      f_handler = logging.handlers.TimedRotatingFileHandler(f'./log/{logger_filename}.log', when='midnight', backupCount=10)
      f_handler.setFormatter(formatter)
      f_handler.setLevel(log_level)

      logger.addHandler(f_handler)

    logger.setLevel(log_level)

  return logger


import asyncio
import time

async def say_after(delay, what):
    await asyncio.sleep(delay)
    return f"{what} - {delay}"

async def main():

    print(f"started at {time.strftime('%X')}")

    ret1 = await asyncio.gather(say_after(1,'hello'), say_after(2,'world'))

    print(ret1)

    print(f"finished at {time.strftime('%X')}")

asyncio.run(main())


class ListNode:
    def __init__(self, val=0, next=None):
        self.val = val
        self.next = next

class Solution:
    def reverseBetween(self, head, left, right):
        dummy = ListNode(0)
        dummy.next = head
        pre = dummy
        for i in range(left - 1):
            pre = pre.next
        tail = pre
        pree=pre
        for i in range(right - left + 1):
            tail = tail.next

        after = tail.next
        start = pre.next
        cur = start

        while pre != tail:
            next=cur.next
            cur.next = pre
            pre = cur
            cur = next
        start.next = after
        pree.next = tail
        return dummy.next


from keys import *
from get_data import *

import sqlite3
from datetime import datetime, timedelta
import time
from binance.client import Client

client = Client(api_key, api_secret)

def build_db(symbols):
    conn = sqlite3.connect(database_path)
    c = conn.cursor()
    for symbol in symbols:
        try:
            c.execute("CREATE TABLE IF NOT EXISTS '{}' (Open_time DATETIME PRIMARY KEY, Open FLOAT, High FLOAT, Low FLOAT, Close FLOAT, Volume FLOAT, Close_time DATETIME, Quote_asset_volume FLOAT, Number_of_trades INT, Taker_buy_base_asset_volume FLOAT, Taker_buy_quote_asset_volume_FLOAT, Ignore INT)".format(symbol))
        except Exception as e:
            print("Error creating table for", symbol,e)
        print(symbol)
    conn.commit()
    conn.close()

def insert_data(db, symbols, interval, start_date, end_date=None):
    conn = sqlite3.connect(db)
    c = conn.cursor()
    for symbol in symbols:
        start_time = time.time()
        data = get_kline_data(symbol, interval, start_date, end_date)
        for row in data:
            try:
                c.execute("insert into '{}' values (?,?,?,?,?,?,?,?,?,?,?,?)".format(symbol), row)
            except Exception as e:
                print("Error Inserting", symbol, "Err:", e)
        end_time = time.time()
        print("Inserted", symbol, "took", round(end_time - start_time, 2),"seconds.")
    conn.commit()
    conn.close()

def drop_tables(db, symbols):
    conn = sqlite3.connect(db)
    c = conn.cursor()
    for symbol in symbols:
        start_time = time.time()
        try:
            c.execute("drop table '{}'".format(symbol))
        except Exception as e:
            print("Error Inserting", symbol, "Err:", e)
        end_time = time.time()
        print("Dropped table", symbol, "took", round(end_time - start_time, 2),"seconds.")
    conn.commit()
    conn.close()

#print(get_all_symbols())
#drop_tables(database_path, get_all_symbols())
#print(len(get_all_symbols()))
#build_db(["BTCUSDT", "ETHUSDT", "BCHUSDT", "LTCUSDT", "XRPUSDT"])
#insert_data(database_path, ["BTCUSDT", "ETHUSDT"], client.KLINE_INTERVAL_1MINUTE, UTC_to_milliseconds("2020-01-01 00:00:00"), UTC_to_milliseconds("2020-01-30 00:00:00"))


from django.urls import path

from . import views

urlpatterns = [
    path('', views.index, name='index'),
    path('select_room/', views.select_room, name='select_room'),
    path('join/', views.join_room, name='join'),
    path('leave/', views.leave_room, name='leave'),
]


from cpu import CPU
import json

# Get instructions and input data
def read_config_file(config_file):
    with open (config_file, 'r') as file:
        config_data = json.load(file)
    return config_data

config_data = read_config_file('CPU_sim_project/config.json')
instruction_input_file = config_data['instruction_input_file']
data_input_file = config_data['data_input_file']

# Generate instructions
def fetch_instructions():
    with open(instruction_input_file, 'r') as instruction_file:
        instructions = instruction_file.readlines()
        instructions = [s.strip() for s in instructions]
    return instructions

# Generate list of data inputs to initialize the memory bus from.
def fetch_data():
    with open(data_input_file, 'r') as data_file:
        data = data_file.readlines()
        data = [s.strip() for s in data]
    return data

# Method to write each value from data_input file to CPU's memory bus
def initialize_memory_bus(cpu):
    data_loaded = fetch_data()
    for data in data_loaded:
        data_parsed = data.split(",")
        address, value = data_parsed[0], data_parsed[1]
        cpu.write_memory_bus(address, value)

# Method to send instructions line-by-line to CPU object
def send_instructions_to_cpu(cpu):
    instructions_loaded = fetch_instructions()
    for instruction in instructions_loaded:
        cpu.parse_instruction(instruction)

# Start of Python script to run the CPU simulator
def run_cpu_simulator():
    my_cpu = CPU()
    print("---------------------------------------------------")
    print("Welcome to the Python CPU Simulator!")
    print("---------------------------------------------------")
    print("Initializing Memory Bus from data input file...")
    initialize_memory_bus(my_cpu)
    print("Memory Bus successfully initialized")
    print("---------------------------------------------------")
    print("Sending instructions to CPU...")
    send_instructions_to_cpu(my_cpu)
    print("---------------------------------------------------")
    print("Terminating CPU Processing...")

run_cpu_simulator()


# 라이브러리 임포트
import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
import torch.utils.data as data_utils
import os, sys
import pandas as pd
import numpy as np

from sklearn.model_selection import train_test_split
from scaling import scaled_into_trainset
from torchvision import transforms

# 데이터 불러오기

os.chdir('/Users/choeunsol/Python/PAINS 방중 프로젝트/최종 분석 데이터셋/인풋 데이터')
data = pd.read_csv('MLB 메이저레벨 분석용 데이터셋.csv')
data.head()

# 데이터 정규화

y_pd = data_pre_dnn.loc[:,'field.value']
X_pd_c = list(data_pre_dnn.columns.difference(['field.value', 'options_No', 'options_Yes']))
X_pd = data_pre_dnn[X_pd_c]

x_train_pd, x_test_pd, y_train_pd, y_test_pd = train_test_split(X_pd, y_pd, test_size=0.2, random_state = 0)

from sklearn.preprocessing import StandardScaler

scaler_nn = StandardScaler()

# x 스케일링
scaling_nn_x_train = x_train_pd.loc[:, ['salary']]
scaling_nn_x_test = x_test_pd.loc[:, ['salary']]

scaler_nn.fit(scaling_nn_x_train)
scaling_nn_x_test = x_test_pd.loc[:, ['salary']]

trainscaled_x = scaler_nn.transform(scaling_nn_x_train)
testscaled_x = scaler_nn.transform(scaling_nn_x_test)

# y 스케일링
train_y_array = np.array(y_train_pd)
train_y_array = train_y_array.reshape(-1, 1)

test_y_array = np.array(y_test_pd)
test_y_array = test_y_array.reshape(-1, 1)

scaler = scaler_nn.fit(train_y_array)

trainscaled_y = scaler.transform(train_y_array)
testscaled_y = scaler.transform(test_y_array)

# 데이터에 덧씌우기
x_train_pd.loc[:, 'salary'], x_test_pd.loc[:, 'salary'] = trainscaled_x, testscaled_x
y_train_pd[:], y_test_pd[:] = trainscaled_y.reshape(-1), testscaled_y.reshape(-1)

## 모델링

class DNN(nn.Module):
    def __init__(self):
        super().__init__()
        self.linear_stack = nn.Sequential(nn.Linear(16, 300, bias=True),
                                          nn.ELU(),
                                          nn.Linear(300, 100, bias = True),
                                          nn.ELU(),
                                          nn.Linear(100, 50, bias = True),
                                          nn.ELU(),
                                          nn.Linear(50, 30, bias = True),
                                          nn.ELU(),
                                          nn.Linear(30, 20, bias = True),
                                          nn.ELU(),
                                          nn.Linear(20, 1, bias = True))

    def forward(self, x):
        out = self.linear_stack(x)
        return out


# -*-coding:utf-8 -*-
u"""
:创建时间: 2022/4/13 0:20
:作者: 苍之幻灵
:我的主页: https://cpcgskill.com
:QQ: 2921251087
:爱发电: https://afdian.net/@Phantom_of_the_Cang
:aboutcg: https://www.aboutcg.org/teacher/54335
:bilibili: https://space.bilibili.com/351598127

"""
from __future__ import unicode_literals, print_function, division
import pyeal.code.unparse as astunparse

with open('./astunparse_test_file.py', 'rb') as f:
    test_code = f.read()

def test():
    tree = astunparse.parser(test_code)
    code = astunparse.unparse(tree)
    print(code)

if __name__ == '__main__':
    test()


import sqlite3

class FDateBase:
    def __init__(self, db):
        self.__db = db
        self.__cur = db.cursor()

    def get_menu(self):
        sql = "SELECT * FROM mainmenu"
        try:
            self.__cur.execute(sql)
            res = self.__cur.fetchall()
            if res:
                return res
        except IOError:
            print("Ошибка чтения из БД")
        return []

    def add_kurs(self, title, price, text):
        try:
            self.__cur.execute("INSERT INTO kurs VALUES(NULL, ?, ?, ?)", (title, price, text))
            self.__db.commit()
        except sqlite3.Error as e:
            print("Ошибка добаления курс в БД" + str(e))
            return False
        return True

    def get_kurs(self, kurs_id):
        try:
            self.__cur.execute(f"SELECT title, price, text FROM kurs WHERE id = {kurs_id} LIMIT 1")
            res = self.__cur.fetchone()
            if res:
                return res
        except sqlite3.Error as e:
            print("Ошибка получения курса из БД" + str(e))

        return False, False, False

    def get_kurs_annonce(self):
        try:
            self.__cur.execute(f"SELECT id, title, text, price FROM kurs")
            res = self.__cur.fetchall
            if res:
                return res
        except sqlite3.Error as e:
            print("Ошибка получения курса из БД" + str(e))

        return []


import numpy as np
import pandas as pd
from matplotlib import pyplot as plt
from matplotlib.colors import LogNorm
from sklearn import metrics
import matplotlib.patches as mpatches
from sklearn.ensemble import RandomForestRegressor
from sklearn.ensemble import ExtraTreesRegressor
from sklearn.preprocessing import StandardScaler
from sklearn.preprocessing import normalize
from sklearn.model_selection import cross_val_score,KFold,cross_validate,train_test_split,cross_val_predict

def GetFeaturesImportance(RFR, feature_list):
    # get numerical feature importances
    importances = list(RFR.feature_importances_)

    # list of tuples with variable and importance
    feature_importances = [(feature, round(importance, 3)) for feature, importance in zip(feature_list, importances)]

    # sort the feature importances by most important first
    feature_importances = sorted(feature_importances, key = lambda x: x[1], reverse = True)

    return feature_importances

def OutputImportanceRank(feature_importances, index=5):
    feature_list_sorted = []
    for i, pair in enumerate(feature_importances):
        print('Variable: {:30} Importance: {}'.format(*pair))
        feature_list_sorted.append(pair[0])
        if i >= index:
            print(feature_list_sorted)
            break

def PlotImportanceRank(feature_importances):
    plt.rcParams['figure.figsize'] = (6.0, 6.0)
    plt.rc('font', family='Times New Roman')
    plt.rcParams["axes.labelweight"] = "bold"
    plt.rcParams["font.weight"] = "bold"
    fig, ax = plt.subplots(1, 1, figsize=(10, 10))
    for i, pair in enumerate(feature_importances):
        if i >= 10:
            break
        rects = ax.bar(*pair, color='lightblue')
        for rect in rects:
            height = rect.get_height()
            ax.text(rect.get_x() + rect.get_width() / 2, height, str(height),
                     size=24, ha='center', va='bottom', rotation=45, weight='regular')
    # ==========================================================
    ax.set_ylim(0, 0.6)
    ax.set_yticks(np.arange(0, 0.6, 0.1))
    ax.set_ylabel("Relative Importance", fontsize=28)
    # ax.tick_params(labelsize=18)
    for tick in ax.get_yticklabels():
        tick.set_fontsize(24)         # 设置y轴坐标轴刻度大小
    for tick in ax.get_xticklabels():
        tick.set_rotation(45)
        tick.set_fontsize(18)         # 设置x轴坐标轴刻度大小
    plt.tight_layout()
    plt.savefig("./rank.png", bbox_inches='tight', dpi=480)
    plt.show()

def PlotCrossValPredict(RFR, X_total, y_total):
    predicted = cross_val_predict(RFR, X_total, y_total, cv=kfold)

    fig, ax = plt.subplots()
    ax.scatter(y_total, predicted, edgecolors=(0, 0, 0))
    ax.plot([y_total.min(), y_total.max()], [y_total.min(), y_total.max()], "k--", lw=4)
    ax.set_xlabel("Measured U (eV)")
    ax.set_ylabel("Predicted U (eV)")
    plt.show()

def AdjustEstimator(X_total, y_total):
    X_train, X_test, y_train, y_test = train_test_split(X_total, y_total, test_size=0.3, shuffle=True)

    estimators_list = list(range(8,100))
    mae_list = []
    rmse_list = []
    r2_list = []
    for estimator in estimators_list:
        RFR=RandomForestRegressor(random_state=0,n_jobs=8,n_estimators=estimator)
        RFR.fit(X_train, y_train)
        predictions = RFR.predict(X_test)
        mae = metrics.mean_absolute_error(y_test, predictions)
        rmse = np.sqrt(metrics.mean_squared_error(y_test, predictions))
        r2 = metrics.r2_score(y_test, predictions)
        mae_list.append(mae)
        rmse_list.append(rmse)
        r2_list.append(r2)
    plt.plot(estimators_list, mae_list, label="MAE (eV)")
    plt.plot(estimators_list, r2_list, label="$R^{2}$")
    plt.plot(estimators_list, rmse_list, label="RMSE (eV)")
    plt.legend()
    plt.show()

def Plot(RFR, X_total, y_total):
    RFR.fit(X_total, y_total)
    #========================= plot the results =====================================
    # predictions = RFR.predict(X_total)
    predictions = RFR.oob_prediction_

    # plot the predictions against true values
    fig, ax = plt.subplots()

    # ax.hist2d(y_total, predictions, norm=LogNorm(), bins=64, cmap='Blues', alpha=0.9)
    ax.plot(y_total, predictions, "bo")

    ax.set_xlim(ax.get_ylim())
    ax.set_ylim(ax.get_xlim())

    mae = metrics.mean_absolute_error(y_total, predictions)
    rmse = np.sqrt(metrics.mean_squared_error(y_total, predictions))
    r2 = metrics.r2_score(y_total, predictions)
    ax.text(0.75, 0.1, 'MAE: {:.2f} eV \nRMSE: {:.2f} eV \n$R^2$: {:.2f}'.format(mae, rmse, r2),
            transform=ax.transAxes,
        bbox={'facecolor': 'w', 'edgecolor': 'k'})

    ax.plot(ax.get_xlim(), ax.get_xlim(), 'k--')
    ax.fill_between(ax.get_xlim(),
                    np.array(ax.get_ylim())-0.5,
                    np.array(ax.get_ylim())+0.5,
                    facecolor='c',
                    alpha=0.6,
                    label="error < 0.5 eV")

    ax.set_xlabel('DFT $U$ (eV)')
    ax.set_ylabel('ML $U$ (eV)')

    fig.tight_layout()
    plt.legend()
    plt.show()

# =====================read the raw data===============
data=pd.read_csv('./MLDatasets.csv')         # Read the data which contains descriptors and targets
X_total=data.iloc[:, 6:-1]                   # Select the feature columns
feature_list = list(X_total.columns)
X_total = data[feature_list]
S=StandardScaler()
X_total=S.fit_transform(X_total)
y_total=data['target']
# ==============set the picture type=================
plt.rcParams['figure.figsize'] = (6.0, 6.0)
plt.rc('font', family='Times New Roman')
plt.rcParams["axes.labelweight"] = "bold"
plt.rcParams["font.weight"] = "bold"
# ==============take all the data as the training set=======
RFR=RandomForestRegressor(random_state=0,n_jobs=8,n_estimators=64, oob_score=True)
Plot(RFR, X_total, y_total)
feature_importances = GetFeaturesImportance(RFR, feature_list)
PlotImportanceRank(feature_importances)
OutputImportanceRank(feature_importances, index=9)
quit()
#===================== save predictions ===================
# pred = pd.DataFrame(data=[data["filepath"],
#                     data["structures"],
#                     y_total,
#                     RFR.oob_prediction_,
#                     data["observation"]],
#                     index=["filepath", "structures", "target", "pred", "observation"]).T
# pred.to_csv("./id_pred.csv")
# quit()
# #=============================KFold training and test====================================
n_splits = 5
kfold=KFold(n_splits=n_splits, shuffle=True, random_state=242)   # random selection
model_list=[RFR]
model_name=['RFR']
score_list=['r2','neg_mean_absolute_error','neg_mean_squared_error']
for i in range(len(model_list)):
    s_list=[]
    ten_fold=pd.DataFrame()
    ten_fold['n']=range(1, n_splits+1)
    for score in score_list:
        #s=cross_val_score(model_list[i],X_total,y_total,scoring=score,cv=kfold,n_jobs=8)
        s=cross_validate(model_list[i],X_total,y_total,scoring=score,cv=kfold,n_jobs=8,return_train_score=True,
                        return_estimator=True)

        if score=='r2':
            ten_fold['R2_test']=s['test_score']
            ten_fold['R2_train']=s['train_score']
        elif score=='neg_mean_absolute_error':
            ten_fold['MAE_test']=[-i for i in s['test_score']]
            ten_fold['MAE_train']=[-i for i in s['train_score']]
        else:
            ten_fold['MSE_test']=[-i for i in s['test_score']]
            ten_fold['MSE_train']=[-i for i in s['train_score']]
    ten_fold.to_csv(model_name[i]+'withNormalize_5fold.csv')
    #===========================================================================
    for estimator in s['estimator']:
        feature_importances = GetFeaturesImportance(estimator, feature_list)
        PlotImportanceRank(feature_importances)
        OutputImportanceRank(feature_importances)
        # print(estimator.oob_score_)
        print("=====================================================")
#==================================================================================
# PlotCrossValPredict(RFR, X_total, y_total)


'''Created on 21 March, 2017
@author:   Robert Frusina
Pledge:    I pledge on my honor that I have abided by the stevens honor system

CS115 - Hw 7
'''

FullAdder = { ('0','0','0') : ('0','0'),
('0','0','1') : ('1','0'),
('0','1','0') : ('1','0'),
('0','1','1') : ('0','1'),
('1','0','0') : ('1','0'),
('1','0','1') : ('0','1'),
('1','1','0') : ('0','1'),
('1','1','1') : ('1','1') }

def numToBaseB(N, B):
    '''converts a number N to binary from its specific base B'''
    add = N%B
    if N <= 1:
        return str(N)
    else:
        return str(numToBaseB(N//B,B))+ str(add)

print (numToBaseB(4, 2))
print (numToBaseB(4, 3))

def baseBToNum(S, B):
    '''opposite function of numToBase... converts binary to the respective value of your choice of base'''
    if S == '':
        return 0
    return int(S[0]) * (B **(len(S) - 1)) + baseBToNum(S[1:], B)

print (baseBToNum("11", 2))
print (baseBToNum("11", 3))

def baseToBase(B1, B2, SinB1):
    '''this function takes in a number in the first base and converts it to the same number in the second base'''
    if B1 == '' or B2 == '':
        return ''
    return numToBaseB(baseBToNum(SinB1, B1), B2)

print (baseToBase(2, 10, "11"))
print (baseToBase(10, 2, "3"))

def add(S, T):
    '''converts numbers to binary and adds them up.'''
    if S == '' and T == '' :
        return str(0)
    M = numToBaseB(baseBToNum(S, 2) + baseBToNum(T, 2), 2)
    return M

print (add('11','01'))
print (add("110", "011"))

def addB(S, T):
    '''same thing as add...other thans the fact that there is no conversion '''
    def add(S, T, C):
        if S == "" and T == "" and C == "0":
            return ""
        elif S == "" and T == "" and C == "1":
            return "1"
        elif S == "":
            a = '0'
            b = T[-1]
            c = C[0]
            ans, co = FullAdder[(a,b,c)]
            return add(S, T[:-1], co) + ans
        elif T == "":
            a = S[-1]
            b = '0'
            c = C[0]
            ans, co = FullAdder[(a,b,c)]
            return add(S[:-1], T, co) + ans

        a = S[-1]
        b = T[-1]
        c = C[0]
        ans, co = FullAdder[(a,b,c)]
        return add(S[:-1], T[:-1], co) + ans
    return add(S, T, '0')\

print (addB("11", "1"))
print (addB("011", "100"))


import numpy as np
from types import LambdaType, FunctionType
from control import lqr

import abstract_controller
import errors

class LQRParameters(abstract_controller.ControllerParameters):
    def __init__(self, Q: np.ndarray, R: np.ndarray, N=None, S=None):
        super().__init__(controller_type="LQ")
        self.Q = Q
        self.R = R
        self.N = N
        self.S = S
        self.check()

    def check(self):
        if self.Q.shape[0] != self.Q.shape[1]:
            raise errors.WrongParametersError("Q should be a square matrix!")
        if len(self.R.shape) == 2 and self.R.shape[0] != self.R.shape[1]:
            raise errors.WrongParametersError("R should be a square matrix!")
        if self.N is not None:
            if self.Q.shape[1] != self.N.shape[0]:
                raise errors.WrongParametersError("N matrix has wrong shape!")
            if self.R.shape[1] != self.N.shape[0]:
                raise errors.WrongParametersError("N matrix has wrong shape!")

class LQRController(abstract_controller.Controller):
    def __init__(self, parameters: LQRParameters):
        super().__init__(parameters=parameters)
        self.K = None
        self.S = None
        self.E = None
        self.x0 = None

    def tune_controller(self, A, B, x0=np.array([0, 0, 0])) -> None:
        self.x0 = x0
        self.K, self.S, self.E = lqr(A, B, self.parameters.Q, self.parameters.R)

    def get_controller(self) -> [LambdaType | FunctionType]:
        if self.K is None:
            raise errors.WrongSequenceError("Before getting a controller it is necessary to fine-tune it!")
        else:
            return lambda x: -self.K @ (x-self.x0)


# -*- coding: utf-8 -*-
import atexit
import sys
import os.path
import datetime
import smtplib
import threading
from email import encoders
from email.utils import formatdate
from email.mime.base import MIMEBase
from email.header import Header
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText

#Gmailアカウント
ADDRESS = "hogehoge@gmail.com"
PASSWARD = "hoge0063hoge0063"

#SMTPサーバの設定(Gmail用)
SMTP = "smtp.gmail.com"
PORT = 587

class SendMail():

	def __init__(self,add,sub,body):
		self.add = add
		self.sub = sub
		self.body = body

		self.thread = threading.Thread(target = self.send)
		self.thread.start()

	def create_message(self, from_addr, to_addr, subject, body, mime=None, attach_file=None):

		"""
		メッセージを作成する
		@:param from_addr 差出人
		@:param to_addr 宛先
		@:param subject 件名
		@:param body 本文
		@:param mime MIME
		@:param attach_file 添付ファイル
		@:return メッセージ
		"""
		msg = MIMEMultipart()
		msg["From"] = from_addr
		msg["To"] = to_addr
		msg["Date"] = formatdate()
		msg["Subject"] = Header(subject, "utf-8")
		body = MIMEText(body,"plain","utf-8")
		msg.attach(body)
		# 添付ファイル
		#if mime != None and attach_file != None:
		#    attachment = MIMEBase(mime['type'],mime['subtype'])
		#    file = open(attach_file['path'])
		#    attachment.set_payload(file.read())
		#    file.close()
		#    encoders.encode_base64(attachment)
		#    msg.attach(attachment)
		#    attachment.add_header("Content-Disposition","attachment", filename=attach_file['name'])

		return msg

	def send_gmail(self, from_addr, to_addrs, msg):
		"""
		メールを送信する
		@:param from_addr 差出人
		@:param to_addr 宛先(list)
		@:param msg メッセージ
		"""
		smtpobj = smtplib.SMTP(SMTP, PORT)
		smtpobj.ehlo()
		smtpobj.starttls()
		smtpobj.ehlo()
		smtpobj.login(ADDRESS, PASSWARD)
		smtpobj.sendmail(from_addr, to_addrs, msg.as_string())
		smtpobj.close()

	def send(self):
		msg = self.create_message(ADDRESS, self.add, self.sub, self.body)
		self.send_gmail(ADDRESS, [self.add], msg)

def send(add, sub, body):
	SendMail(add, sub, body)

if __name__ == '__main__':
	print('send("hoge@gmail.com", "Test", "ABC_TEST")')
	send("hoge@gmail.com", "Test", "ABC_TEST")


import pandas as pd                                             #Importering af pandas bibliotek (Beregning)
import matplotlib.pyplot as plt                                 #Importering af matplotlib.pyplot bibliotek (Plotting)
import csv                                                      #Importering af csv modul (Behandling)

print('Hej, og velkommen til vejrudsigtsmodulet, før du kan få indsigt skal du logge ind.\n')

class Login():                                          #Definerer en class som indeholer en række funktioner.

    def __init__(self):                                 #Definerer opstarts funktionen. Denne funktion kører når Login() kører.

        self.brugernavn = input('Arbejdsmail : ')       #Definerer brugernavn som et input fra bruger
        self.adgangskode = input('Adgangskode : ')      #Definerer adgangskode som et input fra bruger

    def login_check(self):                              #login_check funktion. " By using the “self” keyword we can access the attributes and methods of the class in python. It binds the attributes with the given arguments. " (https://www.geeksforgeeks.org/self-in-python-class/)

        file = open("Login.txt","r")                    #Åbner Login.txt fil i read mode "r". Der kan kun læses i filen i dette mode.

        if '@' not in self.brugernavn:                  #If statement. Hvis @ ikke er en del af brugernavnet gør dette:
            print('Arbejdsmail skal indeholde @')
            print('Log venligst ind igen')
            login = Login()                             #Kører Login() class på ny
            login.login_check()                         #Kører login_check class efter __init__ class.

        elif self.brugernavn and self.adgangskode in file:      #Elif statement. Elif bruges, da der er flere "if". Hvis brugernavn og adgangskode er i fil gør dette:
            print('\nVelkommen', self.brugernavn)

        else:                                                   #else statement. Hvis brugernavn og adgangskode ikke er i fil gør dette:
            question = input("\nArbejdsmail eller Adgangskode er forkert. \nHar du godkendt dine login oplysninger? ja/nej : ")

            if question == 'ja':                                #if statement. Hvis input = "ja" gør dette:
                print('Prøv venligst at logge ind igen')
                login = Login()                                 #Kører Login() class på ny
                login.login_check()                             #Kører login_check class efter __init__ class.

            elif question == "nej":                             #elif statement. Hvis input = "nej" gør dette:
                print('Du skal skrive din arbejdsmail og adgangskode første gang du logger ind.')
                print('Dette skal du gøre for at godkende dine oplysingner i vores system.')
                self.approve_login()                            #Kører funktionen approve_login()

            else:                                               #else start på ny.
                login = Login()
                login.login_check()

    def approve_login(self):                                                            #approve_login funktion. Godkender login.

        file = open("Login.txt", "a")                                                   #Åbner .txt fil i append mode "a". I dette mode er det kun muligt at tilføje noget til filen.

        file.write("\n" + input('Arbejdsmail : '))                                      #.write gør at man kan skrive noget der bliver tilføjet til filen. Her er det brugerens input der bliver tilføjet.
        file.write("\n" + input('Adgangskode : '))
        print("Login godkendes")
        print('Login er godkendt i vores system. Prøv venligst at logge ind igen.')

        file.close()                                                                    #Lukker filen Login.txt der er blevet navngivet "file" i 46.

        login = Login()                                                                 #Starter på ny.
        login.login_check()

login = Login()                     #Kører Login() class og dermed __init__
login.login_check()                 #Kører login_check class efter __init__ class.

class Menu():                       #Definerer Menu() som en class

    #Menu der viser valgmuligheder
    def __init__(self):
        print("----------------------------------------------------------------------------------")
        print("MENU")
        print("1. Se datointerval og antal af målinger.")
        print("2. Se den maksimale vindhastighed for hver enkel dag og samlet for alle dage.")
        print("3. Se graf der viser hyppigheden for vindretningerne.")
        print("4. Se graf der viser middelhastighed for hver vindretning.")
        print("5. Se graf der viser vindretningen for hver enkel dato.")
        print("6. Afslut")
        print("----------------------------------------------------------------------------------")

    #Funktion hvor der vælges hvilket menupunkt man ønsker at tilgå. Består af "if", "elif" og "else" statements.
    def choice(self):

        choice = input("\n" + "Venligst vælg hvilket menupunkt du ønsker at tilgå." + "\n" + "Du vælger menupunkt ved at taste det nummer der står ud for det menupunkt du ønsker at vælge. (1, 2, 3, 4, 5, 6)" + "\n")

        if choice == "1":
            choice1 = choice_1()
            choice1.date_interval()
            choice1.row_count()

        elif choice == "2":
            choice2 = choice_2()
            choice2.max_windspeed_per_day()
            choice2.max_windspeed_period()
            choice2.plot_max_windspeed_per_day()

        elif choice == "3":
            choice3 = choice_3()
            choice3.filter_windspeed()
            choice3.wind_direction_frequency()
            choice3.plot_wind_direction_frequency()

        elif choice == "4":
            choice4 = choice_4()
            choice4.filter_windspeed()
            choice4.mean_windspeed()
            choice4.plot_mean_windspeed()

        elif choice == "5":
            choice5 = choice_5()
            choice5.filter_windspeed()
            choice5.plot_wind_direction_per_day()

        elif choice == "6":                             #Afslutter programmet
            exit()
        else:
            self.choice()                               #Hvis nummeret der indtastes ikke stemmer overens med nummeret i menuen, sendes brugeren tilbage til valg af menupunkt(choice(self)).

    def return_or_leave(self):

        print("----------------------------------------------------------------------------------")
        print("1. Gå tilbage til menu")
        print("2. Afslut")
        print("----------------------------------------------------------------------------------")

        return_or_leave = input("Vælg venligst ved at taste 1 eller 2\n")

        if return_or_leave == "1":
            menu = Menu()           #Kører Menu class på ny med __init__ først
            menu.choice()           #Kører choice() funktion efter __init__ funktion.

        elif return_or_leave == "2":
            exit()                  #Afslutter programmet/script

        else:
            self.return_or_leave()  #Kører return_or_leave funktion på ny.

#Class hvor der vises datointerval og antal af målinger.
class choice_1():

    def date_interval(self):

        fh = open('WindData.csv', 'r')                  #Åbner og læser hvad der står i .csv filen
        csvreader = csv.reader(fh, delimiter = ';')     #Laver hver linje i csv filen til en liste. Denne liste opstår af strings sepereret af kommaer. En ny liste skabes efter hvert linjeskift. I WindData.csv er delimiteren (;). Delimiter er der hvor kolonner i csv filen skifter.
        next(csvreader)                                  #Springer den øverste linje over (header). Bruges for at undgå at overskrifterne tælles med i beregninger.

        TimestampList = []                               #Fortæller at der er tale om en liste
        WindDirectionList = []
        WindSpeedList = []

        for row in csvreader:                                               #For linjer i .csv filen gør dette.
            if any(row):                                                    #Tjekker om der eksisterer linjer med data.
                TimestampList.append(row[0])                                #laver en liste ud fra tidspunkter opgivet i csv filen. Listen indeholder al data der står på kolonne med index 0 i .csv filen (csvreader).
                WindDirectionList.append(row[1])                            #Kolonne index 1 til liste.
                WindSpeedList.append(row[2])                                ##Kolonne index 2 til liste.

        Date_interval = [TimestampList[-1] + " til " + TimestampList[0]]      #Printer det sidste og det første i listen over tidspunkter. Printer index [-1] og [0] i listen "TimestampList".

        print ("\nDatointervallet for samtlige målinger er:\n",Date_interval)
        fh.close()                                      #Lukker fil

    def row_count(self):

        fh = open('WindData.csv', 'r')                  #Åbner og læser hvad der står i .csv filen
        csvreader = csv.reader(fh, delimiter = ';')     #Laver hver linje i csv filen til en liste. Denne liste opstår af strings sepereret af kommaer. En ny liste skabes efter hvert linjeskift. I WindData.csv er delimiteren (;)
        next(csvreader)                                 #Springer den øverste linje over (header)
        rows = len(list(csvreader))                    #Finder hvor mange lister der er i listerne baseret på .csv filen. Mængden af lister må blive det samme som mængden af linjer, da listen laves efter linjeskift.

        print("\nAntal af målinger ialt =", rows, "\n")           #Printer antallet af linjer
        fh.close()                                      #Lukker fil
        menu.return_or_leave()                          #Kører return_or_leave() funktion i Menu() class

# Class hvor der vises den maksimale vindhastighed for hver enkel dag og samlet for alle dage.
class choice_2():

    def max_windspeed_per_day(self):

        winddata = pd.read_csv('WindData.csv', parse_dates=[0], dayfirst=True, sep = ';', decimal=',')  #Bruger pandas til at åbne .csv filen "pd.read_csv". parse_dates laver dataformatet om således at pandas kan forstå det. Datoen står i kolonne med index [0]. dayfirst=True fortæller pandas at i vores datoer står dagen først. sep = ';' fortæller at kolonner skifter ved semikolon. decimal = ',' fortæller at istedet for at bruge punktum bruger vi komma som decimal.

        self.max_windspeed_per_day = winddata.groupby(pd.Grouper(key='Timestamp', freq='1D')).max()          #Gruppere dataen i winddata. key='Timestamp' fortæller at det er "Timestamp" kolonnen der grupperes efter. freq='1D' fortæller at vi ønsker at se data per dag. .max() fortæller at det er den højeste værdi vi ønsker at se per dag.
        print("De maksimale opnåede vindhastighedheder for hver enkel dag:\n")
        print("--------------------------------------------------------------------------")
        print(self.max_windspeed_per_day)
        print("--------------------------------------------------------------------------")

    def max_windspeed_period(self):

        winddata = pd.read_csv('WindData.csv', parse_dates=[0], dayfirst=True, sep = ';', decimal=',')  #Bruger pandas til at åbne .csv filen "pd.read_csv". parse_dates laver dataformatet om således at pandas kan forstå det. Datoen står i kolonne med index [0]. dayfirst=True fortæller pandas at i vores datoer står dagen først. sep = ';' fortæller at kolonner skifter ved semikolon. decimal = ',' fortæller at istedet for at bruge punktum bruger vi komma som decimal.

        print("\nDen maksimale opnået vindhastighed for hele perioden:\n")
        self.max_windspeed_period = winddata['WindSpeed'].max()                                                  #finder max værdien for WindSpeed. winddata['WindSpeed'] fortæller at det er "WindSpeed" kolonnen i winddata. .max() at det er den højeste værdi i den kolonne.
        print("--------------------------------------------------------------------------")
        print(self.max_windspeed_period, "m/s")
        print("--------------------------------------------------------------------------")

    def plot_max_windspeed_per_day(self):

        answer = input("Ønsker du at se en graf over de maksimale opnåede vindhastigheder for hver enkel dag? (ja/nej)")

        if answer == "ja" or "Ja":
            #Plotter en graf over de maksimale opnåede vindhastigheder for hver enkel dag.
            plt.plot(self.max_windspeed_per_day.index, self.max_windspeed_per_day["WindSpeed"], '-o') #max_windspeed_per_day.index fortæller at det er første kolonne(Timestamp) der skal stå på x aksen. max_windspeed_per_day["WindSpeed"] fortæller at det er WindSpeed kolonnen på y aksen. '-o' fotæller at der skal være streger mellem punkterne.
            plt.xlabel("Dato")                                                              #Hvad der skal stå på x aksen
            plt.ylabel("Vindhastighed i m/s")                                               #Hvad der skal stå på y aksen
            plt.title("Maksimalt opnåede vindhastigheder for hver enkel dag")               #Hvad der skal stå som titel
            manager = plt.get_current_fig_manager()                                         #Henter funktion fra plt bibliotek.
            manager.full_screen_toggle()                                                    #Gør at grafen åbner i fuldskærm
            plt.show()                                                                      #Viser graf

            menu.return_or_leave()                          #Kører return_or_leave() funktion i Menu() class

        elif answer == "nej" or "Nej":
            menu.return_or_leave()                          #Kører return_or_leave() funktion i Menu() class

    #class der viser graf over hyppigheden for vindretningerne
class choice_3():

    def filter_windspeed(self):

        winddata = pd.read_csv('WindData.csv', sep = ';', decimal=',')      #Åbner csv filen som winddata i read mode. sep bruges for at fortælle at der bruges semikolon mellem datakolonner og ikke ','. decimal fortæller at vi bruger ',' og ikke '.' som decimal.

        self.filter_windspeed = []                                       #Laver en liste, hvori de filtrerede værdier kommer til at være.

        for windspeed in winddata.WindSpeed:                        #Et for loop der filtrere, således at vi kun har vores ønskede værdier. De ønskede værdier gemmes i vores liste filter_windspeed.
            if ((windspeed >= 2.5) and (windspeed <= 25)):
                self.filter_windspeed.append(True)                       #Hvis dataen er indenfor værdierne tilføjes de til listen via .append. BOOLEAN
            else:
                self.filter_windspeed.append(False)                      #Hvis dataen ikke er indenfor værdierne tilføjes de ikke til listen via .append. BOOLEAN

        convert_filter_windspeed = pd.Series(self.filter_windspeed)      #Konverterer vores liste filter_windspeed[] til pandas serie. Dette gør at data bliver opstillet som et dataframe og ikke liste. Dette dataframe består af True og False statements for WindSpeed.
        self.winddata_filter = winddata[convert_filter_windspeed]        #Koverterer vores true/false dataframe til et samlet dataframe hvor alle false statements er filtreret fra. winddata[convert_filter_windspeed] winddata fortæller at det er det samlede dataframe.[convert_filter_windspeed] fortæller at linjer med WindSpeed under 2.5 eller over 25 skal filtreres fra.

    def wind_direction_frequency(self):

        East = self.winddata_filter[(self.winddata_filter['WindDirection'] > 45) & (self.winddata_filter['WindDirection'] <= 135)]     #Viser kun resultater over 45 eller under eller lig med 135 for WindDirection.
        South = self.winddata_filter[(self.winddata_filter['WindDirection'] > 135) & (self.winddata_filter['WindDirection'] <= 225)]   #Viser kun resultater over 135 eller under eller lig med 225 for WindDirection.
        West = self.winddata_filter[(self.winddata_filter['WindDirection'] > 225) & (self.winddata_filter['WindDirection'] <= 315)]    #Viser kun resultater over 225 eller under eller lig med 315 for WindDirection.
        North315 = self.winddata_filter[(self.winddata_filter['WindDirection'] > 315)]                                            #Viser kun resultater over 315 for WindDirection.
        North45 = self.winddata_filter[(self.winddata_filter['WindDirection'] <= 45)]                                             #Viser kun resultater under eller lig med 45 for WindDirection.
        North = North315.append(North45)                                            #Tilføjer North45 til North315 således at de tilsammen udgør alle resultater for vindretningen North

        self.Winddirection_East = len(East)          #giver antal målinger for "East" eller længden af data rækker for "East"
        self.Winddirection_South = len(South)
        self.Winddirection_West = len(West)
        self.Winddirection_North = len(North)

    def plot_wind_direction_frequency(self):

        wind_direction_frequency_list = [self.Winddirection_East, self.Winddirection_South, self.Winddirection_West, self.Winddirection_North]      #Liste med de forskellige længder af datarækker.
        winddirections = ["Øst", "Syd", "Vest", "Nord"]     #Liste med vindretninger.

        plt.bar(winddirections, wind_direction_frequency_list, color ='blue')       #bar fortæller at det er et søjlediagram. winddirections på x aksen. wind_direction_frequency_list på y aksen. farve blå.
        plt.xlabel("Vindretning")                                                   #Skrift på x akse
        plt.ylabel("Hyppigheden målt i antal tidspunkter")                          #Skrift på y akse
        plt.title("Hyppigheden for vindretningerne Ø, S, V og Nord")                #Skrift på titel
        manager = plt.get_current_fig_manager()                                     #Henter funktion fra plt bibliotek.
        manager.full_screen_toggle()                                                #Gør at grafen åbner i fuldskærm
        plt.show()                                                                  #Viser graf

        menu.return_or_leave()                          #Kører return_or_leave() funktion i Menu() class

#Funktion der viser graf over middelhastighed for hver vindretning.
class choice_4():

    def filter_windspeed(self):

        winddata = pd.read_csv('WindData.csv', sep = ';', decimal=',')      #Åbner csv filen som winddata i read mode. sep bruges for at fortælle at der bruges semikolon mellem datakolonner og ikke ','. decimal fortæller at vi bruger ',' og ikke '.' som decimal.

        self.filter_windspeed = []                                       #Laver en liste, hvori de filtrerede værdier kommer til at være.

        for windspeed in winddata.WindSpeed:                        #Et for loop der filtrere, således at vi kun har vores ønskede værdier. De ønskede værdier gemmes i vores liste filter_windspeed.
            if ((windspeed >= 2.5) and (windspeed <= 25)):
                self.filter_windspeed.append(True)                       #Hvis dataen er indenfor værdierne tilføjes de til listen via .append. BOOLEAN
            else:
                self.filter_windspeed.append(False)                      #Hvis dataen ikke er indenfor værdierne tilføjes de ikke til listen via .append. BOOLEAN

        convert_filter_windspeed = pd.Series(self.filter_windspeed)      #Konverterer vores liste filter_windspeed[] til pandas serie. Dette gør at data bliver opstillet som et dataframe og ikke liste. Dette dataframe består af True og False statements for WindSpeed.
        self.winddata_filter = winddata[convert_filter_windspeed]        #Koverterer vores true/false dataframe til et samlet dataframe hvor alle false statements er filtreret fra. winddata[convert_filter_windspeed] winddata fortæller at det er det samlede dataframe.[convert_filter_windspeed] fortæller at linjer med WindSpeed under 2.5 eller over 25 skal filtreres fra.

    def mean_windspeed(self):

        East = self.winddata_filter[(self.winddata_filter['WindDirection'] > 45) & (self.winddata_filter['WindDirection'] <= 135)]     #Viser kun resultater over 45 eller under eller lig med 135 for WindDirection.
        South = self.winddata_filter[(self.winddata_filter['WindDirection'] > 135) & (self.winddata_filter['WindDirection'] <= 225)]   #Viser kun resultater over 135 eller under eller lig med 225 for WindDirection.
        West = self.winddata_filter[(self.winddata_filter['WindDirection'] > 225) & (self.winddata_filter['WindDirection'] <= 315)]    #Viser kun resultater over 225 eller under eller lig med 315 for WindDirection.
        North315 = self.winddata_filter[(self.winddata_filter['WindDirection'] > 315)]                                            #Viser kun resultater over 315 for WindDirection.
        North45 = self.winddata_filter[(self.winddata_filter['WindDirection'] <= 45)]                                             #Viser kun resultater under eller lig med 45 for WindDirection.
        North = North315.append(North45)                                            #Tilføjer North45 til North315 således at de tilsammen udgør alle resultater for vindretningen North

        self.Average_windspeed_East = East['WindSpeed'].mean()       #Giver gennemsnittet for WindSpeed i dataframe East
        self.Average_windspeed_South = South['WindSpeed'].mean()
        self.Average_windspeed_West = West['WindSpeed'].mean()
        self.Average_windspeed_North = North['WindSpeed'].mean()

    def plot_mean_windspeed(self):

        average_windspeed_list = [self.Average_windspeed_East, self.Average_windspeed_South, self.Average_windspeed_West, self.Average_windspeed_North]     #Liste over gennemsnit for WindSpeed for hver vindretning.
        winddirections = ["Øst", "Syd", "Vest", "Nord"]     #Liste over vindretninger

        plt.bar(winddirections, average_windspeed_list, color ='blue')              #bar fortæller at det er et søjlediagram. winddirections på x aksen. average_windspeed_list på y aksen. farve blå.
        plt.xlabel("Vindretning")                                                   #Skrift på x akse
        plt.ylabel("Gennemsnitlig vindstyrke i m/s")                                #Skrift på y akse
        plt.title("Gennemsnitlig vindstyrke for Ø, S, V og Nord")                   #Skrift på titel
        manager = plt.get_current_fig_manager()                                     #Henter funktion fra plt bibliotek.
        manager.full_screen_toggle()                                                #Gør at grafen åbner i fuldskærm
        plt.show()                                                                  #Viser graf

        menu.return_or_leave()                          #Kører return_or_leave() funktion i Menu() class

#Funktion der viser graf over vindretningen for hver enkel dato.
class choice_5():

    def filter_windspeed(self):

        winddata = pd.read_csv('WindData.csv', parse_dates=[0], dayfirst=True, sep = ';', decimal=',')      #Bruger pandas til at åbne .csv filen "pd.read_csv". parse_dates laver dataformatet om således at pandas kan forstå det. Datoen står i kolonne med index [0]. dayfirst=True fortæller pandas at i vores datoer står dagen først. sep = ';' fortæller at kolonner skifter ved semikolon. decimal = ',' fortæller at istedet for at bruge punktum bruger vi komma som decimal.

        self.filter_windspeed = []                                       #Laver en liste, hvori de filtrerede værdier kommer til at være.

        for windspeed in winddata.WindSpeed:                        #Et for loop der filtrere, således at vi kun har vores ønskede værdier. De ønskede værdier gemmes i vores liste filter_windspeed.
            if ((windspeed >= 2.5) and (windspeed <= 25)):
                self.filter_windspeed.append(True)                       #Hvis dataen er indenfor værdierne tilføjes de til listen via .append. BOOLEAN
            else:
                self.filter_windspeed.append(False)                      #Hvis dataen ikke er indenfor værdierne tilføjes de ikke til listen via .append. BOOLEAN

        convert_filter_windspeed = pd.Series(self.filter_windspeed)      #Konverterer vores liste filter_windspeed[] til pandas serie. Dette gør at data bliver opstillet som et dataframe og ikke liste. Dette dataframe består af True og False statements for WindSpeed.
        self.winddata_filter = winddata[convert_filter_windspeed]        #Koverterer vores true/false dataframe til et samlet dataframe hvor alle false statements er filtreret fra. winddata[convert_filter_windspeed] winddata fortæller at det er det samlede dataframe.[convert_filter_windspeed] fortæller at linjer med WindSpeed under 2.5 eller over 25 skal filtreres fra.

    def plot_wind_direction_per_day(self):

        plt.plot(self.winddata_filter["Timestamp"], self.winddata_filter["WindDirection"], '-o')  #"Timestamp" skal stå på x aksen. "WindDirection" skal stå på y aksen. '-o' fotæller at der skal være streger mellem punkterne.
        plt.xlabel("Tidspunkter")                                                   #Skrift på x akse
        plt.ylabel("Vindretning i grader for hvert tidspunkt")                      #Skrift på y akse
        plt.title("Vindretning i grader. Øst(>45 - <=135), Syd(>135 - <=225), Vest(>225 - <=315), Nord(>315 - <=45)")  #Skrift på titel
        manager = plt.get_current_fig_manager()                                     #Henter funktion fra plt bibliotek.
        manager.full_screen_toggle()                                                #Gør at grafen åbner i fuldskærm
        plt.show()                                                                  #Viser graf

        menu.return_or_leave()                          #Kører return_or_leave() funktion i Menu() class

menu = Menu()   #Kører Menu() class
menu.choice()   #Kører choice() funktion i Menu() class