import numpy as np
from queue import Queue
import time

from collections import deque

import copy

from constant import BOARD_SIZE, WALL_NUM, TURN_LIMIT

HORIZONTAL = 1
VERTICAL = -1

class Quoridor(object):
    HORIZONTAL = 1
    VERTICAL = -1

    def __init__(self, safe=False):
        self.safe = safe

        self.action_space = 12 + (BOARD_SIZE - 1) ** 2  # 12 + 32 actions in total (5x5 Quoridor)
        self.n_players = 2
        self.players = [1, 2]  #
        self.reset()

    # load player's info (human or computer)
    def load(self, p1, p2):
        self.player1 = p1
        self.player2 = p2

    # return current player info
    def get_current_player(self):
        return self.current_player

    # reset and initialize single game
    def reset(self, first_player=1, second_player=2):
        self.current_player = first_player
        self.last_player = second_player

        # Initialize Tiles
        self.tiles = np.zeros(BOARD_SIZE ** 2)

        # Initialize Player Locations
        self._positions = {
            1: (BOARD_SIZE ** 2) - (BOARD_SIZE//2) - 1,
            2: BOARD_SIZE // 2
        }

        self._DIRECTIONS = {
            'N': 0, 'S': 1, 'E': 2, 'W': 3,
            'NN': 4, 'SS': 5, 'EE': 6, 'WW': 7,
            'NE': 8, 'NW': 9, 'SE': 10, 'SW': 11
        }
        self.N_DIRECTIONS = 12
        self.N_TILES = BOARD_SIZE ** 2
        self.N_ROWS = BOARD_SIZE
        self.N_INTERSECTIONS = (BOARD_SIZE - 1) ** 2

        # There are 16 possible intersection
        # Horizontal Walls - 1
        # No Wall - 0
        # Vertical Wall - -1
        self._intersections = np.zeros((BOARD_SIZE - 1) ** 2)

        self._player_walls_remaining = {1: WALL_NUM, 2: WALL_NUM}

    def state(self):
        """Returns a set of 5x5 planes that represent the game state.
        0. No walls
        1. Vertical walls
        2. Horizontal walls
        3. The current player position
        4. The opponent position
        5 - 8. Number of walls remaining for current player (if 3walls remain, 5/6/8th are zeros and 7th is ones)
        9 - 12. Number of walls remaining for opponent
        13. Whose turn it is (0 for player 1, 1 for player 2)
        """
        player1_position_plane = self.tiles.copy()
        player1_position_plane[self._positions[self.current_player]] = 1
        player1_position_plane = player1_position_plane.reshape([BOARD_SIZE, BOARD_SIZE])

        player2_position_plane = self.tiles.copy()
        player2_position_plane[self._positions[3 - self.current_player]] = 1
        player2_position_plane = player2_position_plane.reshape([BOARD_SIZE, BOARD_SIZE])

        player1_walls_plane = np.zeros([WALL_NUM+1, BOARD_SIZE, BOARD_SIZE])
        player2_walls_plane = np.zeros([WALL_NUM+1, BOARD_SIZE, BOARD_SIZE])

        player1_walls_plane[self._player_walls_remaining[self.current_player], :, :] = 1
        player2_walls_plane[self._player_walls_remaining[3 - self.current_player], :, :] = 1

        # 1 where vertical walls are placed
        # if state size is ?x9x9, use only ?x8x8 field
        vertical_walls = np.pad(
            np.int8(self._intersections == -1).reshape([BOARD_SIZE - 1, BOARD_SIZE - 1]),
            (0, 1),
            mode='constant',
            constant_values=0
        )

        # 1 where horizontal walls are placed
        # if state size is ?x9x9, use only ?x8x8 field
        horizontal_walls = np.pad(
            np.int8(self._intersections == 1).reshape([BOARD_SIZE - 1, BOARD_SIZE - 1]),
            (0, 1),
            mode='constant',
            constant_values=0
        )

        # 1 where any walls exist
        # if state size is ?x9x9, use only ?x8x8 field
        no_walls = np.pad(
            np.int8(self._intersections == 0).reshape([BOARD_SIZE - 1, BOARD_SIZE - 1]),
            (0, 1),
            mode='constant',
            constant_values=0
        )

        # shortest path distance
        dist1, dist2 = self.get_shortest_path()

        if self.current_player == 1:
            dist1_plane = np.full((1, BOARD_SIZE, BOARD_SIZE), dist1)
            dist2_plane = np.full((1, BOARD_SIZE, BOARD_SIZE), dist2)
        else:
            dist1_plane = np.full((1, BOARD_SIZE, BOARD_SIZE), dist2)
            dist2_plane = np.full((1, BOARD_SIZE, BOARD_SIZE), dist1)

        state = np.stack([
                no_walls,
                vertical_walls,
                horizontal_walls,
                player1_position_plane,
                player2_position_plane,
            ])

        if self.current_player == 1:
            current_player_plane = np.zeros([1, BOARD_SIZE, BOARD_SIZE])
        else:
            current_player_plane = np.ones([1, BOARD_SIZE, BOARD_SIZE])

        state = np.vstack([state, player1_walls_plane, player2_walls_plane, current_player_plane, dist1_plane, dist2_plane])
        # state = np.vstack([state, player1_walls_plane, player2_walls_plane, current_player_plane])

        return state

    def get_shortest_path(self):

        player1_target = 0
        player2_target = BOARD_SIZE - 1

        player1_position = self._positions[1]
        player2_position = self._positions[2]

        intersections = self._intersections

        player1_valid, dist1 = self._bfs_to_goal2(intersections, player1_target, player1_position, player1_position, player=1)
        player2_valid, dist2 = self._bfs_to_goal2(intersections, player2_target, player2_position, player2_position, player=2)

        return dist1, dist2

    def actions(self):
        player = self.current_player
        location = self._positions[player]

        opponent = 1 if player == 2 else 2
        opponent_loc = self._positions[opponent]
        walls = self._intersections  #
        #
        pawn_actions = self._valid_pawn_actions(location=location,
                                                opponent_loc=opponent_loc, walls=walls, player=player)
        #
        if (self._player_walls_remaining[self.current_player] > 0):
            wall_actions = self._valid_wall_actions()  #

            #
            wall_actions = [action + 12 for action in wall_actions]
        else:
            wall_actions = []

        return pawn_actions + wall_actions

    def step(self, action):
        """Take a step in the environment given the current action"""
        # self._logger.info("Player {player} chooses action {action}".format(player=self.current_player, action=action))
        player = self.current_player
        done = False
        #
        self.valid_actions = self.actions()

        if self.safe:
            if not action in self.valid_actions:
                raise ValueError("Invalid Action: {action}".format(action=action))

        if action < 12:
            self._handle_pawn_action(action, player)
        else:
            self._handle_wall_action(action - 12)

        self.rotate_players()
        """
        game_over, winner = self.has_a_winner()
        if game_over:
            #  print("game over !winner is player" + str(winner))
            done = True
        else:
            self.rotate_players()  #
            # observation = self.get_state  # get_state
            # observation = self.state()
            # print("game over !winner is player" + str(winner))

        return done, winner
        """

    def has_a_winner3(self):
        game_over = False
        winner = None
        if self._positions[2] > (BOARD_SIZE - 1) * BOARD_SIZE - 1:
            winner = 2
            game_over = True
        elif self._positions[1] < BOARD_SIZE:
            winner = 1
            game_over = True
        return game_over, winner

    def has_a_winner(self):
        game_over = False
        winner = None
        dist1, dist2 = self.get_shortest_path()

        if self._positions[2] > (BOARD_SIZE - 1) * BOARD_SIZE - 1:
            winner = 2
            game_over = True
        elif self._positions[1] < BOARD_SIZE:
            winner = 1
            game_over = True

        if abs(dist1 - dist2) > 1 and self._player_walls_remaining[1] == 0 and self._player_walls_remaining[2] == 0:
            winner = 2 if dist1 > dist2 else 1
            game_over = True

        return game_over, winner

    # check that pawn moved to dead end
    def is_dead_end(self, game):
        current_player = self.get_current_player()

    def _return_pawn_action(self, action, player):
        if action == self._DIRECTIONS['N']:
            return self._positions[player] - BOARD_SIZE
        elif action == self._DIRECTIONS['S']:
            return self._positions[player] + BOARD_SIZE
        elif action == self._DIRECTIONS['E']:
            return self._positions[player] + 1
        elif action == self._DIRECTIONS['W']:
            return self._positions[player] - 1
        elif action == self._DIRECTIONS['NN']:
            return self._positions[player] - (BOARD_SIZE * 2)
        elif action == self._DIRECTIONS['SS']:
            return self._positions[player] + (BOARD_SIZE * 2)
        elif action == self._DIRECTIONS['EE']:
            return self._positions[player] + 2
        elif action == self._DIRECTIONS['WW']:
            return self._positions[player] - 2
        elif action == self._DIRECTIONS['NW']:
            return self._positions[player] - (BOARD_SIZE + 1)
        elif action == self._DIRECTIONS['NE']:
            return self._positions[player] - (BOARD_SIZE - 1)
        elif action == self._DIRECTIONS['SW']:
            return self._positions[player] + (BOARD_SIZE - 1)
        elif action == self._DIRECTIONS['SE']:
            return self._positions[player] + (BOARD_SIZE + 1)
        else:
            raise ValueError("Invalid Pawn Action: {action}".format(action=action))

    def _handle_pawn_action(self, action, player):
        if action == self._DIRECTIONS['N']:
            self._positions[player] -= BOARD_SIZE
        elif action == self._DIRECTIONS['S']:
            self._positions[player] += BOARD_SIZE
        elif action == self._DIRECTIONS['E']:
            self._positions[player] += 1
        elif action == self._DIRECTIONS['W']:
            self._positions[player] -= 1
        elif action == self._DIRECTIONS['NN']:
            self._positions[player] -= BOARD_SIZE * 2
        elif action == self._DIRECTIONS['SS']:
            self._positions[player] += BOARD_SIZE *  2
        elif action == self._DIRECTIONS['EE']:
            self._positions[player] += 2
        elif action == self._DIRECTIONS['WW']:
            self._positions[player] -= 2
        elif action == self._DIRECTIONS['NW']:
            self._positions[player] -= BOARD_SIZE + 1
        elif action == self._DIRECTIONS['NE']:
            self._positions[player] -= BOARD_SIZE - 1
        elif action == self._DIRECTIONS['SW']:
            self._positions[player] += BOARD_SIZE - 1
        elif action == self._DIRECTIONS['SE']:
            self._positions[player] += BOARD_SIZE + 1
        else:
            raise ValueError("Invalid Pawn Action: {action}".format(action=action))

    def _handle_wall_action(self, action):
        # Action values less than 16 are horizontal walls
        if action < (BOARD_SIZE - 1) ** 2:
            self._intersections[action] = 1
        # Action values above 16 are vertical walls
        else:
            self._intersections[action - (BOARD_SIZE - 1) ** 2] = -1

        self._player_walls_remaining[self.current_player] -= 1
        # self._logger.info(self._intersections)

    def rotate_players(self):
        """Switch the player turn"""
        # self._logger.debug("Rotating Player")
        if self.current_player == 1:
            self.current_player = 2
            self.last_player = 1

        else:
            self.current_player = 1
            self.last_player = 2

    def _valid_pawn_actions(self, walls, location, opponent_loc, player=1):

        valid = []
        opponent_north = (location == opponent_loc + BOARD_SIZE)
        opponent_south = (location == opponent_loc - BOARD_SIZE)
        opponent_east = (location == opponent_loc - 1)
        opponent_west = (location == opponent_loc + 1)

        current_row = location // self.N_ROWS

        intersections = self._get_intersections(walls, location)
        n = intersections['NW'] != HORIZONTAL and intersections['NE'] != HORIZONTAL and not opponent_north
        s = intersections['SW'] != HORIZONTAL and intersections['SE'] != HORIZONTAL and not opponent_south
        e = intersections['NE'] != VERTICAL and intersections['SE'] != VERTICAL and not opponent_east
        w = intersections['NW'] != VERTICAL and intersections['SW'] != VERTICAL and not opponent_west
        if n: valid.append(self._DIRECTIONS['N'])
        if s: valid.append(self._DIRECTIONS['S'])
        if e: valid.append(self._DIRECTIONS['E'])
        if w: valid.append(self._DIRECTIONS['W'])

        if opponent_north and intersections['NE'] != HORIZONTAL and intersections['NW'] != HORIZONTAL:
            n_intersections = self._get_intersections(walls, opponent_loc)
            if n_intersections['NW'] != HORIZONTAL and n_intersections['NE'] != HORIZONTAL:  # or (current_row == 3 and player == 1):
                valid.append(self._DIRECTIONS['NN'])

            if n_intersections['NE'] != VERTICAL and intersections['NE'] != VERTICAL:
                valid.append(self._DIRECTIONS['NE'])

            if n_intersections['NW'] != VERTICAL and intersections['NW'] != VERTICAL:
                valid.append(self._DIRECTIONS['NW'])

        elif opponent_south and intersections['SE'] != HORIZONTAL and intersections['SW'] != HORIZONTAL:
            s_intersections = self._get_intersections(walls, opponent_loc)
            if s_intersections['SW'] != HORIZONTAL and s_intersections['SE'] != HORIZONTAL:  # or (current_row == 1 and player == 2):
                valid.append(self._DIRECTIONS['SS'])

            if s_intersections['SE'] != VERTICAL and intersections['SE'] != VERTICAL:
                valid.append(self._DIRECTIONS['SE'])

            if s_intersections['SW'] != VERTICAL and intersections['SW'] != VERTICAL:
                valid.append(self._DIRECTIONS['SW'])

        elif opponent_east and intersections['SE'] != VERTICAL and intersections['NE'] != VERTICAL:
            e_intersections = self._get_intersections(walls, opponent_loc)
            if e_intersections['SE'] != VERTICAL and e_intersections['NE'] != VERTICAL:
                valid.append(self._DIRECTIONS['EE'])

            # fix jumping over wall bug
            if e_intersections['NE'] != HORIZONTAL and e_intersections['NW'] != HORIZONTAL:
                valid.append(self._DIRECTIONS['NE'])

            # fix jumping over wall bug
            if e_intersections['SE'] != HORIZONTAL and e_intersections['SW'] != HORIZONTAL:
                valid.append(self._DIRECTIONS['SE'])

        elif opponent_west and intersections['SW'] != VERTICAL and intersections['NW'] != VERTICAL:
            w_intersections = self._get_intersections(walls, opponent_loc)
            if w_intersections['NW'] != VERTICAL and w_intersections['SW'] != VERTICAL:
                valid.append(self._DIRECTIONS['WW'])

            # fix jumping over wall bug
            if w_intersections['NW'] != HORIZONTAL and w_intersections['NE'] != HORIZONTAL:
                valid.append(self._DIRECTIONS['NW'])

            # fix jumping over wall bug
            if w_intersections['SW'] != HORIZONTAL and w_intersections['SE'] != HORIZONTAL:
                valid.append(self._DIRECTIONS['SW'])

        return valid

    def _get_intersections(self, intersections, current_tile):

        """Gets the four intersections for a given tile."""
        location_row = current_tile // self.N_ROWS
        s_border = current_tile > (BOARD_SIZE - 1) * BOARD_SIZE -1
        e_border = current_tile % BOARD_SIZE == BOARD_SIZE - 1
        n_border = current_tile < BOARD_SIZE
        w_border = current_tile % BOARD_SIZE == 0

        if n_border:
            ne_intersection = HORIZONTAL

            location_row = 0
            if w_border:
                nw_intersection = VERTICAL
                sw_intersection = VERTICAL
                se_intersection = intersections[current_tile]
            elif e_border:
                nw_intersection = HORIZONTAL
                se_intersection = VERTICAL
                sw_intersection = intersections[current_tile - 1]
            else:
                nw_intersection = HORIZONTAL
                sw_intersection = intersections[current_tile - 1]
                se_intersection = intersections[current_tile]
        elif s_border:
            location_row = BOARD_SIZE - 1
            sw_intersection = HORIZONTAL
            if w_border:
                nw_intersection = VERTICAL
                se_intersection = HORIZONTAL
                ne_intersection = intersections[(current_tile- BOARD_SIZE) - (location_row-1)]
            elif e_border:
                se_intersection = VERTICAL
                ne_intersection = VERTICAL
                nw_intersection = intersections[(current_tile - BOARD_SIZE) - location_row]
            else:
                se_intersection = HORIZONTAL
                ne_intersection = intersections[(current_tile - BOARD_SIZE) - (location_row -1)]
                nw_intersection = intersections[(current_tile - BOARD_SIZE) - location_row]

        # West but not north or south
        elif w_border:
            nw_intersection = VERTICAL
            sw_intersection = VERTICAL
            se_intersection = intersections[current_tile - location_row]
            ne_intersection = intersections[(current_tile - BOARD_SIZE) - (location_row - 1)]

        elif e_border:
            ne_intersection = VERTICAL
            se_intersection = VERTICAL
            sw_intersection = intersections[current_tile - location_row - 1]
            nw_intersection = intersections[(current_tile - BOARD_SIZE) - (location_row - 1) - 1]

        # No borders
        else:
            ne_intersection = intersections[(current_tile - BOARD_SIZE) - (location_row-1)]
            nw_intersection = intersections[(current_tile - BOARD_SIZE) - location_row ]
            sw_intersection = intersections[current_tile - (location_row +1)]
            se_intersection = intersections[current_tile - location_row]

        return {'NW': nw_intersection,
                'NE': ne_intersection,
                'SE': se_intersection,
                'SW': sw_intersection}

    def _valid_wall_actions(self):
        valid = []
        # If
        for ix in range(self._intersections.size):
            if self._validate_horizontal(ix):
                valid.append(ix)

            if self._validate_vertical(ix):
                valid.append(ix + (BOARD_SIZE - 1) ** 2)

        return valid

    def _validate_horizontal(self, ix):
        column = ix % (BOARD_SIZE - 1)

        if self._intersections[ix] != 0:
            return False

        if column != 0:
            if self._intersections[ix - 1] == 1:
                return False

        if column != BOARD_SIZE - 2:
            if self._intersections[ix + 1] == 1:
                return False

        return not self._blocks_path(ix, self.HORIZONTAL)

    def _validate_vertical(self, ix):
        row = ix // (BOARD_SIZE - 1)
        if self._intersections[ix] != 0:
            return False

        if row != 0:
            if self._intersections[ix - (BOARD_SIZE - 1)] == -1:
                return False

        if row != BOARD_SIZE - 2:
            if self._intersections[ix + (BOARD_SIZE - 1)] == -1:
                return False

        return not self._blocks_path(ix, self.VERTICAL)

    def _blocks_path(self, wall_location, orientation):
        player1_target = 0
        player2_target = BOARD_SIZE - 1

        player1_position = self._positions[1]
        player2_position = self._positions[2]

        intersections = self._intersections.copy()
        intersections[wall_location] = orientation

        # BFS to target row
        player1_valid = self._bfs_to_goal(intersections, player1_target, player1_position, player2_position, player=1)
        player2_valid = self._bfs_to_goal(intersections, player2_target, player2_position, player1_position, player=2)

        return not (player1_valid and player2_valid)

    def _bfs_to_goal(self, intersections, target_row, player_position, opponent_position, player=1):
        visited = []
        invalid_rows = [BOARD_SIZE, -1]
        visit_queue = Queue()
        visit_queue.put(player_position)
        target_visited = False

        while not target_visited and not visit_queue.empty():
            current_position = visit_queue.get()
            valid_directions = self._valid_pawn_actions(intersections,
                                                        location=current_position,
                                                        opponent_loc=opponent_position,
                                                        player=player)

            for direction in valid_directions:
                if direction == self._DIRECTIONS['N']:
                    new_position = current_position - BOARD_SIZE
                elif direction == self._DIRECTIONS['S']:
                    new_position = current_position + BOARD_SIZE
                elif direction == self._DIRECTIONS['E']:
                    new_position = current_position + 1
                elif direction == self._DIRECTIONS['W']:
                    new_position = current_position - 1
                elif direction == self._DIRECTIONS['NN']:
                    new_position = current_position - (BOARD_SIZE * 2)
                elif direction == self._DIRECTIONS['SS']:
                    new_position = current_position + (BOARD_SIZE * 2)
                elif direction == self._DIRECTIONS['EE']:
                    new_position = current_position + 2
                elif direction == self._DIRECTIONS['WW']:
                    new_position = current_position - 2
                elif direction == self._DIRECTIONS['NE']:
                    new_position = current_position - (BOARD_SIZE - 1)
                elif direction == self._DIRECTIONS['NW']:
                    new_position = current_position - (BOARD_SIZE + 1)
                elif direction == self._DIRECTIONS['SW']:
                    new_position = current_position + (BOARD_SIZE - 1)
                elif direction == self._DIRECTIONS['SE']:
                    new_position = current_position + (BOARD_SIZE + 1)
                else:
                    raise ValueError('Invalid direction - should never happen')

                new_row = new_position // self.N_ROWS
                if new_row == target_row:
                    target_visited = True
                elif new_position not in visited:
                    visited.append(new_position)
                    if new_row not in invalid_rows:
                        visit_queue.put(new_position)

        return target_visited

    def _bfs_to_goal2(self, intersections, target_row, player_position, opponent_position, player=1):
        visited = []
        invalid_rows = [BOARD_SIZE, -1]
        visit_queue = Queue()
        visit_queue.put(player_position)
        target_visited = False

        dist = 0

        temp_queue = Queue()

        while not target_visited and not visit_queue.empty():

            while not visit_queue.empty() :
                current_position = visit_queue.get()

                if current_position < 0 or current_position > (BOARD_SIZE ** 2 -1):
                    print("Strange position in the queue: ", current_position)

                valid_directions = self._valid_pawn_actions(intersections,
                                                        location=current_position,
                                                        opponent_loc=opponent_position,
                                                        player=player)

                for direction in valid_directions:
                    if direction == self._DIRECTIONS['N']:
                        new_position = current_position - BOARD_SIZE
                    elif direction == self._DIRECTIONS['S']:
                        new_position = current_position + BOARD_SIZE
                    elif direction == self._DIRECTIONS['E']:
                        new_position = current_position + 1
                    elif direction == self._DIRECTIONS['W']:
                        new_position = current_position - 1
                    elif direction == self._DIRECTIONS['NN']:
                        new_position = current_position - (BOARD_SIZE * 2)
                    elif direction == self._DIRECTIONS['SS']:
                        new_position = current_position + (BOARD_SIZE * 2)
                    elif direction == self._DIRECTIONS['EE']:
                        new_position = current_position + 2
                    elif direction == self._DIRECTIONS['WW']:
                        new_position = current_position - 2
                    elif direction == self._DIRECTIONS['NE']:
                        new_position = current_position - (BOARD_SIZE - 1)
                    elif direction == self._DIRECTIONS['NW']:
                        new_position = current_position - (BOARD_SIZE + 1)
                    elif direction == self._DIRECTIONS['SW']:
                        new_position = current_position + (BOARD_SIZE - 1)
                    elif direction == self._DIRECTIONS['SE']:
                        new_position = current_position + (BOARD_SIZE + 1)
                    else:
                        raise ValueError('Invalid direction - should never happen')

                    new_row = new_position // self.N_ROWS
                    if new_row == target_row:
                        return True, dist + 1
                    elif new_position not in visited:
                        visited.append(new_position)
                        temp_queue.put(new_position)

            while not temp_queue.empty():
                position = temp_queue.get()
                if position < 0 or position > (BOARD_SIZE ** 2 - 1):
                    continue
                else:
                    visit_queue.put(position)

            dist += 1

        return target_visited, dist

    def add_wall(self, wall, orientation):
        self._intersections[wall] = orientation

    def print_board(self):
        player1_row = self._positions[1] // BOARD_SIZE * 2
        player1_col = self._positions[1] % BOARD_SIZE * 2
        player2_row = self._positions[2] // BOARD_SIZE * 2
        player2_col = self._positions[2] % BOARD_SIZE * 2

        x = 'X'
        o = 'O'

        v = 'v'
        h = 'h'
        dash = '-'
        none = ''

        grid_new = np.zeros([BOARD_SIZE * 2 - 1, BOARD_SIZE * 2 - 1])
        grid_new[player1_row, player1_col] = 1
        grid_new[player2_row, player2_col] = 2

        i_reshaped = self._intersections.reshape([BOARD_SIZE - 1, BOARD_SIZE - 1])
        for i in range(BOARD_SIZE -1):
            for j in range(BOARD_SIZE - 1):
                if i_reshaped[i][j] == 1:
                    grid_new[((i * 2) + 1), (j * 2):((j * 2) + 3)] = 3
                elif i_reshaped[i][j] == -1:
                    grid_new[(i * 2):((i * 2) + 3), ((j * 2) + 1)] = 4

        for i in range(BOARD_SIZE * 2 - 1):
            render_row = ""
            for j in range(BOARD_SIZE * 2 - 1):
                if grid_new[i, j] == 0:
                    if i % 2 == 0 and j % 2 == 0:
                        render_row += " . "
                    else:
                        render_row += "   "
                elif grid_new[i, j] == 1:
                    render_row += " X "
                elif grid_new[i, j] == 2:
                    render_row += " O "
                elif grid_new[i, j] == 3:
                    render_row += "---"
                else:
                    render_row += " | "

            print(render_row)

        """
        # Original print board code

        grid = [['{dash:4}'.format(dash=dash) for i in range(5)] for i in range(5)]
        i_reshaped = self._intersections.reshape([4, 4])

        grid[player1_row][player1_col] = '{x:4}'.format(x=x)
        grid[player2_row][player2_col] = '{o:4}'.format(o=o)

        intersection_row = 3
        for i in range(4, -1, -1):
            for j in range(5):
                print(grid[i][j], end='')
            print()
            if intersection_row >= 0:
                print('{none:2}'.format(none=none), end='')
                for j in i_reshaped[intersection_row, :]:
                    if j == 1:
                        # print('{h:4}'.format(h=h), end='')
                        print('{h:4}'.format(h=h), end='')
                    elif j == -1:
                        print('{v:4}'.format(v=v), end='')
                    else:
                        print('{none:4}'.format(none=none), end='')
                intersection_row -= 1
                print()
        """

    def clone(self):
        return Quoridor()

    def start_self_play(self, player, is_shown=0, temp=1e-3):

        self.reset()
        p1, p2 = self.players
        states, mcts_probs, current_players = [], [], []       #

        time_step = 0

        while(1):

            time_step += 1

            tic = time.time()
            move, move_probs = player.choose_action(self, temp=temp, return_prob=1, time_step=time_step)
            toc = time.time()
            print("turn %s" % time_step)
            print('[Move probs]\n', move_probs[:12])
            print('[Wall probs]\n', move_probs[12:])
            print("player %s chose move : %s, prob: %.3f, spend: %.2f seconds" % (self.current_player, move, move_probs[move], (toc-tic)))

            states.append(self.state())
            mcts_probs.append(move_probs)
            current_players.append(self.current_player)

            self.step(move)

            dist1, dist2 = self.get_shortest_path()
            print("Player 1 Shortest Path: {}, Player 2 Shortest Path: {}".format(dist1, dist2))

            self.print_board()
            # if is_shown:
            #     self.graphic(self.board, p1, p2)
            end, winner = self.has_a_winner()

            if end:
                #
                winners_z = np.zeros(len(current_players))
                if winner != -1:
                    winners_z[np.array(current_players) == winner] = 1.0        #
                    winners_z[np.array(current_players) != winner] = -1.0       #
                #
                player.reset_player()
                if is_shown:
                    if winner != -1:
                        print("Game end. Winner is player:", winner)
                    else:
                        print("Game end. Tie")
                return winner, zip(states, mcts_probs, winners_z)
            else:
                if time_step > TURN_LIMIT:
                    print("Reached Game Limit. Draw")

                    winners_z = np.zeros(len(current_players))
                    winners_z[np.array(current_players) == winner] = 0.0  #
                    winners_z[np.array(current_players) != winner] = 0.0  #

                    player.reset_player()
                    return 0, zip(states, mcts_probs, winners_z)

    def start_test_play(self, alpha_player, pure_player, is_shown=0, temp=1e-3, first=1):
        if first == 1 or first == 3:
            self.reset(first_player=1, second_player=2)
        else:
            self.reset(first_player=2, second_player=1)

        time_step = 0

        while (1):

            time_step += 1

            tic = time.time()
            if self.current_player == 1:
                move, move_probs = alpha_player.choose_action(self, temp=temp, return_prob=1, time_step=time_step)
                print("turn %s" % time_step)
                print('[Move probs]\n', move_probs[:12])
                print('[Wall probs]\n', move_probs[12:])
                print("alpha_player chose move : %s, prob: %.3f" % (move, move_probs[move]))
            else:
                move = pure_player.choose_action(self)
                print("pure_player chose move : %s" % (move))
            toc = time.time()

            print("spend: %.2f seconds" % (toc - tic))

            self.step(move)

            dist1, dist2 = self.get_shortest_path()
            print("Player 1 Shortest Path: {}, Player 2 Shortest Path: {}".format(dist1, dist2))

            self.print_board()
            # if is_shown:
            #     self.graphic(self.board, p1, p2)
            end, winner = self.has_a_winner()

            if end:
                alpha_player.reset_player()
                pure_player.reset_player()

                return winner
            else:
                if time_step > TURN_LIMIT:
                    print("Reached Game Limit.")

                    alpha_player.reset_player()
                    pure_player.reset_player()
                    return 0


import numpy as np
from is_wire.core import Channel, Message, Subscription
from is_msgs.image_pb2 import Vertex, ObjectAnnotations
from is_msgs.camera_pb2 import FrameTransformation
from utils import to_np

class TransformationFetcher:
  def __init__(self, broker_uri=None):
    self.channel = Channel() if broker_uri is None else Channel(broker_uri)
    self.subscription = Subscription(self.channel)
    self.transformations = {}

  def get_transformation(self, _from, _to):
    if _from in self.transformations and _to in self.transformations[_from]:
        return self.transformations[_from][_to]
    if self._request_transformation(_from, _to):
      return self.transformations[_from][_to]
    return None

  def _request_transformation(self, _from, _to):
    topic = 'FrameTransformation.{}.{}'.format(_from, _to)
    self.subscription.subscribe(topic)
    try:
      msg = self.channel.consume(timeout=5.0)
      self.subscription.unsubscribe(topic)
    except:
      self.subscription.unsubscribe(topic)
      return False
    transformation = msg.unpack(FrameTransformation)
    if _from not in self.transformations:
      self.transformations[_from] = {}
    self.transformations[_from][_to] = to_np(transformation.tf)
    return True

def vertex_to_np(v, homogeneo=False):
    if homogeneo:
        return np.array([v.x, v.y, v.z, 1.0])
    else:
        return np.array([v.x, v.y, v.z])

def np_to_vertex(v):
    return Vertex(x=v[0], y=v[1], z=v[2])

def transform_vertex(v, tf):
  new_v = np.matmul(tf, vertex_to_np(v, homogeneo=True))
  return np_to_vertex(new_v)

def transform_object_annotations(objs, tf, ref_id):
  new_objs = ObjectAnnotations(frame_id=ref_id)
  for obj in objs.objects:
    new_obj = new_objs.objects.add()
    for keypoint in obj.keypoints:
      new_keypoint = new_obj.keypoints.add()
      new_keypoint.id = keypoint.id
      new_keypoint.position.CopyFrom(transform_vertex(keypoint.position, tf))
  return new_objs


new_line = False
while True:
	words = []
	bigger_len = 0

	test = int(input())
	if test == 0:
		break
	else:
		for _ in range(test):
			words.append(input().strip())

		new_words = []
		for phrase in words:
			test_phrase = ''
			for char in phrase:
				if len(test_phrase) and char == test_phrase[-1] and char == ' ':
					continue
				else:
					test_phrase += char
			else:
				new_words.append(test_phrase)

		for word in new_words:
			if len(word) > bigger_len:
				bigger_len = len(word)

		if new_line:
			print()

		for word in new_words:
			print(" "*(bigger_len - len(word)) + word)

	new_line = True


import numpy as np

from .autoplumber import AutoPlumber

class PretrainedModel:
    """A pretrained model, built using scivision configuration file."""

    def __init__(self, config: dict):
        self._config = config
        self._plumbing = AutoPlumber(config)

    def predict(self, X: np.ndarray, *args, **kwargs):
        """Run the prediction."""
        # note, we may need to pass other kwargs to the prediction here
        return self._plumbing(X, **kwargs)

    def __repr__(self):
        """Return a nice representation of the model."""
        return (
            f"scivision.PretrainedModel( \n"
            f"  module='{self._plumbing.module.__name__}', \n"
            f"  model='{self._plumbing.model.__class__.__name__}', \n"
            f"  source='{self._config['url']}' \n"
            f"  pipe='{self._plumbing.pipe}' \n)"
        )


import unittest

from flask import Flask, request

app = Flask(__name__)

@app.route('/')
def index():
    return unicode(request.referrer or '')

class TestReferrer(unittest.TestCase):

    def test(self):
        c = app.test_client()
        resp = c.get('/', headers={'Referer': '/somethingelse'})
        self.assertEqual('/somethingelse', resp.data)

    def test_empty(self):
        c = app.test_client()
        resp = c.get('/')
        self.assertEqual('', resp.data)

    def test_regex(self):
        from attp import get_domain

        urls = {
            'https://medium.com/famous-blog/': 'medium.com',
            'https://medium.com/': 'medium.com',
            'http://www.medium.com': 'www.medium.com',
            '/verdura': None,
            None: None
        }

        for url, domain in urls.items():
            self.assertEqual(get_domain(url), domain)

if __name__ == '__main__':
    unittest.main()


from enstaller.egg_meta import split_eggname
from enstaller.errors import EnpkgError
from enstaller.repository import egg_name_to_name_version

from .resolve import Resolve

class Solver(object):
    def __init__(self, remote_repository, top_installed_repository,
                 mode='recur', force=False, forceall=False):
        self._remote_repository = remote_repository
        self._top_installed_repository = top_installed_repository

        self.mode = mode
        self.force = force
        self.forceall = forceall

    def resolve(self, request):
        operations = []

        for job in request.jobs:
            if job.kind == "install":
                operations.extend(self._install(job.requirement))
            elif job.kind == "remove":
                operations.extend(("remove", p) for p in
                                  self._remove(job.requirement))
            else:
                raise ValueError("Unsupported job kind: {0}".format(job.kind))

        return operations

    def _install(self, requirement):
        eggs = Resolve(self._remote_repository).install_sequence(requirement,
                                                                 self.mode)
        return self._install_actions(eggs, self.mode, self.force,
                                     self.forceall)

    def _remove(self, requirement):
        if requirement.version and requirement.build:
            full_version = "{0}-{1}".format(requirement.version,
                                            requirement.build)
        else:
            full_version = None
        packages = self._top_installed_repository.find_packages(
            requirement.name, full_version)
        if len(packages) == 0:
            raise EnpkgError("package %s not installed" % (requirement, ))
        return [packages[0].key]

    def _install_actions(self, eggs, mode, force, forceall):
        if not self.forceall:
            # remove already installed eggs from egg list
            if self.force:
                eggs = self._filter_installed_eggs(eggs[:-1]) + [eggs[-1]]
            else:
                eggs = self._filter_installed_eggs(eggs)

        # remove packages with the same name (from first egg collection
        # only, in reverse install order)
        res = []
        for egg in reversed(eggs):
            name = split_eggname(egg)[0].lower()
            installed_packages = self._top_installed_repository.find_packages(name)
            assert len(installed_packages) < 2
            if len(installed_packages) == 1:
                installed_package = installed_packages[0]
                res.append(('remove', installed_package.key))
        for egg in eggs:
            res.append(('install', egg))
        return res

    def _filter_installed_eggs(self, eggs):
        """ Filter out already installed eggs from the given egg list.

        Parameters
        ----------
        eggs: seq
            List of egg filenames
        """
        filtered_eggs = []
        for egg in eggs:
            name, _ = egg_name_to_name_version(egg)
            for installed in self._top_installed_repository.find_packages(name):
                if installed.key == egg:
                    break
            else:
                filtered_eggs.append(egg)
        return filtered_eggs


import itertools
import matplotlib.pyplot as plt

colors = itertools.cycle(['r','g','b','c','y','m','k'])
markers = itertools.cycle(['o','s','v'])

import pylab
from pylab import arange,pi,sin,cos,sqrt
def setup_pylab_fig(scale = 2, heightmult=1):
    import pylab
    from pylab import arange,pi,sin,cos,sqrt
    fig_width_pt = 390.0  # Get this from LaTeX using \showthe\columnwidth
    inches_per_pt = 1.0/72.27               # Convert pt to inch
    golden_mean = (sqrt(5)-1.0)/2.0         # Aesthetic ratio
    fig_width = scale*fig_width_pt*inches_per_pt  # width in inches
    fig_height = fig_width*golden_mean      # height in inches
    fig_size =  [fig_width,fig_height*heightmult]
    params = {'backend': 'ps',
       'axes.labelsize': scale*10,
      'text.fontsize': scale*10,
      'legend.fontsize': scale*10,
      'xtick.labelsize': scale*8,
      'ytick.labelsize': scale*8,
      'text.usetex': True,
      'figure.figsize': fig_size}
    pylab.rcParams.update(params)
    # Generate data
    # Plot data
    pylab.figure(1)
    pylab.clf()


#!/usr/bin/env python
#-*- coding=utf-8 -*-

#Pi_cal
from math import sqrt
from random import random
from time import clock
all = 12000000000  #这个数越大精确度越高
hits = 0
clock()
for i in range(1,all):
    x, y = random(), random()
    area = sqrt(x**2 + y**2)
    if area <= 1.0:
        hits = hits + 1
        #print(hits)
Pi = 4 * (hits/all)
print("圆周率为：%.10f"%Pi)
print("所用时间为：%.5ss"%clock())


import pandas as pd
import numpy as np
import networkx as nx
import matplotlib.pyplot as plt

df = pd.read_csv('network.csv')

#top 20
data = df.groupby(['node'], sort=True).count().reset_index().sort_values('users', ascending=False).head(20)['node'].values

plt.figure(3,figsize=(12,12))
G = nx.from_pandas_edgelist(df, 'node', 'users')
nx.draw_spring(G, with_labels=False, node_size=20, font_size=9, width=0.1)

labels={}
for node in G.nodes():
	if node in data:
		labels[node]=node

nx.draw_networkx_labels(G, pos=nx.spring_layout(G), labels=labels)
plt.show()


from django.test import TestCase

from django.conf import settings
from django.core.management import call_command
from django.db import models
from django.db.models import loading

from proj.actions_logger.models import Record
from proj.actions_logger import signals

class TestModel(models.Model):
    field = models.CharField(max_length=10)

class SignalsTestCase(TestCase):
    """
    Test signal for saving object.
    """
    def test_signals_received(self):
        t = TestModel(field="test1")
        t.save()
        for record in Record.objects.all():
            if 'TestModel object was created' in record.note:
                break
        else:
            self.fail("No record on create")
        t.field = 'field2'
        t.save()
        for record in Record.objects.all():
            if 'TestModel object was updated' in record.note:
                break
        else:
            self.fail("No record on update")
        t.delete()
        for record in Record.objects.all():
            if 'TestModel object was deleted' in record.note:
                break
        else:
            self.fail("No record on delete")


"""
This script computes the R² of 700hPa dT/dt and dq/dt of the cVAE
"""

from tensorflow.keras.layers import Lambda, Input, Dense, Concatenate
from cbrain.layers import *
from tensorflow.keras.models import Model
from tensorflow.keras.losses import mse, binary_crossentropy
from tensorflow.keras.utils import plot_model
from tensorflow.keras import backend as K
from tensorflow.keras.callbacks import LearningRateScheduler,Callback

import numpy as np
import matplotlib.pyplot as plt
import argparse
import os

import tensorflow as tf
from cbrain.imports import *

from cbrain.utils import *
import pandas as ps

# reparameterization trick
# instead of sampling from Q(z|X), sample epsilon = N(0,I)
# z = z_mean + sqrt(var) * epsilon
def sampling(args):
    """Reparameterization trick by sampling from an isotropic unit Gaussian.

    # Arguments
        args (tensor): mean and log of variance of Q(z|X)

    # Returns
        z (tensor): sampled latent vector

    based on VAE presented on keras webpage for keras version 1 /
    recent keras VAE version can be seen on
    https://keras.io/examples/generative/vae/

    """

    z_mean, z_log_var = args
    batch= K.shape(z_mean)[0]
    dim=K.int_shape(z_mean)[1]
    # by default, random_normal has mean = 0 and std = 1.0
    epsilon=K.random_normal(shape=(batch,dim)) # epsilion= random_normal distributed tensor
    sample_prob=z_mean+K.exp(0.5*z_log_var)*epsilon #exp= elementwise exponential
    return sample_prob

# kl annealing for increase in reproduction skill of cVAE
klstart = 2
# number of epochs over which KL scaling is increased from 0 to 1
kl_annealtime = 5

class AnnealingCallback(Callback):
    def __init__(self, weight):
        self.weight = weight
    def on_epoch_end (self, epoch, logs={}):
        if epoch > klstart :
            new_weight = min(K.get_value(self.weight) + (1./kl_annealtime), 1.)
            K.set_value(self.weight, new_weight)
        print ("Current KL Weight is " + str(K.get_value(self.weight)))

# the initial value of weight is 0
# define it as a keras backend variable
weight = K.variable(0.)

original_dim_input=int(65+64)  # cVAE is trained on SP and CAM variables

original_dim_output=65 # and reproduces SP variables

# network parameters

intermediate_dim = 457 # number of nodes in first / last hidden layers of Encoder / Decoder
batch_size = 666
latent_dim = 5 # latent space width of signals passed trough encoder
epochs = 40

# network parameters
input_shape = (original_dim_input,)
out_shape=(original_dim_output,)
large_scale_fields=64

latent_dim_cond = int(latent_dim+large_scale_fields)# node size of latent space nodes + initial CAM variables --> input to decoder

## Encoder
inputs =Input(shape=input_shape, name='encoder_input')

x_0 =Dense(intermediate_dim, activation='relu')(inputs)
x_1 =Dense(intermediate_dim, activation='relu')(x_0)
x_2 =Dense(int(np.round(intermediate_dim/2)), activation='relu')(x_1)
x_3 =Dense(int(np.round(intermediate_dim/4)), activation='relu')(x_2)
x_4 =Dense(int(np.round(intermediate_dim/8)), activation='relu')(x_3)
x_5 =Dense(int(np.round(intermediate_dim/16)), activation='relu')(x_4)

z_mean = Dense(latent_dim, name='z_mean')(x_5)
z_log_var = Dense(latent_dim, name='z_log_var')(x_5)

# reparametrization trick
z = Lambda(sampling, output_shape=(latent_dim), name='z')([z_mean, z_log_var])

z_cond=Concatenate()([z,inputs[:,65:129]]) #here latent nodes and CAM variables are merged

# instantiate encoder model
encoder = Model([inputs], [z_mean, z_log_var,z, z_cond], name='encoder')
#output of encoder is mean, log-var, latent nodes z and (z+CAM) variables
encoder.summary()

##conditional Decoder
decoder_inputs =Input(shape=(latent_dim_cond,), name='decoder_input') # has 69 input nodes due to combination of z and CAM variables

x_1 =Dense(int(np.round(intermediate_dim/16)), activation='relu')(decoder_inputs)
x_2 =Dense(int(np.round(intermediate_dim/8)), activation='relu')(x_1)
x_3 =Dense(int(np.round(intermediate_dim/4)), activation='relu')(x_2)
x_4 =Dense(int(np.round(intermediate_dim/2)), activation='relu')(x_3)
x_5 =Dense(intermediate_dim, activation='relu')(x_4)
x_6 =Dense(intermediate_dim, activation='relu')(x_5)
outputs = Dense(original_dim_output, activation='elu')(x_6)

decoder = Model([decoder_inputs], outputs, name='decoder')
decoder.summary()
emul_cond_outputs=decoder(encoder([inputs])[3])
kl_loss = 1 + z_log_var - K.square(z_mean) - K.exp(z_log_var)
kl_loss = K.sum(kl_loss, axis=-1)
kl_loss *= -0.5
VAE_loss = K.mean(kl_loss*weight)

cond_VAE=Model(inputs,emul_cond_outputs)
cond_VAE.add_loss(VAE_loss)
cond_VAE.add_metric(kl_loss, name='kl_loss', aggregation='mean')

#loading scaling dictionary for SP variables
scale_array_2D=ps.read_csv('nn_config/scale_dicts/Scaling_enc_II_range_profiles.csv')
scale_array_1D=ps.read_csv('nn_config/scale_dicts/Scaling_enc_II_range.csv')

TBP_std_surf=scale_array_2D.TBP_std.values[-1]

QBP_std_surf=scale_array_2D.QBP_std.values[-1]

Q_lat_std_surf=scale_array_1D.Q_lat_std.values

Q_sens_std_surf=scale_array_1D.Q_sens_std.values

Q_solar_std_surf=scale_array_1D.Q_sol_std.values

PS_std_surf=scale_array_1D.PS_std.values

# resulting scaling dictionary
scale_dict_II = {
    'PHQ': 1/PHQ_std_surf,
    'TPHYSTND': 1/TPHYSTND_std_23,
    'FSNT': 1/FSNT_std,
    'FSNS': 1/FSNS_std,
    'FLNT': 1/FLNT_std,
    'FLNS': 1/FLNS_std,
    'PRECT': 1/PRECT_std
}

out_vars = ['PHQ','TPHYSTND','FSNT', 'FSNS', 'FLNT', 'FLNS', 'PRECT']
in_vars = ['PHQ','TPHYSTND','FSNT', 'FSNS', 'FLNT', 'FLNS', 'PRECT','QBP', 'TBP','PS', 'SOLIN', 'SHFLX', 'LHFLX']

# Takes representative value for PS since purpose is normalization
PS = 1e5; P0 = 1e5;
P = P0*hyai+PS*hybi; # Total pressure [Pa]
dP = P[1:]-P[:-1];

from cbrain.data_generator import DataGenerator

val_gen_II = DataGenerator(
    data_fn = '../preprocessed_data/1918_train_3_month_OND.nc',
    input_vars = in_vars,
    output_vars = out_vars,
    norm_fn = '../preprocessed_data/000_norm_1_month.nc',
    input_transform = ('mean', 'maxrs'),
    output_transform = scale_dict_II,
    batch_size=8192,
    shuffle=True
)

cond_VAE.load_weights('saved_models/cVAE/New_Cond_VAE_40_opt_anneal.h5')

X=np.nan*np.zeros((4415,8192,129))
Y=np.nan*np.zeros((4415,8192,65))
for i in np.arange(X[:,1,1].size):
    X[i],Y[i]=val_gen_II[i]
    print(i)

X_=np.reshape(X,(4415*8192,129))
Y_=np.reshape(Y,(4415*8192,65))

Y_emul=val_gen_II.output_transform.inverse_transform(cond_VAE.predict(X_))
Y_real=val_gen_II.output_transform.inverse_transform(Y_)

lat=np.arange(-90,90,180/64)
lon=np.arange(-180,180,360/128)
time=4415

## dT/dt ID [30:60]
## dq/dt ID [0:30] in SPCAM data set

T_tend_real=np.reshape(Y_real[:,30:60],(time,lat.size,lon.size,Y_real[1,30:60].size))
T_tend_emul=np.reshape(Y_emul[:,30:60],(time,lat.size,lon.size,Y_real[1,30:60].size))
Q_tend_real=np.reshape(Y_real[:,0:30],(time,lat.size,lon.size,Y_real[1,30:60].size))
Q_tend_emul=np.reshape(Y_emul[:,0:30],(time,lat.size,lon.size,Y_real[1,30:60].size))

T_tend_real_long_mean=np.mean(T_tend_real,2)
T_tend_emul_long_mean=np.mean(T_tend_emul,2)
Q_tend_real_long_mean=np.mean(Q_tend_real,2)
Q_tend_emul_long_mean=np.mean(Q_tend_emul,2)

T_tend_R_2_700=np.nan*np.zeros((lat.size,lon.size))
Q_tend_R_2_700=np.nan*np.zeros((lat.size,lon.size))

## compute R² values on 700hPa

T_tend_R_2_700=1-np.mean((np.squeeze(T_tend_real[:,:,:,20])-np.squeeze(T_tend_emul[:,:,:,20]))**2,0)/np.var(np.squeeze(T_tend_real[:,:,:,20]),0)
Q_tend_R_2_700=1-np.mean((np.squeeze(Q_tend_real[:,:,:,20])-np.squeeze(Q_tend_emul[:,:,:,20]))**2,0)/np.var(np.squeeze(Q_tend_real[:,:,:,20]),0)

np.save('R_2_val/CVAE_T_tend_R_2_700',T_tend_R_2_700)
np.save('R_2_val/CVAE_Q_tend_R_2_700',Q_tend_R_2_700)


# Copyright 2018 The TensorFlow Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ==============================================================================
"""Mask-RCNN anchor definition."""

from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

import tensorflow.compat.v1 as tf
from REDACTED.mask_rcnn import box_utils
from REDACTED.mask_rcnn import non_max_suppression

def generate_detections_per_image_op(
    cls_outputs, box_outputs, anchor_boxes, image_id, image_info,
    num_detections=100, pre_nms_num_detections=1000, nms_threshold=0.3,
    bbox_reg_weights=(10., 10., 5., 5.)):
  """Generates detections with model outputs and anchors.

  Args:
    cls_outputs: a Tensor with shape [N, num_classes], which stacks class
      logit outputs on all feature levels. The N is the number of total anchors
      on all levels. The num_classes is the number of classes predicted by the
      model. Note that the cls_outputs should be the output of softmax().
    box_outputs: a Tensor with shape [N, num_classes*4], which stacks
      box regression outputs on all feature levels. The N is the number of total
      anchors on all levels.
    anchor_boxes: a Tensor with shape [N, 4], which stacks anchors on all
      feature levels. The N is the number of total anchors on all levels.
    image_id: an integer number to specify the image id.
    image_info: a tensor of shape [5] which encodes the input image's [height,
      width, scale, original_height, original_width]
    num_detections: Number of detections after NMS.
    pre_nms_num_detections: Number of candidates before NMS.
    nms_threshold: a float number to specify the threshold of NMS.
    bbox_reg_weights: a list of 4 float scalars, which are default weights on
      (dx, dy, dw, dh) for normalizing bbox regression targets.
  Returns:
    detections: detection results in a tensor with each row representing
      [image_id, ymin, xmin, ymax, xmax, score, class]
  """
  num_boxes, num_classes = cls_outputs.get_shape().as_list()

  # Removes background class scores.
  cls_outputs = cls_outputs[:, 1:num_classes]
  top_k_scores, top_k_indices_with_classes = tf.nn.top_k(
      tf.reshape(cls_outputs, [-1]),
      k=pre_nms_num_detections,
      sorted=True)
  classes = tf.mod(top_k_indices_with_classes, num_classes - 1)
  top_k_indices = tf.floordiv(top_k_indices_with_classes, num_classes - 1)

  anchor_boxes = tf.gather(anchor_boxes, top_k_indices)
  box_outputs = tf.reshape(
      box_outputs, [num_boxes, num_classes, 4])[:, 1:num_classes, :]
  box_outputs = tf.gather_nd(box_outputs,
                             tf.stack([top_k_indices, classes], axis=1))

  # Applies bounding box regression to anchors.
  boxes = box_utils.batch_decode_box_outputs_op(
      tf.expand_dims(anchor_boxes, axis=0),
      tf.expand_dims(box_outputs, axis=0),
      bbox_reg_weights)[0]
  boxes = box_utils.clip_boxes(
      tf.expand_dims(boxes, axis=0), tf.expand_dims(image_info[:2], axis=0))[0]

  classes = tf.tile(tf.reshape(classes, [1, pre_nms_num_detections]),
                    [num_classes - 1, 1])
  scores = tf.tile(tf.reshape(top_k_scores, [1, pre_nms_num_detections]),
                   [num_classes - 1, 1])
  boxes = tf.tile(tf.reshape(boxes, [1, pre_nms_num_detections, 4]),
                  [num_classes - 1, 1, 1])

  class_bitmask = tf.tile(
      tf.reshape(tf.range(num_classes-1), [num_classes - 1, 1]),
      [1, pre_nms_num_detections])
  scores = tf.where(tf.equal(classes, class_bitmask), scores,
                    tf.zeros_like(scores))
  scores = tf.where(tf.greater(scores, 0.05), scores, tf.zeros_like(scores))
  # Reshape classes to be compartible with the top_k function.
  classes = tf.reshape(classes, [num_classes -1, pre_nms_num_detections, 1])
  scores, sorted_tensors = box_utils.top_k(
      scores, k=pre_nms_num_detections, tensors=[boxes, classes])
  boxes = sorted_tensors[0]
  classes = tf.reshape(sorted_tensors[1],
                       [num_classes - 1, pre_nms_num_detections])

  idx, num_valid = non_max_suppression.non_max_suppression_padded(
      scores, boxes, max_output_size=num_detections,
      iou_threshold=nms_threshold, level=0)

  post_nms_boxes = non_max_suppression.gather_boxes_by_indices(
      boxes, num_detections, idx, num_valid)
  post_nms_scores = non_max_suppression.gather_scores_by_indices(
      scores, num_detections, idx, num_valid)

  # Sorts all results.
  sorted_scores, sorted_indices = tf.nn.top_k(
      tf.to_float(tf.reshape(post_nms_scores, [-1])),
      k=num_detections,
      sorted=True)
  post_nms_boxes = tf.gather(tf.reshape(post_nms_boxes, [-1, 4]),
                             sorted_indices)
  classes = tf.batch_gather(classes, idx)
  post_nms_classes = tf.gather(tf.reshape(classes, [-1]), sorted_indices) + 1

  if isinstance(image_id, int):
    image_id = tf.constant(image_id)
  image_id = tf.reshape(image_id, [])
  detections_result = tf.stack(
      [
          tf.to_float(tf.fill(tf.shape(sorted_scores), image_id)),
          post_nms_boxes[:, 0],
          post_nms_boxes[:, 1],
          post_nms_boxes[:, 2],
          post_nms_boxes[:, 3],
          sorted_scores,
          tf.to_float(post_nms_classes),
      ],
      axis=1)
  return detections_result


# -*- coding: utf-8 -*-
# Copyright (c) 2014 Insight Centre.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#    http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
# implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""
docker_registry.drivers.hdfs
~~~~~~~~~~~~~~~~~~~~~~~~~~

This is a hadoop based hdfs driver.  It would be better to do this
with snakebite (https://github.com/spotify/snakebite) but it doesn't
yet support writing to hdfs.

"""

import logging
import os
import hadoopy
import pika
import shutil
import time
from hadoopy._hdfs import _checked_hadoop_fs_command
from snakebite.client import Client
from snakebite.client import HAClient
from snakebite.namenode import Namenode

from ..core import driver
from ..core import exceptions
from ..core import lru

# Hadoopy fs functions are... deficient.  Yes this is gross.  I'm sorry.

logger = logging.getLogger(__name__)

def hdfs_putf(local_path, hdfs_path):
    cmd = "hadoop fs -put -f %s %s" % (local_path, hdfs_path)
    rcode, stdout, stderr = _checked_hadoop_fs_command(cmd)

class Storage(driver.Base):

    #supports_bytes_range = True

    def __init__(self, path=None, config=None):
        self._root_path = path or '/registry'
        self._local_path = config.local_path or './local_registry'
        self._hdfs_ha_enable = config.hdfs_ha_enable
        if self._hdfs_ha_enable:
            self._hdfs_nn1_host = config.hdfs_nn1_host
            self._hdfs_nn1_port = config.hdfs_nn1_port
            self._hdfs_nn2_host = config.hdfs_nn2_host
            self._hdfs_nn2_port = config.hdfs_nn2_port
            logger.info("HDFS namenode 1 info: %s:%s" % (self._hdfs_nn1_host, self._hdfs_nn1_port))
            logger.info("HDFS namenode 2 info: %s:%s" % (self._hdfs_nn2_host, self._hdfs_nn2_port))
        else:
            self._hdfs_nn_host = config.hdfs_nn_host
            self._hdfs_nn_port = config.hdfs_nn_port
            logger.info("HDFS namenode info: %s:%s" % (self._hdfs_nn_host, self._hdfs_nn_port))
        self._need_sync = config.need_sync
        # If it is master, it needs to sync the data to slaves
        self._is_master = config.is_master
        if self._need_sync:
            if self._is_master:
                logger.info("Master storage node.")
                self._mq_queue = config.mq_queue
                self._mq_host = config.mq_host
                self._init_mq(self._mq_host, self._mq_queue)
            else:
                logger.info("Slave storage node.")
        else:
            logger.info("Not in sync mode.")

    def _init_path(self, path=None):
        if path:
            hdfs_path = os.path.join(self._root_path, path)
        else:
            hdfs_path = self._root_path
        local_path = os.path.join(self._local_path, path)
        return local_path, hdfs_path

    def _init_mq(self, mq_host, mq_queue):
        connection = pika.BlockingConnection(pika.ConnectionParameters(mq_host))
        channel = connection.channel()
        channel.queue_declare(queue=mq_queue, durable=True)
        self._channel = channel

    def _get_hdfs_client(self):
        if self._hdfs_ha_enable:
            nn1 = Namenode(self._hdfs_nn1_host, self._hdfs_nn1_port)
            nn2 = Namenode(self._hdfs_nn2_host, self._hdfs_nn2_port)
            return HAClient([nn1, nn2], use_trash=True)
        else:
            return Client(self._hdfs_nn_host, self._hdfs_nn_port)

    def _hdfs_exsits(self, path):
        hdfs_client = self._get_hdfs_client()
        return hdfs_client.test(path, exists=True)

    def _hdfs_mkdirp(self, path):
        hdfs_client = self._get_hdfs_client()
        xs = hdfs_client.mkdir([path], create_parent=True)
        ret = xs.next()
        result = ret["result"]
        if not result:
            logger.error('Failed to mkdir -p {0} : {1}'.format(path, ret["error"]))
        return result

    def _hdfs_rmr(self, path):
        hdfs_client = self._get_hdfs_client()
        xs = hdfs_client.delete([path], recurse=True)
        ret = xs.next()
        result = ret["result"]
        if not result:
            logger.error('Failed to delete {0} : {1}'.format(path, ret["error"]))
        return result

    def _hdfs_du(self, path):
        hdfs_client = self._get_hdfs_client()
        xs = hdfs_client.du([path], include_toplevel=True)
        ret = xs.next()
        return ret["length"]

    def _create_local(self, local_path):
        dirname = os.path.dirname(local_path)
        if not os.path.exists(dirname):
            os.makedirs(dirname)

    def _delete_local_file(self, local_file):
        if not os.path.exists(local_file):
            logger.warn("Try to delete local file %s does not exsit" % local_file)
        else:
            os.remove(local_file)

    def _create_hdfs(self, hdfs_path):
        dirname = os.path.dirname(hdfs_path)
        v = self._get_exists(dirname)
        if v is None:
            self._hdfs_mkdirp(dirname)
            self._record_exists(dirname, "True")
            return True
        else:
            return str(v) == 'True'

    def _send_msg(self, msg):
        logger.info(msg)
        while True:
            try:
                self._channel.basic_publish(exchange='',
                                            routing_key=self._mq_queue,
                                            body=msg,
                                            properties=pika.BasicProperties(
                                                delivery_mode=2. # make message persistent
                                            ))
                return
            except Exception as e:
                logger.error(e)
                self._init_mq(self._mq_host, self._mq_queue)
                time.sleep(10)

    def _sync_with_slaves(self, path, operation):
        if not self._need_sync:
            return
        else:
            if self._is_master:
                logger.info("Sync with slaves : %s %s" % (operation, path))
            else:
                logger.error("MUST NOT %s %s on slaves" % (operation, path))
                return
        if path.split('/')[-1] != "_inprogress":
            if path[0] != '/':
                path = self._init_path(path)[1]
            self._send_msg(operation + " " + path)
        else:
            logger.info("Not sync file %s" % path)

    def _is_layer(self, path):
        return path.split('/')[-1] == "layer"

    def _get_key(self, path, key):
        return lru.cache_key(path + "/" + str(key))

    def _record_size(self, path, size):
        lru.set_key_val(self._get_key(path, "size"), size)

    def _delete_size(self, path):
        lru.remove_key(self._get_key(path, "size"))

    def _get_size(self, path):
        return lru.get_by_key(self._get_key(path, "size"))

    def _record_exists(self, path, val):
        lru.set_key_val(self._get_key(path, "exists"), val)

    def _delete_exists(self, path):
        lru.remove_key(self._get_key(path, "exists"))

    def _get_exists(self, path):
        return lru.get_by_key(self._get_key(path, "exists"))

    def _put_local_to_hdfs(self, path, local_path, hdfs_path):
        self._create_hdfs(hdfs_path)
        hdfs_putf(local_path, hdfs_path)
        self._record_size(path, os.path.getsize(local_path))
        self._record_exists(path, True)
        self._delete_local_file(local_path)
        self._sync_with_slaves(path, "ADD")

    @lru.get
    def get_content(self, path):
        try:
            buf = ""
            for content in self.stream_read(path):
                buf += content
        except Exception as e:
            logger.error(e)
            raise exceptions.FileNotFoundError('%s is not there' % path)
        return buf

    @lru.set
    def put_content(self, path, content):
        local_path, hdfs_path = self._init_path(path)
        self._create_local(local_path)
        with open(local_path, mode='wb') as f:
            f.write(content)
        self._put_local_to_hdfs(path, local_path, hdfs_path)
        return hdfs_path

    def stream_read(self, path, bytes_range=None):
        hdfs_path = (self._init_path(path))[1]

        try:
            hdfs_client = self._get_hdfs_client()
            xs = hdfs_client.cat([hdfs_path])
            for content in xs.next():
                yield content
        except Exception as e:
            logger.error(e)
            raise exceptions.FileNotFoundError('%s is not there' % path)

    def stream_write(self, path, fp):
        # Size is mandatory
        local_path, hdfs_path = self._init_path(path)
        self._create_local(local_path)
        with open(local_path, mode='wb') as f:
            try:
                while True:
                    buf = fp.read(self.buffer_size)
                    if not buf:
                        break
                    f.write(buf)
            except IOError as e:
                logger.error(e)
                pass
        self._put_local_to_hdfs(path, local_path, hdfs_path)

    def list_directory(self, path=None):
        hdfs_path = (self._init_path(path))[1]
        try:
            hdfs_client = self._get_hdfs_client()
            return [x["path"] for x in hdfs_client.ls([hdfs_path])]
        except Exception as e:
            logger.error(e)
            raise exceptions.FileNotFoundError('%s is not there' % path)

    def exists(self, path):
        hdfs_path = (self._init_path(path))[1]

        v = self._get_exists(path)
        if v is None:
            v = self._hdfs_exsits(hdfs_path)
            self._record_exists(path, v)

        return str(v) == 'True'

    @lru.remove
    def remove(self, path):
        hdfs_path = (self._init_path(path))[1]
        try:
            self._hdfs_rmr(hdfs_path)
            self._delete_size(path)
            self._delete_exists(path)
            self._delete_exists(os.path.dirname(hdfs_path))
        except Exception as e:
            logger.error(e)
            raise exceptions.FileNotFoundError('%s is not there' % path)
        self._sync_with_slaves(hdfs_path, "DEL")

    def get_size(self, path):
        size = self._get_size(path)
        if size:
            return size

        hdfs_path = (self._init_path(path))[1]

        try:
            size = self._hdfs_du(hdfs_path)
            self._record_size(path, size)
            return size
        except Exception as e:
            logger.error(e)
            raise exceptions.FileNotFoundError('%s is not there' % path)

    def is_private(self, namespace, repository):
        return False

#
# Editor modelines  -  http://www.wireshark.org/tools/modelines.html
#
# Local variables:
# c-basic-offset: 4
# tab-width: 8
# indent-tabs-mode: nil
# End:
#
# vi: set shiftwidth=4 tabstop=8 expandtab:
# :indentSize=4:tabSize=8:noTabs=true:
#


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

import hmac
import hashlib
import time
import requests
from cryptotik.common import APIError, headers, ExchangeWrapper
from re import findall
from decimal import Decimal

class TheRock(ExchangeWrapper):

    url = 'https://api.therocktrading.com/v1/'
    delimiter = ""
    headers = headers

    def __init__(self, apikey=None, secret=None, timeout=None, proxy=None):
        '''initialize bittrex class'''

        if apikey and secret:
            self.apikey = apikey.encode("utf-8")
            self.secret = secret.encode("utf-8")

        if proxy:
            assert proxy.startswith('https'), {'Error': 'Only https proxies supported.'}
        self.proxy = {'https': proxy}

        if not timeout:
            self.timeout = (8, 15)
        else:
            self.timeout = timeout

        self.api_session = requests.Session()

    @classmethod
    def format_pair(self, pair):
        """format the pair argument to format understood by remote API."""

        return "".join(findall(r"[^\W\d_]+|\d+", pair)).upper()

    def api(self, url):
        '''call api'''

        try:
            result = self.api_session.get(url, headers=self.headers,
                                          timeout=self.timeout, proxies=self.proxy)
            assert result.status_code == 200
            return result.json()

        except requests.exceptions.RequestException as e:
            raise APIError(e)

    def get_market_ticker(self, pair):
        '''returns simple current market status report'''

        return self.api(self.url + "funds/" + self.format_pair(pair) + "/ticker")

    def get_market_trade_history(self, pair, limit=10):
        '''get market trade history'''

        return self.api(self.url + "funds/" + self.format_pair(pair) + "/trades" +
                                "?per_page={}".format(limit))['trades']

    def get_market_orders(self, pair):
        '''return order book for the market'''

        return self.api(self.url + "funds/" + self.format_pair(pair) + "/orderbook")

    def get_market_spread(self, pair):
        '''return first buy order and first sell order'''

        order_book = self.get_market_orders(pair)

        ask = order_book["asks"][0]['price']
        bid = order_book["bids"][0]['price']

        return Decimal(ask) - Decimal(bid)

    def get_market_depth(self, pair):
        '''return sum of all bids and asks'''

        ob = self.get_market_orders(pair)
        return {"bids": Decimal(ob['bids'][-1]['depth']),
                "asks": Decimal(ob['asks'][-1]['depth'])}

    def get_markets(self):
        '''Find supported markets on this exchange'''

        r = self.api(self.url + "funds")['funds']
        pairs = [i["id"].lower() for i in r]

        return pairs

    def get_market_volume(self, pair):
        ''' return volume of last 24h'''

        return self.get_market_ticker(self.format_pair(pair))["volume"]

    def private_api(self, url, http_method='GET', params={}):
        '''handles private api methods'''

        if not self.apikey or not self.secret:
            raise ValueError("A Key and Secret needed!")

        nonce = str(self.get_nonce())
        if params:
            url += "?" + requests.compat.urlencode(sorted(params.items()))
        nonce_plus_url = str(nonce) + url
        signature = hmac.new(self.secret,
                             nonce_plus_url.encode("utf-8"),
                             hashlib.sha512).hexdigest()

        head = {"Content-Type": "application/json",
                "X-TRT-KEY": self.apikey,
                "X-TRT-SIGN": signature,
                "X-TRT-NONCE": nonce}

        try:
            result = self.api_session.request(http_method, url, headers=head,
                                              proxies=self.proxy)
            assert result.status_code == 200, {'error: ' + str(result.json())}
        except requests.exceptions.RequestException as e:
            raise APIError(e)

        return result.json()

    def get_nonce(self):
        '''return nonce integer'''

        nonce = getattr(self, '_nonce', 0)
        if nonce:
            nonce += 1
        # If the unix time is greater though, use that instead (helps low
        # concurrency multi-threaded apps always call with the largest nonce).
        self._nonce = max(int(time.time()), nonce)
        return self._nonce

    def get_balances(self):
        """get all balances from your account"""

        balances = self.private_api(self.url + "balances")
        return [i for i in balances['balances'] if i["trading_balance"] != 0.0]

    def get_deposit_address(self, currency):
        ''' get deposit address for <currency> '''

        return self.private_api(self.url + "currencies/" + currency.upper() +
                                "/addresses",
                                http_method='GET',
                                params={'unused': 'true'})

    def buy(self, pair, price, quantity):
        '''creates buy order for <pair> at <price> for <quantity>'''

        return self.private_api(self.url + "funds/"
                                + self.format_pair(pair) + "/orders",
                                params={'fund_id': self.format_pair(pair),
                                    'side': 'buy', 'amount': quantity,
                                    'price': price},
                                http_method='POST')

    def sell(self, pair, price, quantity):
        '''creates sell order for <pair> at <price> for <quantity>'''

        return self.private_api(self.url + "funds/"
                                + self.format_pair(pair) + "/orders",
                                params={'fund_id': self.format_pair(pair),
                                    'side': 'sell', 'amount': quantity,
                                    'price': price},
                                http_method='POST')

    def withdraw(self, coin, amount, address):
        '''withdraw <coin> <amount> to <address> with <address_tag> if needed'''

        return self.private_api(self.url + "atms/withdraw",
                                params={'currency': coin.upper(),
                                        'destination_address': address,
                                        'amount': amount},
                                http_method='POST')

    def get_withdraw_history(self, currency=None):
        '''Retrieves withdrawal history.'''

        if currency:
            transactions = self.private_api(self.url + "transactions",
                                        params={'currency': currency.upper()})["transactions"]
        else:
            transactions = self.private_api(self.url + "transactions")["transactions"]

        return [i for i in transactions if i["type"] == "withdraw"]

    def get_deposit_history(self, currency=None):
        '''Retreive deposit history.'''

        if currency:
            transactions = self.private_api(self.url + "transactions",
                                        params={'currency': currency})["transactions"]
        else:
            transactions = self.private_api(self.url + "transactions")["transactions"]

        return [i for i in transactions if i["type"] == "atm_payment"]

    def get_open_orders(self, pair=None):
        '''get open orders for <pair>
           or all open orders if called without an argument.'''

        if not pair:
            all_pairs=[]
            for market in self.get_markets():
                all_pairs += self.private_api(self.url + "funds/" +
                                            self.format_pair(market) + "/orders")
                return all_pairs
        else:
            return self.private_api(self.url + "funds/" + self.format_pair(pair)
                                    + "/orders")["orders"]

    def get_order(self, symbol, order_id):
        """retrieve a single order by orderId."""

        return self.private_api(self.url + "funds/" + symbol + "/orders/" + order_id,
                                http_method='GET')

    def cancel_order(self, order_id, symbol):
        """cancel order with <order_id> for <symbol>"""

        return self.private_api(self.url + "funds/" + symbol +
                                "/orders/" + order_id,
                                http_method='DELETE')

    def cancel_all_orders(self, symbol):
        """cancel all orders for <symbol> """

        return self.private_api(self.url + "funds/" + symbol +
                                "/orders/remove_all",
                                http_method='DELETE')


T = int(input())
stairs = [0]*(T+1)
for i in range(1,T+1):
    stairs[i] = int(input())
D = [0]*(T+1)
D[1]=stairs[1]
D[2]=stairs[2]+stairs[1]
for i in range(3,T+1):
    D[i]=max(stairs[i]+stairs[i-1]+D[i-3],stairs[i]+D[i-2])

print(D[-1])
'''
recursive
def upStairs(start, prev):
    if start>T:
        return -3000000
    elif start==T:
        return stairs[-1]
    elif prev==0:
        return stairs[start]+max(upStairs(start+1,1),upStairs(start+2,0))
    elif prev==1:
        return stairs[start]+upStairs(start+2,0)
print(max(upStairs(1,0),upStairs(2,0)))'''


# -*- coding: utf-8 -*-
# 栈的应用：颠倒序列 O(n)

from SequenceStack import SStack

def ListReverse(lst):
    ss = SStack()
    lst2 = list()
    for x in lst:
        ss.push(x)
    while not ss.is_empty():
        lst2.append(ss.pop_())
    return lst2

if __name__ == "__main__":
    lstOrigin = [1, 2, 3, 4, 5, 6]
    print(ListReverse(lstOrigin))


# -*- coding: utf-8 -*-
"""
Created on Sat Feb  2 14:34:53 2019

@author: victo
"""

import tensorflow as tf

import numpy as np

a = np.zeros((3,3))

ta = tf.convert_to_tensor(a)

sess = tf.Session()

print(sess.run(ta))

input1 = tf.placeholder(tf.float32) ### input1 : 占位符

input2 = tf.placeholder(tf.float32) ### input2 : 占位符

output = tf.multiply(input1,input2)

s = sess.run([output],feed_dict={input1:[7.],input2:[5.]})

print(s)


import cherrypy
import json

class HelloWorld(object):
    @cherrypy.expose
    def index(self, **params):
        return "Hello World!"
        print(params)

def object_to_json(object):
    # converts everything it doesn't know to strings. stackoverflow.com/questions/11875770/
    j = json.dumps([ob.__dict__ for ob in object], indent=4, sort_keys=True, default=str)
    return j

cherrypy.quickstart(HelloWorld())


from bs4 import BeautifulSoup
import requests

response = requests.get("https://news.ycombinator.com/")

yc_webpage = response.text

soup = BeautifulSoup(yc_webpage, "html.parser")

articles = soup.find_all(name="a", class_="storylink")
article_texts = []
article_links = []

for article_tag in articles:
    text = article_tag.get_text()
    article_texts.append(text)
    link = article_tag.get("href")
    article_links.append(link)
article_upvotes = [int(score.getText().split()[0]) for score in soup.find_all(name="span", class_="score")]

# print(article_texts)
# print(article_links)
# print(article_upvotes)

largest_number = max(article_upvotes)
print(largest_number)
largest_index = article_upvotes.index(largest_number)
print(article_texts[largest_index])

#----------------------------------------- Scraping website from local

# with open("website.html") as file:
#     contents = file.read()
#
# soup = BeautifulSoup(contents, 'html.parser')
#
# # print(soup.prettify())
# # print(soup.title)
# # print(soup.title.string)
#
# all_anchor_tags = soup.find_all(name="a")
# print(all_anchor_tags)
#
# for tag in all_anchor_tags:
#     # print(tag.getText())
#     print(tag.get("href"))
#
# heading = soup.find(name="h1", id="name")
# print(heading)
#
# class_is_heading = soup.find_all(class_="heading")
#
# h3_heading = soup.find(name="h3", class_="heading")
# print(h3_heading)
#
# company_url = soup.select_one(selector="p a")
# print(company_url)
#
# headings = soup.select(".heading")
# print(headings)


from collections import namedtuple

class TriangleFunction:
    M = 256

    def __init__(self, x1, x3):
        if x1 > x3:
            temp = x3
            x3 = x1
            x1 = temp
        self.x1 = x1
        self.x2 = (x1 + x3) // 2
        self.x3 = x3
        self.k1_denominator = max(1, self.x2 - x1)
        self.k2_denominator = min(-1, self.x2 - x3)

    def __call__(self, x):
        if x <= self.x1 or x >= self.x3:
            return 0
        if x <= self.x2:
            return self.M * (x - self.x1) // self.k1_denominator
        else:
            return self.M * (x - self.x3) // self.k2_denominator

_5Levels = namedtuple('FiveLevels', ('NM', 'NS', 'Z', 'PS', 'PM'))
_3Levels = namedtuple('ThreeLevels', ('NM', 'Z', 'PM'))
_3LevelsPositive = namedtuple('ThreeLevelsPositive', ('Z', 'PS', 'PM'))

def FiveLevels(NM, NS, Z, PS, PM):
    return _5Levels(
        TriangleFunction(*NM),
        TriangleFunction(*NS),
        TriangleFunction(*Z),
        TriangleFunction(*PS),
        TriangleFunction(*PM)
    )

def ThreeLevels(NM, Z, PM):
    return _3Levels(
        TriangleFunction(*NM),
        TriangleFunction(*Z),
        TriangleFunction(*PM)
    )

def ThreeLevelsPositive(Z, PS, PM):
    return _3LevelsPositive(
        TriangleFunction(*Z),
        TriangleFunction(*PS),
        TriangleFunction(*PM)
    )

class Defuzzer:
    def __init__(self):
        self.numerator = 0
        self.denominator = 0

    def feed(self, y2, output):
        self.numerator += y2 * output
        self.denominator += output

    def defuzz(self):
        return self.numerator // max(1, self.denominator)

    def reset(self):
        self.__init__()


import numpy as np
import matplotlib.pyplot as plt
import os

def draw_his(version, show=False):
    loss = np.load(os.path.join("./logs", "loss_his_{}.npy".format(version)))
    acc = np.load(os.path.join("./logs", "acc_his_{}.npy".format(version)))
    loss_val = np.load(os.path.join("./logs", "loss_val_his_{}.npy".format(version)))
    acc_val = np.load(os.path.join("./logs", "acc_val_his_{}.npy".format(version)))
    plt.figure(0)
    plt.subplot(1, 2, 1)
    plt.plot(loss)
    plt.subplot(1, 2, 2)
    plt.plot(loss_val)
    if show:
        plt.show()
    else:
        plt.savefig(os.path.join("./logs", "loss val_{}.png".format(version)))
    plt.figure(1)
    plt.subplot(1, 2, 1)
    plt.plot(acc)
    plt.subplot(1, 2, 2)
    plt.plot(acc_val)
    if show:
        plt.show()
    else:
        plt.savefig(os.path.join("./logs", "acc val_{}.png".format(version)))

if __name__ == "__main__":
    draw_his("resnet-2.0", True)


"""djangoblog URL Configuration

The `urlpatterns` list routes URLs to views. For more information please see:
    https://docs.djangoproject.com/en/1.8/topics/http/urls/
Examples:
Function views
    1. Add an import:  from my_app import views
    2. Add a URL to urlpatterns:  url(r'^$', views.home, name='home')
Class-based views
    1. Add an import:  from other_app.views import Home
    2. Add a URL to urlpatterns:  url(r'^$', Home.as_view(), name='home')
Including another URLconf
    1. Add an import:  from blog import urls as blog_urls
    2. Add a URL to urlpatterns:  url(r'^blog/', include(blog_urls))
"""
from django.conf.urls import include, url
from django.contrib import admin
from blog import views
from django.conf.urls.static import static
from django.conf import settings
urlpatterns = [
    url(r'^admin/', include(admin.site.urls)),
    url(r'^$', views.post_list),
    url(r'^post/(?P<pk>[0-9]+)/$', views.post_detail),
    url(r'^post/new/$', views.post_new, name='post_new'),
    url(r'^post/(?P<pk>[0-9]+)/edit/$', views.post_edit, name='post_edit'),
    url(r'^drafts/$',	views.post_draft_list,	name='post_draft_list'),
    url(r'^post/(?P<pk>[0-9]+)/publish/$',	views.post_publish,	name='post_publish'),
    url(r'^post/(?P<pk>[0-9]+)/remove/$',   views.post_remove,  name='post_remove'),
    url(r'^accounts/login/$',   'django.contrib.auth.views.login'),
    url(r'^accounts/logout/$',  'django.contrib.auth.views.logout', {'next_page':   '/'}),
    url(r'^accounts/profile/$',  views.profile),
    url(r'^readings/$',  views.readings),
    url(r'^post/(?P<pk>[0-9]+)/comment/$',  views.add_comment_to_post,  name='add_comment_to_post'),
    url(r'^comment/(?P<pk>[0-9]+)/approve/$',   views.comment_approve,  name='comment_approve'),
    url(r'^comment/(?P<pk>[0-9]+)/like/$',   views.comment_like,  name='comment_like'),
    url(r'^comment/(?P<pk>[0-9]+)/remove/$',    views.comment_remove,   name='comment_remove'),
]+ static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)


class Solution(object):
    def findKthLargest(self, nums, k):
        """
        :type nums: List[int]
        :type k: int
        :rtype: int
        """
        # k-selection: quick-selection
        # binary search: mustbe range [l,r]
        pivot = nums[-1]
        i = 0 # place-holder
        for j in xrange(len(nums)-1):
            if nums[j] > pivot:
                nums[j], nums[i] = nums[i], nums[j]
                i += 1
            j += 1
        nums[i], nums[-1] = nums[-1], nums[i]
        if k == i+1:
            return nums[i]
        elif k < i+1:
            return self.findKthLargest(nums[:i], k)
        else:
            assert 1 <= k - (i+1) <= len(nums[i+1:])
            return self.findKthLargest(nums[i+1:], k - (i+1))


# -*- coding: utf-8 -*-
import scrapy
import re
import json
from zhihu.items import ZhihuItem

class UserinfoSpider(scrapy.Spider):
    name = 'userinfo'
    allowed_domains = ['zhihu.com']
    start_urls = ['https://www.zhihu.com/api/v4/members/cmf2015/followers?include=data%5B*%5D.answer_count%2Carticles_count%2Cgender%2Cfollower_count%2Cis_followed%2Cis_following%2Cbadge%5B%3F(type%3Dbest_answerer)%5D.topics&offset=0&limit=20']

    def parse(self, response):
        data = json.loads(response.body.decode('unicode_escape'))['data']
        num = len(data)
        if num < 20:
            pass
        else:
            page_offset = re.findall("&offset=(.*?)&",response.url)[0]
            new_page_offset = page_offset+str(20)
            next_page_url = response.url.replace("&offset="+str(page_offset)+"&","&offset="+new_page_offset+"&")
            yield  scrapy.Request(url = next_page_url,callback=self.parse)

        for eve_user in data:
            item = ZhihuItem()
            item['name'] = eve_user['name']
            item['user_type'] = eve_user['user_type']
            item['follower_count'] = eve_user['follower_count']
            item['headline'] = eve_user['headline']
            item['url_token'] = eve_user['url_token']
            item['answer_count'] = eve_user['answer_count']
            item['gender'] = eve_user['gender']
            yield item

            new_url = 'https://www.zhihu.com/api/v4/members/'+eve_user['url_token']+'/followers?include=data%5B*%5D.answer_count%2Carticles_count%2Cgender%2Cfollower_count%2Cis_followed%2Cis_following%2Cbadge%5B%3F(type%3Dbest_answerer)%5D.topics&offset=0&limit=20'
            yield scrapy.Request(url=new_url,callback=self.parse)


import pygame
import config

class Game:
    def __init__(self):
        pygame.init()
        pygame.display.set_caption(config.TITLE)
        self.screen = pygame.display.set_mode((config.X, config.Y))
        self.running = True

        # Start main game loop
        self.loop()

    def loop(self):
        while self.running:
            self.check_events()
            self.render()
            self.update()

    def render(self):
        self.screen.fill(config.COLOR)
        pygame.display.update()

    def update(self):
        pass

    def check_events(self):
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                self.running = False

if __name__ == "__main__":
    game = Game()


import numpy as np
import matplotlib.pyplot as plt
from scipy import interpolate
import time

def sky(pos,L,tol):
    #Equation for the sky
    R = float(L)/2
    r = np.sqrt((pos[0]-R)**2+(pos[1]-R)**2+(pos[2]-R)**2)
    if np.abs(R-r) < tol:
        return 0
    elif r > R:
        return (r - R)
    else:
        return 1

def matSci(lmbda,mat):
    #Returns the sigma, albedeo, and cos(theta) grain values based on the wavelength and materials (*no material dependence yet*)
    #Uses linear interpolation to return parameters
    if mat == 'test':
        albedo = 0.6
        g = 0.6
        sigma = 10*0.6 / (1300 * 0.5 * 3.086e18)

    else:
        #Loading model data
        data = np.loadtxt('dustdata.txt')
        lam = data[:,0]
        albedogrid = data[:,1]
        ggrid = data[:,2]
        ext = data[:,3]
        absorp = data[:,4]

        #Converts absorption coeffiecients to cm^2 per H nucleon
        absorp *= 1.87e-26
        #Calculates scattering coeffiecients
        sigmagrid = ext - absorp

        #Interpolation of sigma, albedo, g using model grids
        falb = interpolate.interp1d(lam,albedogrid)
        albedo = float(falb(lmbda))

        fg = interpolate.interp1d(lam,ggrid)
        g = float(fg(lmbda))

        fsig = interpolate.interp1d(lam,sigmagrid)
        sigma = float(fsig(lmbda))

    return sigma,albedo,g

def genKobs(Aobs,L):
    psphere = np.loadtxt('pointsonsphere.txt')

    Kobs = np.zeros([psphere.shape[0],2])

    for j in range(psphere.shape[0]):
        r = np.sqrt((Aobs[0]-psphere[j,0])**2+(Aobs[1]-psphere[j,1])**2+(Aobs[2]-psphere[j,2])**2)
        Kobs[j,0] = np.arccos((psphere[j,2]-Aobs[2])/(r))

        if np.abs(Kobs[j,0]) < 1e-6 or np.abs(Kobs[j,0] - np.pi) < 1e-6:
            Kobs[j,1] = 0.0
#            print(Kobs[j,:])
        else:
            if np.isnan(np.arcsin((psphere[j,1]-Aobs[1])/((r)*np.sin(Kobs[j,0])))):
                Kobs[j,1] = np.pi/2
            else:
                Kobs[j,1] = np.arcsin((psphere[j,1]-Aobs[1])/((r)*np.sin(Kobs[j,0])))
            if psphere[j,0] < L/2:
                Kobs[j,1] = np.pi - Kobs[j,1]
#            print(Kobs[j,:])

    return Kobs

def genDirection(khat,g):
    theta = 0.0
    phi = 0.0

    p = np.random.rand(2)
    theta =  ((1+g)**2 - ((1-g**2)/(1-g+2*g*p[0]))**2)/(2*g)
    phi = 2*np.pi*p[1]
    k = np.zeros(2)
    k[0] = theta
    k[1] = phi

    return k

def posUpdate(pos,khat,step):
    theta = khat[0]
    phi = khat[1]
    npos = np.zeros(pos.shape)
    npos[0] = pos[0] + step*np.sin(theta)*np.cos(phi)
    npos[1] = pos[1] + step*np.sin(theta)*np.sin(phi)
    npos[2] = pos[2] + step*np.cos(theta)
    return npos

def interpolateDen(pos,density,axmin,axmax,C,khat):
    if sky(pos,axmax,1e-2) != 0 and sky(pos,axmax,1e-2) !=1:
        return 0

    x,y,z = pos[0],pos[1],pos[2]

    i = int((x-axmin)/(axmax-axmin)*(C-1.0))
    j = int((y-axmin)/(axmax-axmin)*(C-1.0))
    k = int((z-axmin)/(axmax-axmin)*(C-1.0))

    if sky(pos,axmax,1e-2) == 0:
        return density[i,j,k]

    posPrime = posUpdate(pos,khat,axmax/C)
    xprime,yprime,zprime = posPrime[0],posPrime[1],posPrime[2]
#    print(khat)

    iprime = int((xprime-axmin)/(axmax-axmin)*(C-1.0))
    jprime = int((yprime-axmin)/(axmax-axmin)*(C-1.0))
    kprime = int((zprime-axmin)/(axmax-axmin)*(C-1.0))

    if sky(posPrime,axmax,1e-2) != 1:
        return density[i,j,k]

    avgDen = (density[i,j,k] + density[iprime,j,k] + density[i,jprime,k] + density[i,j,kprime] + density[iprime,jprime,k] + density[iprime,j,kprime] + density[i,jprime,kprime] + density[iprime,jprime,kprime])/8
    #print(avgDen)
    return np.abs(avgDen)

def odsSample(pos,sigma,omega,g,density,tol,khat,C,L):
    oda = 0.0

    while sky(pos,L,tol):
        p = np.random.rand(1)
        ods = -np.log(p)
        odsp = 0.0

        while np.abs(ods-odsp) > tol:
            den = interpolateDen(pos,density,0.0,L,C,khat)
            if den == 0:
                step = L/C
            else:
                step = ods / (sigma*den)
#            print(den)
#            print(step)

            poscheck = posUpdate(pos,khat,step)
            if sky(poscheck,L,tol) != 1:
                step -= sky(poscheck,L,tol)
                odsp += sigma * den * step
                oda += (1/omega - 1)*odsp
                pos = posUpdate(pos,khat,step)
#                print('sky',pos)
                return oda

            elif step < L/C:
                odsp += sigma * den * step
                pos = posUpdate(pos,khat,step)
#                print('<',pos)
                break

            else:
                odsp += sigma * den * L/C
                pos = posUpdate(pos,khat,L/C)
                ods -= sigma * den * L/C
#                print('>',pos)

        oda += (1/omega - 1)*odsp
        khat = genDirection(khat,g)

    return oda

def monteCarlo(density,mat,lmbda,Aobs,M,tol,L,C):
    t0 = time.time()
    sigma,omega,g = matSci(lmbda,mat)
    intensities = np.zeros(Aobs.shape[0])

    for a in range(Aobs.shape[0]):
        Kobs = genKobs(Aobs[a,:],L)
        K = Kobs.shape[0]
        W = np.zeros([K,M])
        for k in range(K):
            for m in range(M):
                pos = Aobs[a,:]
                oda = odsSample(pos,sigma,omega,g,density,tol,Kobs[k],C,L)
                W[k,m] = np.exp(-oda)

        intensities[a] = 1/(K*M)*np.sum(W)

    returnArr = np.zeros([Aobs.shape[0],4])
    returnArr[:,0:3] = Aobs
    returnArr[:,3] = intensities
    print('time',(time.time()-t0))
    return returnArr


from __future__ import print_function

import sklearn
import pandas as pd
import numpy as np
import matplotlib
matplotlib.use('TkAgg')
import matplotlib.pyplot as plt

from sklearn.model_selection import train_test_split
from sklearn import linear_model

# Load data into DataFrame
data_url = 'https://archive.ics.uci.edu/ml/machine-learning-databases/housing/housing.data'
col_names = ["CRIM", "ZN", "INDUS", "CHAS", "NOX", "RM", "AGE",
             "DIS", "RAD", "TAX", "PTRATIO", "B", "LSTAT", "MEDV"]
'''
There are 14 attributes in each case of the dataset. They are:

    CRIM - per capita crime rate by town
    ZN - proportion of residential land zoned for lots over 25,000 sq.ft.
    INDUS - proportion of non-retail business acres per town.
    CHAS - Charles River dummy variable (1 if tract bounds river; 0 otherwise)
    NOX - nitric oxides concentration (parts per 10 million)
    RM - average number of rooms per dwelling
    AGE - proportion of owner-occupied units built prior to 1940
    DIS - weighted distances to five Boston employment centres
    RAD - index of accessibility to radial highways
    TAX - full-value property-tax rate per $10,000
    PTRATIO - pupil-teacher ratio by town
    B - 1000(Bk - 0.63)^2 where Bk is the proportion of blacks by town
    LSTAT - % lower status of the population
    MEDV - Median value of owner-occupied homes in $1000's
'''
df = pd.read_csv(data_url, delimiter=r"\s+", names=col_names)
print(df.head())  # retrun fist n rows, default n = 5
print(df.shape)  # dimensionality of the DataFrame

X = df[["CRIM","ZN","INDUS","CHAS","NOX","RM","AGE", "DIS","RAD","TAX","PTRATIO","B","LSTAT"]]
y = df[['MEDV']]

# Slice data into training and testing sets
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.20, random_state=5)

# Train model
reg = linear_model.LinearRegression()  # import the linear model
reg.fit(X_train, y_train)

# Predict
reg.predict([[0.03237, 0.0, 2.18, 0,0.458, 6.998, 45.8, 6.0622, 3,222.0,18.7, 394.63, 2.94]])
print( 'The intercept is', reg.intercept_)
print( 'The slops are', reg.coef_)

print ('the predict result is', reg.predict([[0.03237, 0.0, 2.18, 0,0.458, 6.998, 45.8, 6.0622, 3,222.0,18.7, 394.63, 2.94]]))

# Check accuracy
y_pred = reg.predict(X_test)
y_test_m = y_test.as_matrix()

plt.figure(figsize=(15,10))
plt.plot(y_test_m, ms=50, alpha=1)
plt.plot(y_pred, ms=50, alpha=1)
legend_list =['y_test_m','y_pred']
plt.legend(legend_list, loc=4, fontsize='25')

from sklearn.metrics import mean_squared_error
from sklearn.metrics import r2_score
print( 'The mean_squared_error is', mean_squared_error(y_test, y_pred))
print( 'The score is', r2_score(y_test, y_pred))


import RPi.GPIO as GPIO
import time
import maestro
import pandas as pd
import datetime as dt
import csv
import numpy as np

#dataframe stuff

#assign variables
LED =4
IR =17  # N BACK L RELAY6 PO2
IR2 =27 # W FRONT L RE5 PO1
IR3 =22 # S FRONT R RELAY 7 PO3
IR4 =5 # E BACK R RE4 PO0
#set up diff things
GPIO.setmode(GPIO.BCM)
#GPIO.setup(LED,GPIO.OUT)
GPIO.setup(IR, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(IR2, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(IR3, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(IR4, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setwarnings(False)
polo = maestro.Controller()
polo.setSpeed(0, 10)
polo.setAccel(0,4)
polo.setSpeed(1, 10)
polo.setAccel(1,4)
polo.setSpeed(2, 10)
polo.setAccel(2,4)
polo.setSpeed(3, 10)
polo.setAccel(3,4)
polo.setSpeed(4, 10)
polo.setAccel(4,4)
polo.setSpeed(6, 10)
polo.setAccel(6,4)
start = polo.getPosition(0)

#set the start point (idk it's for switching back and forth probably will need to find
prev=1
polo.setTarget(4, 3500)
polo.setTarget(6, 3500)
cueAB = [3500, 4500]
ts = 10 #trial number
tAB= np.random.choice([3500,4500], size=ts, replace='True') #random trial choice
NoSo = [4,6]

mins = time.time() + 60*20
#i want to make this loop more frequently
#but i need the water reward to be at least 0.5sec
while time.time() < mins:
    #df1 = pd.df
    for i in tAB:
        polo.setTarget(4, i) and polo.setTarget(6, i) #atm just does for loop... gotta figure out how to make her change per each
        if (GPIO.input(IR)== False and prev ==1) or (GPIO.input(IR3)== False and prev == 1):
            print("good")
            prev = 0
            time.sleep(0.5)
        if (GPIO.input(IR2)== False and prev == 0):
            polo.setTarget(1,6000)
            time.sleep(.5)
            polo.setTarget(1,992)
            prev = 1
            time.sleep(.01)
        elif (GPIO.input(IR4)== False and prev == 0):
            polo.setTarget(0,6000)
            time.sleep(.5)
            polo.setTarget(0,992)
            prev = 1
            time.sleep(.01)
        elif (GPIO.input(IR2)== False and prev == 1) or (GPIO.input(IR4)== False and prev == 1):
            print("wrong")
            time.sleep(.01)
        elif (GPIO.input(IR)== False and prev == 0) or (GPIO.input(IR3)==False and prev == 0):
            print("wrong")
            time.sleep(.01)
    #else:
       #print("heyo")
       #time.sleep(.01)