<commit_before>import os
import copy
import time

import pygame
from pygame.locals import *

from chess.core.models import Coordinate, Color, Piece, Player
from chess.core.utils import initial_board, BLACK_PIECES, WHITE_PIECES
from chess.core.possible_destinations import (destinations,
                                              is_check_for_player,
                                              is_check_mate_for_player)
from chess.core.coloring import color_board
from chess.core.moving import move
from chess.ai.score import score_board
from chess.ai.greedy import greedy_move
from chess.core.game import Game

SCREEN_TITLE = 'Chess'
SCREEN_WIDTH = 640
SCREEN_HEIGHT = 740
BOARD_SIZE = 640
CELL_BORDER = 3
IMAGES_FOLDER_PATH = 'chess/ui/assets/images'

class UI:
    def __init__(self):
        pygame.init()
        self.font = pygame.font.SysFont("monospace", 50)
        self.screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
        pygame.display.set_caption(SCREEN_TITLE)
        self.sprites = {
            "WHITE_PAWN_IMAGE": self.load_png('chess-pieces/white-pawn'),
            "WHITE_BISHOP_IMAGE": self.load_png('chess-pieces/white-bishop'),
            "WHITE_KING_IMAGE": self.load_png('chess-pieces/white-king'),
            "WHITE_KNIGHT_IMAGE": self.load_png('chess-pieces/white-knight'),
            "WHITE_QUEEN_IMAGE": self.load_png('chess-pieces/white-queen'),
            "WHITE_ROOK_IMAGE": self.load_png('chess-pieces/white-rook'),
            "BLACK_PAWN_IMAGE": self.load_png('chess-pieces/black-pawn'),
            "BLACK_BISHOP_IMAGE": self.load_png('chess-pieces/black-bishop'),
            "BLACK_KING_IMAGE": self.load_png('chess-pieces/black-king'),
            "BLACK_KNIGHT_IMAGE": self.load_png('chess-pieces/black-knight'),
            "BLACK_QUEEN_IMAGE": self.load_png('chess-pieces/black-queen'),
            "BLACK_ROOK_IMAGE": self.load_png('chess-pieces/black-rook')
        }

        self.__displayed_text = self.font.render("", 1, (255, 255, 255))

    def display_text(self, text, color=(255, 255, 255)):
        self.__displayed_text = self.font.render(text, 1, color)

    def erase_displayed_text(self):
        self.__displayed_text = self.font.render("", 1, (255, 255, 255))

    def animate(self, board, colored_board, move_diff):
        dH = move_diff[1].row - move_diff[0].row
        dL = move_diff[1].column - move_diff[0].column
        for i in range(10):
            t = i / 10.0
            board_surface = pygame.Surface((BOARD_SIZE, BOARD_SIZE)).convert()
            chess_pieces = []
            num_of_cells = len(board)
            cell_size = (BOARD_SIZE / num_of_cells)
            for row in range(num_of_cells):
                for col in range(num_of_cells):
                    cell_rect = (col * cell_size, row * cell_size,
                                 cell_size - 5, cell_size - 5)
                    if row == move_diff[1].row and col == move_diff[1].column:
                        piece_cell_rect = (
                            (move_diff[0].column + t * dL) * cell_size,
                            (move_diff[0].row + t * dH) * cell_size,
                            cell_size - 5, cell_size - 5)
                    else:
                        piece_cell_rect = cell_rect
                    cell_color_rgb = colored_board[row][col].rgb
                    board_surface.fill(cell_color_rgb, cell_rect)
                    cell_value = board[row][col]
                    chess_piece = self.create_chess_piece(
                        cell_value, cell_size, piece_cell_rect)
                    if chess_piece is not None:
                        chess_pieces.append(chess_piece)

            self.screen.blit(board_surface, board_position())
            for chess_piece in chess_pieces:
                self.screen.blit(chess_piece.image, chess_piece.rect)
            pygame.display.update()
            time.sleep(0.03)

    def refresh(self, chess_board, colored_board):
        # Erase screen
        self.screen.fill((0, 0, 0))

        board_surface, chess_pieces = self.setup_board(
            chess_board, colored_board)
        self.screen.blit(board_surface, board_position())
        for chess_piece in chess_pieces:
            self.screen.blit(chess_piece.image, chess_piece.rect)

        # Foreground
        text_rect = self.__displayed_text.get_rect(center=(SCREEN_WIDTH/2, 50))
        self.screen.blit(self.__displayed_text, text_rect)

        pygame.display.update()

    def create_chess_piece(self, piece, cell_size, cell_rect):
        if piece == Piece.NONE:
            piece_image = None
        else:
            piece_image = self.sprites[piece.name + '_IMAGE']

        chess_piece = None
        if piece_image is not None:
            chess_piece_image = pygame.transform.scale(
                piece_image, (int(cell_size), int(cell_size)))
            chess_piece = ChessPiece(chess_piece_image, cell_rect)

        return chess_piece

    def setup_board(self, board, color_board):
        board_surface = pygame.Surface((BOARD_SIZE, BOARD_SIZE)).convert()
        chess_pieces = []
        num_of_cells = len(board)
        cell_size = (BOARD_SIZE / num_of_cells)
        for row in range(num_of_cells):
            for col in range(num_of_cells):
                cell_rect = (
                    col * cell_size,
                    row * cell_size,
                    cell_size - CELL_BORDER,
                    cell_size - CELL_BORDER)
                cell_color_rgb = color_board[row][col].rgb
                board_surface.fill(cell_color_rgb, cell_rect)
                cell_value = board[row][col]

                piece_rect = (
                    col * cell_size + board_position()[0],
                    row * cell_size + board_position()[1],
                    cell_size - CELL_BORDER,
                    cell_size - CELL_BORDER)

                chess_piece = self.create_chess_piece(
                    cell_value, cell_size, piece_rect)
                if chess_piece is not None:
                    chess_pieces.append(chess_piece)

        return board_surface, chess_pieces

    def load_png(self, file_name):
        """ Load image and return image object"""
        fullname = os.path.join(IMAGES_FOLDER_PATH, file_name + '.png')
        image = pygame.image.load(fullname)
        if image.get_alpha() is None:
            image = image.convert()
        else:
            image = image.convert_alpha()
        return image

class ChessPiece(pygame.sprite.Sprite):
    def __init__(self, image_surface, rect):
        pygame.sprite.Sprite.__init__(self)
        self.image = image_surface
        self.rect = pygame.Rect(rect)

    def was_clicked(self, click_position):
        return self.rect.collidepoint(click_position)

def get_coordinates_by_position(position, board):
    num_of_cells = len(board)
    cell_size = BOARD_SIZE / num_of_cells
    for row in range(num_of_cells):
        for col in range(num_of_cells):
            cell = (col * cell_size + board_position()[0],
                    row * cell_size + board_position()[1],
                    cell_size, cell_size)
            cell_rect = pygame.Rect(cell)
            if cell_rect.collidepoint(position):
                return Coordinate(row, col)

def get_rect_by_coordinates(coordinates, board):
    num_of_cells = len(board)
    cell_size = BOARD_SIZE / num_of_cells
    board_x, board_y = board_position()
    rect = pygame.Rect(board_x + coordinates.column * cell_size,
                       board_y + coordinates.row * cell_size,
                       BOARD_SIZE / 8, BOARD_SIZE / 8)

    return rect

def board_position():
    return (
        (SCREEN_WIDTH - BOARD_SIZE) / 2,
        (SCREEN_HEIGHT - BOARD_SIZE) / 2 + 50)

def is_holding_piece(piece_coord):
    return piece_coord is not None

def can_move_piece(clicked_piece, held_piece_coord):
    if not is_holding_piece(held_piece_coord) and clicked_piece != Piece.NONE \
            and clicked_piece in WHITE_PIECES:
        return True
    return False

def select_promotion_piece():
    selected_piece = None

    while selected_piece is None:
        for event in pygame.event.get():
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_q:
                    selected_piece = Piece.WHITE_QUEEN

    return selected_piece

def menu(ui):
    print("menu")
    menu = True
    quit = False
    while menu and not quit:
        for event in pygame.event.get():
            if event.type == pygame.KEYDOWN and event.key == \
                    pygame.K_RETURN:
                menu = False
                quit = False
            if event.type == pygame.QUIT:
                quit = True

        ui.screen.fill((0, 0, 0,))

        font = pygame.font.SysFont("monospace", 50)
        text = font.render("Press (ENTER) to Start", 1, (255, 255, 255))
        text_rect = text.get_rect(
            center=(SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2))
        ui.screen.blit(text, text_rect)
        pygame.draw.lines(ui.screen, (0, 128, 255), 1, [
                (0, 0), (SCREEN_WIDTH, 0),
                (SCREEN_WIDTH, SCREEN_HEIGHT), (0, SCREEN_HEIGHT),
            ], 10)

        pygame.display.update()

    return quit

def run_game(ui, game, board):

    held_piece_coord = None
    player_turn = True
    print("Player turn...")
    ui.display_text("Your turn...")

    colored_board = []

    game_running = True
    end_game = False

    while game_running:
        for event in pygame.event.get():
            if event.type == QUIT:
                quit = True
                return quit
            if event.type == pygame.KEYDOWN and event.key == \
                    pygame.K_ESCAPE:
                quit = False
                return quit
            if player_turn:
                if event.type == pygame.MOUSEBUTTONDOWN:
                    cell_coord = get_coordinates_by_position(
                        pygame.mouse.get_pos(), board)
                    if cell_coord is not None:
                        clicked_piece = \
                            board[cell_coord.row][cell_coord.column]
                        if can_move_piece(clicked_piece, held_piece_coord):
                            held_piece_coord = Coordinate(
                                cell_coord.row, cell_coord.column)
                            print(
                                "Clicked on cell: {} which contains a {}"
                                .format(held_piece_coord, clicked_piece))
                elif event.type == pygame.MOUSEBUTTONUP:
                    cell_coord = get_coordinates_by_position(
                        pygame.mouse.get_pos(), board)
                    if is_holding_piece(held_piece_coord):
                        possible_destinations = destinations(
                            game, held_piece_coord)
                        if cell_coord in possible_destinations:
                            move(game, held_piece_coord, cell_coord,
                                 select_promotion_piece)
                            player_turn = False
                            print("Player moved!")
                            if is_check_mate_for_player(game, Player.BLACK):
                                print('WHITE player wins!')
                                ui.display_text(
                                    "WHITE player wins! (Press ESC)",
                                    color=(0, 255, 0))
                                end_game = True
                            elif is_check_for_player(game, Player.BLACK):
                                ui.display_text("BLACK player is in CHECK")
                    else:
                        print("You cannot do that!")
                        print("Player turn still...")
                    held_piece_coord = None

        possible_destinations = []
        if player_turn and is_holding_piece(held_piece_coord):
            possible_destinations = destinations(game, held_piece_coord)
        colored_board = color_board(board, possible_destinations)

        if not end_game and not player_turn:
            print("Computer turn")
            ui.display_text("Computer turn...")
            movement = greedy_move(game)
            move(game, movement[0], movement[1])
            print("Computer moved!")
            if is_check_mate_for_player(game, Player.WHITE):
                print('BLACK player wins!')
                ui.display_text("BLACK player wins! (Press ESC)",
                                color=(255, 0, 0))
                end_game = True
            elif is_check_for_player(game, Player.WHITE):
                print('WHITE player is in check!')
                ui.display_text("Your turn... (CHECK!)", color=(255, 0, 0))
            else:
                print("Player turn")
                ui.display_text("Your turn...")
            player_turn = True

        if end_game:
            player_turn = False
        ui.refresh(board, colored_board)

def run():
    ui = UI()
    running = True
    while running:
        quit = menu(ui)
        if not quit:
            game = Game()
            board = game.board
            quit = run_game(ui, game, board)
            if quit:
                break
            ui.refresh(board, color_board(board, []))
        else:
            break

    pygame.quit()
<commit_msg>:rocket: #69 Add bottom border<commit_after>import os
import copy
import time

import pygame
from pygame.locals import *

from chess.core.models import Coordinate, Color, Piece, Player
from chess.core.utils import initial_board, BLACK_PIECES, WHITE_PIECES
from chess.core.possible_destinations import (destinations,
                                              is_check_for_player,
                                              is_check_mate_for_player)
from chess.core.coloring import color_board
from chess.core.moving import move
from chess.ai.score import score_board
from chess.ai.greedy import greedy_move
from chess.core.game import Game

SCREEN_TITLE = 'Chess'
SCREEN_WIDTH = 640
SCREEN_HEIGHT = 840
BOARD_SIZE = 640
CELL_BORDER = 3
IMAGES_FOLDER_PATH = 'chess/ui/assets/images'

class UI:
    def __init__(self):
        pygame.init()
        self.font = pygame.font.SysFont("monospace", 50)
        self.screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
        pygame.display.set_caption(SCREEN_TITLE)
        self.sprites = {
            "WHITE_PAWN_IMAGE": self.load_png('chess-pieces/white-pawn'),
            "WHITE_BISHOP_IMAGE": self.load_png('chess-pieces/white-bishop'),
            "WHITE_KING_IMAGE": self.load_png('chess-pieces/white-king'),
            "WHITE_KNIGHT_IMAGE": self.load_png('chess-pieces/white-knight'),
            "WHITE_QUEEN_IMAGE": self.load_png('chess-pieces/white-queen'),
            "WHITE_ROOK_IMAGE": self.load_png('chess-pieces/white-rook'),
            "BLACK_PAWN_IMAGE": self.load_png('chess-pieces/black-pawn'),
            "BLACK_BISHOP_IMAGE": self.load_png('chess-pieces/black-bishop'),
            "BLACK_KING_IMAGE": self.load_png('chess-pieces/black-king'),
            "BLACK_KNIGHT_IMAGE": self.load_png('chess-pieces/black-knight'),
            "BLACK_QUEEN_IMAGE": self.load_png('chess-pieces/black-queen'),
            "BLACK_ROOK_IMAGE": self.load_png('chess-pieces/black-rook')
        }

        self.__displayed_text = self.font.render("", 1, (255, 255, 255))

    def display_text(self, text, color=(255, 255, 255)):
        self.__displayed_text = self.font.render(text, 1, color)

    def erase_displayed_text(self):
        self.__displayed_text = self.font.render("", 1, (255, 255, 255))

    def animate(self, board, colored_board, move_diff):
        dH = move_diff[1].row - move_diff[0].row
        dL = move_diff[1].column - move_diff[0].column
        for i in range(10):
            t = i / 10.0
            board_surface = pygame.Surface((BOARD_SIZE, BOARD_SIZE)).convert()
            chess_pieces = []
            num_of_cells = len(board)
            cell_size = (BOARD_SIZE / num_of_cells)
            for row in range(num_of_cells):
                for col in range(num_of_cells):
                    cell_rect = (col * cell_size, row * cell_size,
                                 cell_size - 5, cell_size - 5)
                    if row == move_diff[1].row and col == move_diff[1].column:
                        piece_cell_rect = (
                            (move_diff[0].column + t * dL) * cell_size,
                            (move_diff[0].row + t * dH) * cell_size,
                            cell_size - 5, cell_size - 5)
                    else:
                        piece_cell_rect = cell_rect
                    cell_color_rgb = colored_board[row][col].rgb
                    board_surface.fill(cell_color_rgb, cell_rect)
                    cell_value = board[row][col]
                    chess_piece = self.create_chess_piece(
                        cell_value, cell_size, piece_cell_rect)
                    if chess_piece is not None:
                        chess_pieces.append(chess_piece)

            self.screen.blit(board_surface, board_position())
            for chess_piece in chess_pieces:
                self.screen.blit(chess_piece.image, chess_piece.rect)
            pygame.display.update()
            time.sleep(0.03)

    def refresh(self, chess_board, colored_board):
        # Erase screen
        self.screen.fill((0, 0, 0))

        board_surface, chess_pieces = self.setup_board(
            chess_board, colored_board)
        self.screen.blit(board_surface, board_position())
        for chess_piece in chess_pieces:
            self.screen.blit(chess_piece.image, chess_piece.rect)

        # Foreground
        text_rect = self.__displayed_text.get_rect(center=(SCREEN_WIDTH/2, 50))
        self.screen.blit(self.__displayed_text, text_rect)

        pygame.display.update()

    def create_chess_piece(self, piece, cell_size, cell_rect):
        if piece == Piece.NONE:
            piece_image = None
        else:
            piece_image = self.sprites[piece.name + '_IMAGE']

        chess_piece = None
        if piece_image is not None:
            chess_piece_image = pygame.transform.scale(
                piece_image, (int(cell_size), int(cell_size)))
            chess_piece = ChessPiece(chess_piece_image, cell_rect)

        return chess_piece

    def setup_board(self, board, color_board):
        board_surface = pygame.Surface((BOARD_SIZE, BOARD_SIZE)).convert()
        chess_pieces = []
        num_of_cells = len(board)
        cell_size = (BOARD_SIZE / num_of_cells)
        for row in range(num_of_cells):
            for col in range(num_of_cells):
                cell_rect = (
                    col * cell_size,
                    row * cell_size,
                    cell_size - CELL_BORDER,
                    cell_size - CELL_BORDER)
                cell_color_rgb = color_board[row][col].rgb
                board_surface.fill(cell_color_rgb, cell_rect)
                cell_value = board[row][col]

                piece_rect = (
                    col * cell_size + board_position()[0],
                    row * cell_size + board_position()[1],
                    cell_size - CELL_BORDER,
                    cell_size - CELL_BORDER)

                chess_piece = self.create_chess_piece(
                    cell_value, cell_size, piece_rect)
                if chess_piece is not None:
                    chess_pieces.append(chess_piece)

        return board_surface, chess_pieces

    def load_png(self, file_name):
        """ Load image and return image object"""
        fullname = os.path.join(IMAGES_FOLDER_PATH, file_name + '.png')
        image = pygame.image.load(fullname)
        if image.get_alpha() is None:
            image = image.convert()
        else:
            image = image.convert_alpha()
        return image

class ChessPiece(pygame.sprite.Sprite):
    def __init__(self, image_surface, rect):
        pygame.sprite.Sprite.__init__(self)
        self.image = image_surface
        self.rect = pygame.Rect(rect)

    def was_clicked(self, click_position):
        return self.rect.collidepoint(click_position)

def get_coordinates_by_position(position, board):
    num_of_cells = len(board)
    cell_size = BOARD_SIZE / num_of_cells
    for row in range(num_of_cells):
        for col in range(num_of_cells):
            cell = (col * cell_size + board_position()[0],
                    row * cell_size + board_position()[1],
                    cell_size, cell_size)
            cell_rect = pygame.Rect(cell)
            if cell_rect.collidepoint(position):
                return Coordinate(row, col)

def get_rect_by_coordinates(coordinates, board):
    num_of_cells = len(board)
    cell_size = BOARD_SIZE / num_of_cells
    board_x, board_y = board_position()
    rect = pygame.Rect(board_x + coordinates.column * cell_size,
                       board_y + coordinates.row * cell_size,
                       BOARD_SIZE / 8, BOARD_SIZE / 8)

    return rect

def board_position():
    return (
        (SCREEN_WIDTH - BOARD_SIZE) / 2,
        (SCREEN_HEIGHT - BOARD_SIZE) / 2)

def is_holding_piece(piece_coord):
    return piece_coord is not None

def can_move_piece(clicked_piece, held_piece_coord):
    if not is_holding_piece(held_piece_coord) and clicked_piece != Piece.NONE \
            and clicked_piece in WHITE_PIECES:
        return True
    return False

def select_promotion_piece():
    selected_piece = None

    while selected_piece is None:
        for event in pygame.event.get():
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_q:
                    selected_piece = Piece.WHITE_QUEEN

    return selected_piece

def menu(ui):
    print("menu")
    menu = True
    quit = False
    while menu and not quit:
        for event in pygame.event.get():
            if event.type == pygame.KEYDOWN and event.key == \
                    pygame.K_RETURN:
                menu = False
                quit = False
            if event.type == pygame.QUIT:
                quit = True

        ui.screen.fill((0, 0, 0,))

        font = pygame.font.SysFont("monospace", 50)
        text = font.render("Press (ENTER) to Start", 1, (255, 255, 255))
        text_rect = text.get_rect(
            center=(SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2))
        ui.screen.blit(text, text_rect)
        pygame.draw.lines(ui.screen, (0, 128, 255), 1, [
                (0, 0), (SCREEN_WIDTH, 0),
                (SCREEN_WIDTH, SCREEN_HEIGHT), (0, SCREEN_HEIGHT),
            ], 10)

        pygame.display.update()

    return quit

def run_game(ui, game, board):

    held_piece_coord = None
    player_turn = True
    print("Player turn...")
    ui.display_text("Your turn...")

    colored_board = []

    game_running = True
    end_game = False

    while game_running:
        for event in pygame.event.get():
            if event.type == QUIT:
                quit = True
                return quit
            if event.type == pygame.KEYDOWN and event.key == \
                    pygame.K_ESCAPE:
                quit = False
                return quit
            if player_turn:
                if event.type == pygame.MOUSEBUTTONDOWN:
                    cell_coord = get_coordinates_by_position(
                        pygame.mouse.get_pos(), board)
                    if cell_coord is not None:
                        clicked_piece = \
                            board[cell_coord.row][cell_coord.column]
                        if can_move_piece(clicked_piece, held_piece_coord):
                            held_piece_coord = Coordinate(
                                cell_coord.row, cell_coord.column)
                            print(
                                "Clicked on cell: {} which contains a {}"
                                .format(held_piece_coord, clicked_piece))
                elif event.type == pygame.MOUSEBUTTONUP:
                    cell_coord = get_coordinates_by_position(
                        pygame.mouse.get_pos(), board)
                    if is_holding_piece(held_piece_coord):
                        possible_destinations = destinations(
                            game, held_piece_coord)
                        if cell_coord in possible_destinations:
                            move(game, held_piece_coord, cell_coord,
                                 select_promotion_piece)
                            player_turn = False
                            print("Player moved!")
                            if is_check_mate_for_player(game, Player.BLACK):
                                print('WHITE player wins!')
                                ui.display_text(
                                    "WHITE player wins! (Press ESC)",
                                    color=(0, 255, 0))
                                end_game = True
                            elif is_check_for_player(game, Player.BLACK):
                                ui.display_text("BLACK player is in CHECK")
                    else:
                        print("You cannot do that!")
                        print("Player turn still...")
                    held_piece_coord = None

        possible_destinations = []
        if player_turn and is_holding_piece(held_piece_coord):
            possible_destinations = destinations(game, held_piece_coord)
        colored_board = color_board(board, possible_destinations)

        if not end_game and not player_turn:
            print("Computer turn")
            ui.display_text("Computer turn...")
            movement = greedy_move(game)
            move(game, movement[0], movement[1])
            print("Computer moved!")
            if is_check_mate_for_player(game, Player.WHITE):
                print('BLACK player wins!')
                ui.display_text("BLACK player wins! (Press ESC)",
                                color=(255, 0, 0))
                end_game = True
            elif is_check_for_player(game, Player.WHITE):
                print('WHITE player is in check!')
                ui.display_text("Your turn... (CHECK!)", color=(255, 0, 0))
            else:
                print("Player turn")
                ui.display_text("Your turn...")
            player_turn = True

        if end_game:
            player_turn = False
        ui.refresh(board, colored_board)

def run():
    ui = UI()
    running = True
    while running:
        quit = menu(ui)
        if not quit:
            game = Game()
            board = game.board
            quit = run_game(ui, game, board)
            if quit:
                break
            ui.refresh(board, color_board(board, []))
        else:
            break

    pygame.quit()
<|endoftext|>


<commit_before>import numpy as np

class Neuron(object):
    pass

class LIF(Neuron):
    def __init__(self, tau_rc=0.02, tau_ref=0.002):
        self.tau_rc = tau_rc
        self.tau_ref = tau_ref

class Rate(Neuron):
    pass

class Spiking(Neuron):
    pass

class Fixed(Neuron):
    pass

class Izhikevich(Neuron):
    def __init__(self, a=0.02, b=0.2, c=-65, d=8):
        self.a = a
        self.b = b
        self.c = c
        self.d = d

class NeuronPool:
    def __init__(self, n_neurons, neuron_types=None):
        if neuron_types is None:
            neuron_types = self.neuron_types
        for n in neuron_types:
            for key, value in n.__dict__.items():
                if not key.startswith('_'):
                    setattr(self, key, value)
        self.make(n_neurons)

    def make(self, n_neurons):
        raise NotImplementedError('NeuronPools must provide "make"')

    def step(self, dt, J):
        raise NotImplementedError('NeuronPools must provide "step"')

class LIFRatePool(NeuronPool):
    neuron_type = [LIF, Rate]

    def make(self, n_neurons):
        pass

    def step(self, dt, J):
        old = np.seterr(divide='ignore', invalid='ignore')
        try:
            r = 1.0 / (self.tau_ref + self.tau_rc * np.log1p(1.0 / (J-1)))
            r[J <= 1] = 0
        finally:
            np.seterr(**old)
        return r * dt   # multiply by dt to do rate per timestep

class LIFSpikingPool(NeuronPool):
    neuron_type = [LIF, Spiking]

    def make(self, n_neurons):
        self.voltage = np.zeros(n_neurons)
        self.refractory_time = np.zeros(n_neurons)

    def step(self, dt, J):
        dv = (dt / self.tau_rc) * (J - self.voltage)
        self.voltage += dv

        self.voltage[self.voltage < 0] = 0

        self.refractory_time -= dt

        self.voltage *= (1-self.refractory_time / dt).clip(0, 1)

        spiked = self.voltage > 1

        overshoot = (self.voltage[spiked > 0] - 1) / dv[spiked > 0]
        spiketime = dt * (1 - overshoot)

        self.voltage[spiked > 0] = 0
        self.refractory_time[spiked > 0] = self.tau_ref + spiketime

        return spiked

class LIFFixedPool(NeuronPool):
    neuron_type = [LIF, Spiking, Fixed]

    def make(self, n_neurons):
        self.voltage = np.zeros(n_neurons, dtype='i32')
        self.refractory_time = np.zeros(n_neurons, dtype='u8')

        self.dt = None
        self.ref_steps = None
        self.lfsr = 1

    def step(self, dt, J):
        if self.dt != dt:
            self.dt = dt
            self.dt_over_tau_rc = int(dt * 0x10000 / self.tau_rc)
            self.ref_steps = int(self.tau_ref / dt)

        J = np.asarray(J * 0x10000, dtype='i32')

        dv = ((J - self.voltage) * self.dt_over_tau_rc) >> 16

        dv[self.refractory_time > 0] = 0

        self.refractory_time[self.refractory_time > 0] -= 1

        self.voltage += dv

        self.voltage[self.voltage < 0] = 0

        spiked = self.voltage > 0x10000

        self.refractory_time[spiked > 0] = self.ref_steps

        # randomly adjust the refractory period to account for overshoot
        for i in np.where(spiked > 0)[0]:
            p = ((self.voltage[i] - 0x10000) << 16) / dv[i]
            if self.lfsr < p:
                self.refractory_time[i] -= 1
            self.lfsr = (self.lfsr >> 1) ^ (-(self.lfsr & 0x1) & 0xB400)

        self.voltage[spiked > 0] = 0

        return spiked

class IzhikevichPool(NeuronPool):
    neuron_type = [Izhikevich, Spiking]

    def make(self, n_neurons):
        self.v = np.zeros(n_neurons) + self.c
        self.u = self.b * self.v

    def step(self, dt, J):
        dv = (0.04 * self.v ** 2 + 5 * self.v + 140 - self.u + J) * 1000
        du = (self.a * (self.b * self.v - self.u)) * 1000

        self.v += dv * dt
        self.u += du * dt

        spiked = self.v >= 30
        self.v[spiked > 0] = self.c
        self.u[spiked > 0] = self.u[spiked > 0] + self.d

        return spiked

neuron_models = [
    LIFSpikingPool,
    LIFRatePool,
    LIFFixedPool,
    IzhikevichPool,
    ]

import inspect
def create(n_neurons, neuron_type):

    # make sure it's a list
    try:
        len(neuron_type)
    except TypeError:
        neuron_type = [neuron_type]

    # make sure elements in the list are instances, not classes
    for i, type in enumerate(neuron_type):
        if inspect.isclass(type):
            neuron_type[i] = type()

    # look through the list of neuron models to see if we can
    # find a match
    for model in neuron_models:
        for type in neuron_type:
            if type.__class__ not in model.neuron_type:
                break
        else:
            return model(n_neurons, neuron_type)

    raise Exception('Could not find suitable neuron model')

if __name__ == '__main__':

    spiking = create(100, [LIF, Spiking])
    rate = create(100, [LIF, Rate])
    fixed = create(100, [LIF, Fixed])
    iz = create(100, [Izhikevich])
    #iz = create(100, [Izhikevich(a=0.02, b=0.2, c=-50, d=2)])

    J = np.linspace(-2, 10, 100)
    dt = 0.001
    T = 1
    spiking_data = []
    rate_data = []
    iz_data = []
    fixed_data = []
    v = []
    for i in range(int(T/dt)):
        spiking_data.append(spiking.step(dt, J))
        rate_data.append(rate.step(dt, J))
        iz_data.append(iz.step(dt, J))
        fixed_data.append(fixed.step(dt, J))
        v.append(fixed.voltage[-1])

    rate_tuning = np.sum(rate_data, axis=0)/T
    spiking_tuning = np.sum(spiking_data, axis=0)/T
    iz_tuning = np.sum(iz_data, axis=0)/T
    fixed_tuning = np.sum(fixed_data, axis=0)/T

    import pylab
    pylab.subplot(2, 1, 1)
    pylab.plot(J, rate_tuning)
    pylab.plot(J, spiking_tuning)
    pylab.plot(J, iz_tuning)
    pylab.plot(J, fixed_tuning, linewidth=4)
    pylab.subplot(2, 1, 2)
    pylab.plot(v)
    #pylab.plot(np.array(fixed_data)[:,-1])
    pylab.show()

<commit_msg>Small cleanup<commit_after>import numpy as np

class Neuron(object):
    pass

class LIF(Neuron):
    def __init__(self, tau_rc=0.02, tau_ref=0.002):
        self.tau_rc = tau_rc
        self.tau_ref = tau_ref

class Rate(Neuron):
    pass

class Spiking(Neuron):
    pass

class Fixed(Neuron):
    pass

class Izhikevich(Neuron):
    def __init__(self, a=0.02, b=0.2, c=-65, d=8):
        self.a = a
        self.b = b
        self.c = c
        self.d = d

class NeuronPool:
    def __init__(self, n_neurons, neuron_types=None):
        if neuron_types is None:
            neuron_types = self.neuron_types
        for n in neuron_types:
            for key, value in n.__dict__.items():
                if not key.startswith('_'):
                    setattr(self, key, value)
        self.make(n_neurons)

    def make(self, n_neurons):
        raise NotImplementedError('NeuronPools must provide "make"')

    def step(self, dt, J):
        raise NotImplementedError('NeuronPools must provide "step"')

class LIFRatePool(NeuronPool):
    neuron_type = [LIF, Rate]

    def make(self, n_neurons):
        pass

    def step(self, dt, J):
        old = np.seterr(divide='ignore', invalid='ignore')
        try:
            r = 1.0 / (self.tau_ref + self.tau_rc * np.log1p(1.0 / (J-1)))
            r[J <= 1] = 0
        finally:
            np.seterr(**old)
        return r * dt   # multiply by dt to do rate per timestep

class LIFSpikingPool(NeuronPool):
    neuron_type = [LIF, Spiking]

    def make(self, n_neurons):
        self.voltage = np.zeros(n_neurons)
        self.refractory_time = np.zeros(n_neurons)

    def step(self, dt, J):
        dv = (dt / self.tau_rc) * (J - self.voltage)
        self.voltage += dv

        self.voltage[self.voltage < 0] = 0

        self.refractory_time -= dt

        self.voltage *= (1-self.refractory_time / dt).clip(0, 1)

        spiked = self.voltage > 1

        overshoot = (self.voltage[spiked > 0] - 1) / dv[spiked > 0]
        spiketime = dt * (1 - overshoot)

        self.voltage[spiked > 0] = 0
        self.refractory_time[spiked > 0] = self.tau_ref + spiketime

        return spiked

class LIFFixedPool(NeuronPool):
    neuron_type = [LIF, Spiking, Fixed]

    def make(self, n_neurons):
        self.voltage = np.zeros(n_neurons, dtype='i32')
        self.refractory_time = np.zeros(n_neurons, dtype='u8')

        self.dt = None
        self.lfsr = 1

    def step(self, dt, J):
        if self.dt != dt:
            self.dt = dt
            self.dt_over_tau_rc = int(dt * 0x10000 / self.tau_rc)
            self.ref_steps = int(self.tau_ref / dt)

        J = np.asarray(J * 0x10000, dtype='i32')

        dv = ((J - self.voltage) * self.dt_over_tau_rc) >> 16

        dv[self.refractory_time > 0] = 0

        self.refractory_time[self.refractory_time > 0] -= 1

        self.voltage += dv

        self.voltage[self.voltage < 0] = 0

        spiked = self.voltage > 0x10000

        self.refractory_time[spiked > 0] = self.ref_steps

        # randomly adjust the refractory period to account for overshoot
        for i in np.where(spiked > 0)[0]:
            p = ((self.voltage[i] - 0x10000) << 16) / dv[i]
            if self.lfsr < p:
                self.refractory_time[i] -= 1
            self.lfsr = (self.lfsr >> 1) ^ (-(self.lfsr & 0x1) & 0xB400)

        self.voltage[spiked > 0] = 0

        return spiked

class IzhikevichPool(NeuronPool):
    neuron_type = [Izhikevich, Spiking]

    def make(self, n_neurons):
        self.v = np.zeros(n_neurons) + self.c
        self.u = self.b * self.v

    def step(self, dt, J):
        dv = (0.04 * self.v ** 2 + 5 * self.v + 140 - self.u + J) * 1000
        du = (self.a * (self.b * self.v - self.u)) * 1000

        self.v += dv * dt
        self.u += du * dt

        spiked = self.v >= 30
        self.v[spiked > 0] = self.c
        self.u[spiked > 0] = self.u[spiked > 0] + self.d

        return spiked

neuron_models = [
    LIFSpikingPool,
    LIFRatePool,
    LIFFixedPool,
    IzhikevichPool,
    ]

import inspect
def create(n_neurons, neuron_type):

    # make sure it's a list
    try:
        len(neuron_type)
    except TypeError:
        neuron_type = [neuron_type]

    # make sure elements in the list are instances, not classes
    for i, type in enumerate(neuron_type):
        if inspect.isclass(type):
            neuron_type[i] = type()

    # look through the list of neuron models to see if we can
    # find a match
    for model in neuron_models:
        for type in neuron_type:
            if type.__class__ not in model.neuron_type:
                break
        else:
            return model(n_neurons, neuron_type)

    raise Exception('Could not find suitable neuron model')

if __name__ == '__main__':

    spiking = create(100, [LIF, Spiking])
    rate = create(100, [LIF, Rate])
    fixed = create(100, [LIF, Fixed])
    iz = create(100, [Izhikevich])
    #iz = create(100, [Izhikevich(a=0.02, b=0.2, c=-50, d=2)])

    J = np.linspace(-2, 10, 100)
    dt = 0.001
    T = 1
    spiking_data = []
    rate_data = []
    iz_data = []
    fixed_data = []
    v = []
    for i in range(int(T/dt)):
        spiking_data.append(spiking.step(dt, J))
        rate_data.append(rate.step(dt, J))
        iz_data.append(iz.step(dt, J))
        fixed_data.append(fixed.step(dt, J))
        v.append(fixed.voltage[-1])

    rate_tuning = np.sum(rate_data, axis=0)/T
    spiking_tuning = np.sum(spiking_data, axis=0)/T
    iz_tuning = np.sum(iz_data, axis=0)/T
    fixed_tuning = np.sum(fixed_data, axis=0)/T

    import pylab
    pylab.subplot(2, 1, 1)
    pylab.plot(J, rate_tuning)
    pylab.plot(J, spiking_tuning)
    pylab.plot(J, iz_tuning)
    pylab.plot(J, fixed_tuning, linewidth=4)
    pylab.subplot(2, 1, 2)
    pylab.plot(v)
    #pylab.plot(np.array(fixed_data)[:,-1])
    pylab.show()

<|endoftext|>


<commit_before>#   -*- coding: utf-8 -*-
#
#   This file is part of PyBuilder
#
#   Copyright 2011-2014 PyBuilder Team
#
#   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.

"""
    Plugin for Jedi linting support.

    https://jedi.jedidjah.ch/
"""

__author__ = 'Maximilien Riehl'

import os

try:
    import jedi
except ImportError:
    jedi = None

from pybuilder.core import after, task, init, use_plugin, depends
from pybuilder.errors import BuildFailedException, MissingPrerequisiteException, InternalException
from pybuilder.utils import discover_files_matching

use_plugin("python.core")

@init
def initialize_jedi_linter_plugin(project, logger):
    project.build_depends_on("jedi")
    project.set_property_if_unset("jedi_linter_break_build", False)
    project.set_property_if_unset("jedi_linter_verbose", False)

    logger.warn("The jedi plugin is unstable since the linter API will probably change.")

@after("prepare")
def assert_jedi_is_installed(logger):
    if not jedi:
        raise MissingPrerequisiteException("Missing build dependency `jedi`, please install_dependencies first.")
    if "_analysis" not in dir(jedi.Script):
        raise InternalException(
            "The jedi linter API changed, please file a bug at https://github.com/pybuilder/pybuilder/issues/new")

@task
@depends("prepare")
def analyze(project, logger):
    root_directory = os.getcwd()
    source_modules = discover_files_matching(project.get_property("dir_source_main_python"),
                                             "*.py")
    errors = []

    logger.info("Executing jedi linter on project sources.")

    try:
        for path in source_modules:
            for error in jedi.Script(path=path)._analysis():
                errors.append(error)
    except Exception as e:
        logger.error("Jedi crashed: {0}".format(e))

    number_of_errors = len(errors)
    output = logger.info if number_of_errors == 0 else logger.warn
    output("Jedi linter found {0} errors.".format(number_of_errors))
    if project.get_property("jedi_linter_verbose") or project.get_property("verbose"):
        for error in errors:
            logger.warn(error)

    if project.get_property("jedi_linter_break_build") and number_of_errors > 0:
        raise BuildFailedException("Jedi linter found errors")

    os.chdir(root_directory)  # jedi chdirs into directories, so undo it
<commit_msg>add jedi traceback to debug output<commit_after>#   -*- coding: utf-8 -*-
#
#   This file is part of PyBuilder
#
#   Copyright 2011-2014 PyBuilder Team
#
#   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.

"""
    Plugin for Jedi linting support.

    https://jedi.jedidjah.ch/
"""

__author__ = 'Maximilien Riehl'

import os

try:
    import jedi
except ImportError:
    jedi = None

from pybuilder.core import after, task, init, use_plugin, depends
from pybuilder.errors import BuildFailedException, MissingPrerequisiteException, InternalException
from pybuilder.utils import discover_files_matching

use_plugin("python.core")

@init
def initialize_jedi_linter_plugin(project, logger):
    project.build_depends_on("jedi")
    project.set_property_if_unset("jedi_linter_break_build", False)
    project.set_property_if_unset("jedi_linter_verbose", False)

    logger.warn("The jedi plugin is unstable since the linter API will probably change.")

@after("prepare")
def assert_jedi_is_installed(logger):
    if not jedi:
        raise MissingPrerequisiteException("Missing build dependency `jedi`, please install_dependencies first.")
    if "_analysis" not in dir(jedi.Script):
        raise InternalException(
            "The jedi linter API changed, please file a bug at https://github.com/pybuilder/pybuilder/issues/new")

@task
@depends("prepare")
def analyze(project, logger):
    root_directory = os.getcwd()
    source_modules = discover_files_matching(project.get_property("dir_source_main_python"),
                                             "*.py")
    errors = []

    logger.info("Executing jedi linter on project sources.")

    try:
        for path in source_modules:
            for error in jedi.Script(path=path)._analysis():
                errors.append(error)
    except Exception as e:
        logger.error("Jedi crashed: {0}".format(e))
        import traceback
        logger.debug(traceback.format_exc())

    number_of_errors = len(errors)
    output = logger.info if number_of_errors == 0 else logger.warn
    output("Jedi linter found {0} errors.".format(number_of_errors))
    if project.get_property("jedi_linter_verbose") or project.get_property("verbose"):
        for error in errors:
            logger.warn(error)

    if project.get_property("jedi_linter_break_build") and number_of_errors > 0:
        raise BuildFailedException("Jedi linter found errors")

    os.chdir(root_directory)  # jedi chdirs into directories, so undo it
<|endoftext|>


<commit_before>"""
apipkg: control the exported namespace of a python package.

see http://pypi.python.org/pypi/apipkg

(c) holger krekel, 2009 - MIT license
"""
import sys
from types import ModuleType

__version__ = "1.0b2"

def initpkg(pkgname, exportdefs):
    """ initialize given package from the export definitions.
        replace it in sys.modules
    """
    mod = ApiModule(pkgname, exportdefs)
    oldmod = sys.modules[pkgname]
    mod.__file__ = getattr(oldmod, '__file__', None)
    mod.__version__ = getattr(oldmod, '__version__', None)
    mod.__path__ = getattr(oldmod, '__path__', None)
    sys.modules[pkgname]  = mod

def importobj(importspec):
    """ return object specified by importspec."""
    modpath, attrname = importspec.split(":")
    module = __import__(modpath, None, None, ['__doc__'])
    return getattr(module, attrname)

class ApiModule(ModuleType):
    def __init__(self, name, importspec, parent=None):
        self.__name__ = name
        self.__all__ = list(importspec)
        self.__map__ = {}
        for name, importspec in importspec.items():
            if isinstance(importspec, dict):
                package = '%s.%s'%(self.__name__, name)
                apimod = ApiModule(package, importspec, parent=self)
                sys.modules[package] = apimod
                setattr(self, name, apimod)
            else:
                if not importspec.count(":") == 1:
                    raise ValueError("invalid importspec %r" % (importspec,))
                if name == '__doc__':
                    self.__doc__ = importobj(importspec)
                else:
                    if importspec[0] == '.':
                        importspec = self.__name__ + importspec
                    self.__map__[name] = importspec

    def __repr__(self):
        return '<ApiModule %r>' % (self.__name__,)

    def __getattr__(self, name):
        try:
            importspec = self.__map__.pop(name)
        except KeyError:
            raise AttributeError(name)
        else:
            result = importobj(importspec)
            setattr(self, name, result)
            return result

    def __dict__(self):
        # force all the content of the module to be loaded when __dict__ is read
        dictdescr = ModuleType.__dict__['__dict__']
        dict = dictdescr.__get__(self)
        if dict is not None:
            for name in self.__all__:
                hasattr(self, name)  # force attribute load, ignore errors
        return dict
    __dict__ = property(__dict__)
<commit_msg>use new apipkg version<commit_after>"""
apipkg: control the exported namespace of a python package.

see http://pypi.python.org/pypi/apipkg

(c) holger krekel, 2009 - MIT license
"""
import sys
from types import ModuleType

__version__ = "1.0b2"

def initpkg(pkgname, exportdefs):
    """ initialize given package from the export definitions. """
    mod = ApiModule(pkgname, exportdefs, implprefix=pkgname)
    oldmod = sys.modules[pkgname]
    mod.__file__ = getattr(oldmod, '__file__', None)
    mod.__version__ = getattr(oldmod, '__version__', None)
    mod.__path__ = getattr(oldmod, '__path__', None)
    sys.modules[pkgname]  = mod

def importobj(modpath, attrname):
    module = __import__(modpath, None, None, ['__doc__'])
    return getattr(module, attrname)

class ApiModule(ModuleType):
    def __init__(self, name, importspec, implprefix=None):
        self.__name__ = name
        self.__all__ = list(importspec)
        self.__map__ = {}
        self.__implprefix__ = implprefix or name
        for name, importspec in importspec.items():
            if isinstance(importspec, dict):
                subname = '%s.%s'%(self.__name__, name)
                apimod = ApiModule(subname, importspec, implprefix)
                sys.modules[subname] = apimod
                setattr(self, name, apimod)
            else:
                modpath, attrname = importspec.split(':')
                if modpath[0] == '.':
                    modpath = implprefix + modpath
                if name == '__doc__':
                    self.__doc__ = importobj(modpath, attrname)
                else:
                    self.__map__[name] = (modpath, attrname)

    def __repr__(self):
        return '<ApiModule %r>' % (self.__name__,)

    def __getattr__(self, name):
        try:
            modpath, attrname = self.__map__[name]
        except KeyError:
            raise AttributeError(name)
        else:
            result = importobj(modpath, attrname)
            setattr(self, name, result)
            del self.__map__[name]
            return result

    def __dict__(self):
        # force all the content of the module to be loaded when __dict__ is read
        dictdescr = ModuleType.__dict__['__dict__']
        dict = dictdescr.__get__(self)
        if dict is not None:
            for name in self.__all__:
                hasattr(self, name)  # force attribute load, ignore errors
        return dict
    __dict__ = property(__dict__)
<|endoftext|>


<commit_before>'''Using VGGNet-16 on the CIFAR10 small images dataset.

Code for VGGNet architecture from: https://gist.github.com/baraldilorenzo/07d7802847aaad0a35d3

'''

from __future__ import print_function
import keras
import time
import matplotlib as mpl
mpl.use('Agg')    # Save graph to file
import matplotlib.pyplot as plt
from keras.datasets import cifar10
from keras.preprocessing.image import ImageDataGenerator
from keras.models import Sequential
from keras.layers import Flatten, Dense, Dropout, Activation
from keras.layers import Conv2D, MaxPooling2D, ZeroPadding2D
from keras.optimizers import SGD
import cv2, numpy as np

now = time.time()

batch_size = 32
num_classes = 10
epochs = 25
data_augmentation = True

# input image dimensions
img_rows, img_cols = 32, 32
# The CIFAR10 images are RGB.
img_channels = 3

# The data, shuffled and split between train and test sets:
(x_train, y_train), (x_test, y_test) = cifar10.load_data()
print('x_train shape:', x_train.shape)
print(x_train.shape[0], 'train samples')
print(x_test.shape[0], 'test samples')

# Convert class vectors to binary class matrices.
y_train = keras.utils.to_categorical(y_train, num_classes)
y_test = keras.utils.to_categorical(y_test, num_classes)

model = Sequential()

# Block 1
model.add(ZeroPadding2D((1,1),input_shape=x_train.shape[1:]))
model.add(Conv2D(64, (3, 3)))
model.add(Activation('relu'))
model.add(ZeroPadding2D((1,1)))
model.add(Conv2D(64, (3, 3)))
model.add(Activation('relu'))
model.add(MaxPooling2D((2,2), strides=(2,2)))

# Block 2
model.add(ZeroPadding2D((1,1)))
model.add(Conv2D(128, (3, 3)))
model.add(Activation('relu'))
model.add(ZeroPadding2D((1,1)))
model.add(Conv2D(128, (3, 3)))
model.add(Activation('relu'))
model.add(MaxPooling2D((2,2), strides=(2,2)))

# Block 3
model.add(ZeroPadding2D((1,1)))
model.add(Conv2D(256, (3, 3)))
model.add(Activation('relu'))
model.add(ZeroPadding2D((1,1)))
model.add(Conv2D(256, (3, 3)))
model.add(Activation('relu'))
model.add(ZeroPadding2D((1,1)))
model.add(Conv2D(256, (3, 3)))
model.add(Activation('relu'))
model.add(MaxPooling2D((2,2), strides=(2,2)))

# Block 4
model.add(ZeroPadding2D((1,1)))
model.add(Conv2D(512, (3, 3)))
model.add(Activation('relu'))
model.add(ZeroPadding2D((1,1)))
model.add(Conv2D(512, (3, 3)))
model.add(Activation('relu'))
model.add(ZeroPadding2D((1,1)))
model.add(Conv2D(512, (3, 3)))
model.add(Activation('relu'))
model.add(MaxPooling2D((2,2), strides=(2,2)))

# Block 5
model.add(ZeroPadding2D((1,1)))
model.add(Conv2D(512, (3, 3)))
model.add(Activation('relu'))
model.add(ZeroPadding2D((1,1)))
model.add(Conv2D(512, (3, 3)))
model.add(Activation('relu'))
model.add(ZeroPadding2D((1,1)))
model.add(Conv2D(512, (3, 3)))
model.add(Activation('relu'))
model.add(MaxPooling2D((2,2), strides=(2,2)))

model.add(Flatten())
model.add(Dense(4096))
model.add(Activation('relu'))
model.add(Dropout(0.5))
model.add(Dense(4096))
model.add(Activation('relu'))
model.add(Dropout(0.5))
model.add(Dense(num_classes))
model.add(Activation('softmax'))

#sgd = SGD(lr=0.1, decay=1e-3, momentum=1.0, nesterov=True)
adam = keras.optimizers.Adam(lr=0.001)
model.compile(loss='categorical_crossentropy', optimizer=adam, metrics=['accuracy'])

'''
x_train = x_train.astype('float32')
x_test = x_test.astype('float32')
x_train /= 255
x_test /= 255
'''

hist = model.fit(x_train, y_train, batch_size=batch_size, epochs=epochs, validation_data=(x_test, y_test), shuffle=True)
train_loss = hist.history['loss']
train_accuracy = hist.history['acc']
test_loss = hist.history['val_loss']
test_accuracy = hist.history['val_acc']
print(hist)

fig = plt.figure()
plt.plot(train_accuracy, '-', test_accuracy, '-', train_loss, '--', test_loss, '--')
plt.title('VGGNet')
plt.ylabel('Train and Test Accuracy/Loss')
plt.xlabel('Epochs')
fig.savefig('graph.png', bbox_inches='tight')

print("Time Elapsed:", time.time() - now)
<commit_msg>Added preprocessing to CIFAR-10 and changed lr for adam to 1.0<commit_after>'''Using VGGNet-16 on the CIFAR10 small images dataset.

Code for VGGNet architecture from: https://gist.github.com/baraldilorenzo/07d7802847aaad0a35d3
Code for Cifar-10 preprocessing: https://github.com/fchollet/keras/blob/master/examples/cifar10_cnn.py

'''

from __future__ import print_function
import keras
import time
import matplotlib as mpl
mpl.use('Agg')    # Save graph to file
import matplotlib.pyplot as plt
from keras.datasets import cifar10
from keras.preprocessing.image import ImageDataGenerator
from keras.models import Sequential
from keras.layers import Flatten, Dense, Dropout, Activation
from keras.layers import Conv2D, MaxPooling2D, ZeroPadding2D
from keras.optimizers import SGD
import cv2, numpy as np

now = time.time()

batch_size = 32
num_classes = 10
epochs = 25
data_augmentation = True

# input image dimensions
img_rows, img_cols = 32, 32
# The CIFAR10 images are RGB.
img_channels = 3

# The data, shuffled and split between train and test sets:
(x_train, y_train), (x_test, y_test) = cifar10.load_data()
print('x_train shape:', x_train.shape)
print(x_train.shape[0], 'train samples')
print(x_test.shape[0], 'test samples')

# Convert class vectors to binary class matrices.
y_train = keras.utils.to_categorical(y_train, num_classes)
y_test = keras.utils.to_categorical(y_test, num_classes)

model = Sequential()

# Block 1
model.add(ZeroPadding2D((1,1),input_shape=x_train.shape[1:]))
model.add(Conv2D(64, (3, 3)))
model.add(Activation('relu'))
model.add(ZeroPadding2D((1,1)))
model.add(Conv2D(64, (3, 3)))
model.add(Activation('relu'))
model.add(MaxPooling2D((2,2), strides=(2,2)))

# Block 2
model.add(ZeroPadding2D((1,1)))
model.add(Conv2D(128, (3, 3)))
model.add(Activation('relu'))
model.add(ZeroPadding2D((1,1)))
model.add(Conv2D(128, (3, 3)))
model.add(Activation('relu'))
model.add(MaxPooling2D((2,2), strides=(2,2)))

# Block 3
model.add(ZeroPadding2D((1,1)))
model.add(Conv2D(256, (3, 3)))
model.add(Activation('relu'))
model.add(ZeroPadding2D((1,1)))
model.add(Conv2D(256, (3, 3)))
model.add(Activation('relu'))
model.add(ZeroPadding2D((1,1)))
model.add(Conv2D(256, (3, 3)))
model.add(Activation('relu'))
model.add(MaxPooling2D((2,2), strides=(2,2)))

# Block 4
model.add(ZeroPadding2D((1,1)))
model.add(Conv2D(512, (3, 3)))
model.add(Activation('relu'))
model.add(ZeroPadding2D((1,1)))
model.add(Conv2D(512, (3, 3)))
model.add(Activation('relu'))
model.add(ZeroPadding2D((1,1)))
model.add(Conv2D(512, (3, 3)))
model.add(Activation('relu'))
model.add(MaxPooling2D((2,2), strides=(2,2)))

# Block 5
model.add(ZeroPadding2D((1,1)))
model.add(Conv2D(512, (3, 3)))
model.add(Activation('relu'))
model.add(ZeroPadding2D((1,1)))
model.add(Conv2D(512, (3, 3)))
model.add(Activation('relu'))
model.add(ZeroPadding2D((1,1)))
model.add(Conv2D(512, (3, 3)))
model.add(Activation('relu'))
model.add(MaxPooling2D((2,2), strides=(2,2)))

model.add(Flatten())
model.add(Dense(4096))
model.add(Activation('relu'))
model.add(Dropout(0.5))
model.add(Dense(4096))
model.add(Activation('relu'))
model.add(Dropout(0.5))
model.add(Dense(num_classes))
model.add(Activation('softmax'))

sgd = SGD(lr=1.0, decay=1e-5, momentum=0.9, nesterov=True)
adam = keras.optimizers.Adam(lr=1)
model.compile(loss='categorical_crossentropy', optimizer=adam, metrics=['accuracy'])

'''
x_train = x_train.astype('float32')
x_test = x_test.astype('float32')
x_train /= 255
x_test /= 255
'''

datagen = ImageDataGenerator(
        featurewise_center=False,  # set input mean to 0 over the dataset
        samplewise_center=False,  # set each sample mean to 0
        featurewise_std_normalization=False,  # divide inputs by std of the dataset
        samplewise_std_normalization=False,  # divide each input by its std
        zca_whitening=False,  # apply ZCA whitening
        rotation_range=0,  # randomly rotate images in the range (degrees, 0 to 180)
        width_shift_range=0.1,  # randomly shift images horizontally (fraction of total width)
        height_shift_range=0.1,  # randomly shift images vertically (fraction of total height)
        horizontal_flip=True,  # randomly flip images
        vertical_flip=False)  # randomly flip images

# Compute quantities required for featurewise normalization
# (std, mean, and principal components if ZCA whitening is applied).
datagen.fit(x_train)

# Fit the model on the batches generated by datagen.flow().
hist = model.fit_generator(datagen.flow(x_train, y_train,
                                 batch_size=batch_size),
                    steps_per_epoch=x_train.shape[0] // batch_size,
                    epochs=epochs,
                    validation_data=(x_test, y_test))

#hist = model.fit(x_train, y_train, batch_size=batch_size, epochs=epochs, validation_data=(x_test, y_test), shuffle=True)
train_loss = hist.history['loss']
train_accuracy = hist.history['acc']
test_loss = hist.history['val_loss']
test_accuracy = hist.history['val_acc']
print(hist)

fig = plt.figure()
plt.plot(train_accuracy, '-', test_accuracy, '-', train_loss, '--', test_loss, '--')
plt.title('VGGNet')
plt.ylabel('Train and Test Accuracy/Loss')
plt.xlabel('Epochs')
fig.savefig('graph.png', bbox_inches='tight')

print("Time Elapsed:", time.time() - now)
<|endoftext|>


<commit_before>"""Markdown template filter."""

from django import template
from django.utils.safestring import mark_safe

import bleach
import markdown as markdown_

register = template.Library()

ADDITIONAL_TAGS = ['p', 'br']

@register.filter(name='markdown')
def markdown_filter(value):
    """Convert markdown value to html."""
    rendered_html = markdown_.markdown(value)
    bleached_html = bleach.clean(rendered_html, tags=bleach.ALLOWED_TAGS + ADDITIONAL_TAGS, strip=True)
    return mark_safe(bleached_html)
<commit_msg>allow pre tags<commit_after>"""Markdown template filter."""

from django import template
from django.utils.safestring import mark_safe

import bleach
import markdown as markdown_

register = template.Library()

ADDITIONAL_TAGS = ['p', 'br', 'pre']

@register.filter(name='markdown')
def markdown_filter(value):
    """Convert markdown value to html."""
    rendered_html = markdown_.markdown(value)
    bleached_html = bleach.clean(rendered_html, tags=bleach.ALLOWED_TAGS + ADDITIONAL_TAGS, strip=True)
    return mark_safe(bleached_html)
<|endoftext|>


<commit_before>import logging
import struct
import threading

import serial
import serial.tools.list_ports

COMMAND_TO_CHANNEL = {
	'F': 0x00,
	'W': 0x01,
	'H': 0x02,
	'C': 0x03
}

class SerialPort(object):
	def __init__(self, port_name):
		self.port_name = port_name
		self.serial_port = None
		self.serial_lock = None
		self.log_thread = None

		self.serial_lock = threading.Lock()
		self.initSerialPort()

	def initSerialPort(self):
		port_device = self.get_serial_port_device()
		logging.info("Initializing port %s", port_device)
		try:
			# Init Serial port
			self.serial_port = serial.Serial(port_device, timeout=1, baudrate=115200)
			self.serial_port.flushInput()
			self.serial_port.flushOutput()

		except (OSError, serial.serialutil.SerialException) as error:
			logging.error("Cannot initialize. Reason: %s", error)
			from vjdummyserial import VjDummySerial
			self.serial_port = VjDummySerial(port_device)
			logging.error("Running on dummy serial")

		logging.debug("Serial: %s", self.serial_port)

	def _send_serial_command(self, command, value):
		if command not in COMMAND_TO_CHANNEL:
			logging.error("Unknown command: %s", command)
			return

		message = self.int2bin(0xF6) + self.int2bin(0x6F) + self.int2bin(0x04) + self.int2bin(COMMAND_TO_CHANNEL[command]) + self.int2bin(value)

		if self.serial_port:
			try:
				self.serial_lock.acquire(True)
				ret = self.serial_port.write(message)
				logging.debug("Sent %s Bytes, being", ret)
				for x in message:
					logging.debug("%s", self.bin2int(x))
			finally:
				self.serial_lock.release()
		else:
			logging.error("Not sending %s, %s - no serial port?", command, value)

	def send_serial_command(self, command, value):
		if not self.serial_port:
			self.initSerialPort()

		if self.serial_port:
			try:
				self._send_serial_command(command, value)
			except IOError:
				self.initSerialPort()
				self._send_serial_command(command, value)

	def get_serial_port_device(self):
		ports = serial.tools.list_ports.grep(self.port_name)
		try:
			return ports.next().device
		except StopIteration:
			return None

	@staticmethod
	def int2bin(value):
		return struct.pack('!B', value)

	@staticmethod
	def bin2int(value):
		return struct.unpack('!B', value)[0]

	def close(self):
		# Close serial port
		logging.info("Close serial port")
		if self.serial_port is not None and self.serial_port.isOpen():
			self.serial_port.close()
			self.serial_port = None
<commit_msg>[Python3] First stash of compatibilty changes.<commit_after>import logging
import struct
import threading

import serial
import serial.tools.list_ports

COMMAND_TO_CHANNEL = {
	'F': 0x00,
	'W': 0x01,
	'H': 0x02,
	'C': 0x03
}

class SerialPort(object):
	def __init__(self, port_name):
		self.port_name = port_name
		self.serial_port = None
		self.serial_lock = None
		self.log_thread = None

		self.serial_lock = threading.Lock()
		self.initSerialPort()

	def initSerialPort(self):
		port_device = self.get_serial_port_device()
		logging.info("Initializing port %s", port_device)
		try:
			# Init Serial port
			self.serial_port = serial.Serial(port_device, timeout=1, baudrate=115200)
			self.serial_port.flushInput()
			self.serial_port.flushOutput()

		except (OSError, serial.serialutil.SerialException) as error:
			logging.error("Cannot initialize. Reason: %s", error)
			from vjdummyserial import VjDummySerial
			self.serial_port = VjDummySerial(port_device)
			logging.error("Running on dummy serial")

		logging.debug("Serial: %s", self.serial_port)

	def _send_serial_command(self, command, value):
		if command not in COMMAND_TO_CHANNEL:
			logging.error("Unknown command: %s", command)
			return

		message = self.int2bin(0xF6) + self.int2bin(0x6F) + self.int2bin(0x04) + self.int2bin(COMMAND_TO_CHANNEL[command]) + self.int2bin(value)

		if self.serial_port:
			try:
				self.serial_lock.acquire(True)
				ret = self.serial_port.write(message)
				logging.debug("Sent %s Bytes, being", ret)
				for x in message:
					logging.debug("%s", self.bin2int(x))
			finally:
				self.serial_lock.release()
		else:
			logging.error("Not sending %s, %s - no serial port?", command, value)

	def send_serial_command(self, command, value):
		if not self.serial_port:
			self.initSerialPort()

		if self.serial_port:
			try:
				self._send_serial_command(command, value)
			except IOError:
				self.initSerialPort()
				self._send_serial_command(command, value)

	def get_serial_port_device(self):
		ports = serial.tools.list_ports.grep(self.port_name)
		try:
			return next(ports).device
		except StopIteration:
			return None

	@staticmethod
	def int2bin(value):
		return struct.pack('!B', value)

	@staticmethod
	def bin2int(value):
		if isinstance(value, int):
			return value
		return struct.unpack('!B', value)[0]

	def close(self):
		# Close serial port
		logging.info("Close serial port")
		if self.serial_port is not None and self.serial_port.isOpen():
			self.serial_port.close()
			self.serial_port = None
<|endoftext|>


<commit_before>import os
import sys
import stat
import subprocess
import requests
from xbmctorrent.common import RESOURCES_PATH
from xbmctorrent.platform import PLATFORM

def ensure_exec_perms(file_):
    st = os.stat(file_)
    os.chmod(file_, st.st_mode | stat.S_IEXEC)
    return file_

BIN_PATH = os.path.join(RESOURCES_PATH, "bin", "%(os)s_%(arch)s" % PLATFORM)
TORRENT2HTTP_BINARY = ensure_exec_perms(os.path.join(BIN_PATH, "torrent2http%s" % (sys.platform == "win32" and ".exe" or "")))

def find_free_port():
    import socket
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.bind(('', 0))
    port = s.getsockname()[1]
    s.close()
    return port

def start(**kwargs):
    args = [TORRENT2HTTP_BINARY]
    bind_address = "localhost:%d" % find_free_port()
    kwargs["--bind"] = bind_address

    # Are we on ARM? Activate minimum memory mode, and nice torrent2http
    if PLATFORM["arch"] == "arm":
        args = ["/bin/nice", "-n", "19"] + args
        kwargs["minmem"] = None

    for k, v in kwargs.items():
        args.append("--%s" % k)
        if v:
            args.append(v)

    # Needed because torrent2http is vendored with Boost and libtorrent-rasterbar
    env = os.environ.copy()
    env["LD_LIBRARY_PATH"] = BIN_PATH
    env["DYLD_LIBRARY_PATH"] = BIN_PATH

    import xbmc
    xbmc.log(repr(args))
    kwargs = {
        "cwd": BIN_PATH,
        "env": env,
    }
    if sys.platform == "win32":
        si = subprocess.STARTUPINFO()
        si.dwFlags |= 1
        si.wShowWindow = 0
        kwargs["startupinfo"] = si
    proc = subprocess.Popen(args, **kwargs)
    proc.get_bind_address = lambda: bind_address
    proc.shutdown = lambda: requests.post("http://%s/shutdown" % bind_address)
    return proc
<commit_msg>Oops, fix typo, pushed too soon<commit_after>import os
import sys
import stat
import subprocess
import requests
from xbmctorrent.common import RESOURCES_PATH
from xbmctorrent.platform import PLATFORM

def ensure_exec_perms(file_):
    st = os.stat(file_)
    os.chmod(file_, st.st_mode | stat.S_IEXEC)
    return file_

BIN_PATH = os.path.join(RESOURCES_PATH, "bin", "%(os)s_%(arch)s" % PLATFORM)
TORRENT2HTTP_BINARY = ensure_exec_perms(os.path.join(BIN_PATH, "torrent2http%s" % (sys.platform == "win32" and ".exe" or "")))

def find_free_port():
    import socket
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.bind(('', 0))
    port = s.getsockname()[1]
    s.close()
    return port

def start(**kwargs):
    args = [TORRENT2HTTP_BINARY]
    bind_address = "localhost:%d" % find_free_port()
    kwargs["bind"] = bind_address

    # Are we on ARM? Activate minimum memory mode, and nice torrent2http
    if PLATFORM["arch"] == "arm":
        args = ["/bin/nice", "-n", "19"] + args
        kwargs["minmem"] = None

    for k, v in kwargs.items():
        args.append("--%s" % k)
        if v:
            args.append(v)

    # Needed because torrent2http is vendored with Boost and libtorrent-rasterbar
    env = os.environ.copy()
    env["LD_LIBRARY_PATH"] = BIN_PATH
    env["DYLD_LIBRARY_PATH"] = BIN_PATH

    import xbmc
    xbmc.log(repr(args))
    kwargs = {
        "cwd": BIN_PATH,
        "env": env,
    }
    if sys.platform == "win32":
        si = subprocess.STARTUPINFO()
        si.dwFlags |= 1
        si.wShowWindow = 0
        kwargs["startupinfo"] = si
    proc = subprocess.Popen(args, **kwargs)
    proc.get_bind_address = lambda: bind_address
    proc.shutdown = lambda: requests.post("http://%s/shutdown" % bind_address)
    return proc
<|endoftext|>


<commit_before>""" CalvinSys handler """

import importlib
import pkgutil
import os
import inspect
from calvin.utilities import calvinconfig
from calvin.utilities.calvinlogger import get_logger

_conf = calvinconfig.get()
_log = get_logger(__name__)

class Sys(object):
    """ Calvin system object """
    def __init__(self, node=None):
        self._node = node

        path = [os.path.dirname(inspect.getfile(Sys))]
        name = __name__

        self._name = name
        self._path = path
        self.modules = {}

        packages = pkgutil.walk_packages(path, name + '.')
        blacklist = _conf.get(None, 'capabilities_blacklist') or []
        node_id = node.id if node else "<no node>"
        _log.analyze(node_id, "+ BLACKLIST", {'blacklist': blacklist})
        for package in packages:
            if not package[2]:
                (_, _, package_name) = package[1].partition(".")
                # this is a loadable module
                if package_name not in blacklist:
                    self.modules[package_name] = {'name': package[1], 'module': None, 'error': None}
            else:
                # This is a package, ignore it
                pass

    def scheduler_wakeup(self):
        self._node.sched.trigger_loop()

    def _loadmodule(self, modulename):
        if self.modules[modulename]['module'] or self.modules[modulename]['error']:
            return

        try:
            self.modules[modulename]['module'] = importlib.import_module(self.modules[modulename]['name'])
        except Exception as e:
            _log.info("Module '%s' not available: %s" % (modulename, e))
            self.modules[modulename]['error'] = e

    def use_requirement(self, actor, modulename):
        if self.require(modulename):
            raise self.modules[modulename]['error']
        return self.modules[modulename]['module'].register(node=self._node, actor=actor)

    def require(self, modulename):
        if not self.modules.get(modulename, None):
            self.modules[modulename] = {'error': Exception("No such capability '%s'" % (modulename,)), 'module': None}

        self._loadmodule(modulename)

        return self.modules[modulename]['error']

    def has_capability(self, requirement):
        """
        Returns True if "requirement" is satisfied in this system,
        otherwise False.
        """
        return not self.require(requirement)

    def list_capabilities(self):
        """
        Returns list of requirements this system satisfies
        """
        return [cap for cap in self.modules.keys() if self.has_capability(cap)]
<commit_msg>log.analyze() allows node id None<commit_after>""" CalvinSys handler """

import importlib
import pkgutil
import os
import inspect
from calvin.utilities import calvinconfig
from calvin.utilities.calvinlogger import get_logger

_conf = calvinconfig.get()
_log = get_logger(__name__)

class Sys(object):
    """ Calvin system object """
    def __init__(self, node=None):
        self._node = node

        path = [os.path.dirname(inspect.getfile(Sys))]
        name = __name__

        self._name = name
        self._path = path
        self.modules = {}

        packages = pkgutil.walk_packages(path, name + '.')
        blacklist = _conf.get(None, 'capabilities_blacklist') or []
        _log.analyze(node.id if node else None, "+ BLACKLIST", {'blacklist': blacklist})
        for package in packages:
            if not package[2]:
                (_, _, package_name) = package[1].partition(".")
                # this is a loadable module
                if package_name not in blacklist:
                    self.modules[package_name] = {'name': package[1], 'module': None, 'error': None}
            else:
                # This is a package, ignore it
                pass

    def scheduler_wakeup(self):
        self._node.sched.trigger_loop()

    def _loadmodule(self, modulename):
        if self.modules[modulename]['module'] or self.modules[modulename]['error']:
            return

        try:
            self.modules[modulename]['module'] = importlib.import_module(self.modules[modulename]['name'])
        except Exception as e:
            _log.info("Module '%s' not available: %s" % (modulename, e))
            self.modules[modulename]['error'] = e

    def use_requirement(self, actor, modulename):
        if self.require(modulename):
            raise self.modules[modulename]['error']
        return self.modules[modulename]['module'].register(node=self._node, actor=actor)

    def require(self, modulename):
        if not self.modules.get(modulename, None):
            self.modules[modulename] = {'error': Exception("No such capability '%s'" % (modulename,)), 'module': None}

        self._loadmodule(modulename)

        return self.modules[modulename]['error']

    def has_capability(self, requirement):
        """
        Returns True if "requirement" is satisfied in this system,
        otherwise False.
        """
        return not self.require(requirement)

    def list_capabilities(self):
        """
        Returns list of requirements this system satisfies
        """
        return [cap for cap in self.modules.keys() if self.has_capability(cap)]
<|endoftext|>


<commit_before>#!/usr/bin/env python3
# Copyright (C) 2015 nickolas360 (https://github.com/nickolas360)
#
# This file is part of nimbot.
#
# nimbot is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# nimbot is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with nimbot.  If not, see <http://www.gnu.org/licenses/>.
"""
Usage:
  nimbot <host> <port> <channel> [-i] [-n nick]

Options:
  -i --identify  Identify with NickServ. Accepts a password through stdin.
  -n <nick>      The nickname to use [default: nimbot].
"""
from pyrcb import IrcBot
from mention import Mention
from docopt import docopt
from collections import defaultdict
from datetime import datetime
from humanize import naturaltime
import os
import re
import sys
import threading

# If modified, replace the source URL with one to the modified version.
help_message = """\
nimbot: The non-intrusive mailbot.
Source: https://github.com/nickolas360/nimbot (AGPLv3 or later)
To send mail, begin your message with "[nickname]:".
You can specify multiple nicknames, separated by commas or colons.
nimbot is {0}.
Usage:
  help     Show this help message.
  check    Manually check for mail.
  clear    Clear all non-private mail without reading.
  enable   Enable nimbot.
  disable  Disable nimbot.
  send     Send a private message.
           Syntax: send [nickname] [message]
"""

class Nimbot(IrcBot):
    def __init__(self):
        super(Nimbot, self).__init__()
        self.msg_index = 0
        self.names = []

        self.mentions = defaultdict(list)
        self.private_mentions = defaultdict(list)
        self.enabled = defaultdict(lambda: True)

        self.script_dir = os.path.dirname(os.path.realpath(sys.argv[0]))
        self.prefs_path = os.path.join(self.script_dir, "prefs")
        self.mentions_path = os.path.join(self.script_dir, "saved_mentions")

        self.read_prefs()
        self.read_mentions()

    def deliver(self, nickname, mentions):
        for mention in mentions:
            message = "[{0}] <{1}> {2}".format(
                naturaltime(mention.time), mention.sender, mention.message)
            if mention.private:
                message = "[private] " + message
            self.send(nickname, message)
            print("[deliver -> {0}] {1}".format(nickname, message))

    def on_query(self, message, nickname):
        cmd = message.split(" ", 1)[0].lower()
        nick = nickname.lower()
        print("[{2}] [query] <{0}> {1}".format(
            nickname, message, datetime.now().replace(microsecond=0)))

        if cmd == "help":
            help_lines = help_message.format(
                ["disabled", "enabled"][self.enabled[nick]]).splitlines()
            for line in help_lines:
                self.send(nick, line)
        elif cmd == "check":
            if not self.enabled[nick]:
                self.send(nick, "nimbot is disabled.")
            elif self.mentions[nick] or self.private_mentions[nick]:
                self.deliver(nick, self.mentions[nick])
                self.deliver(nick, self.private_mentions[nick])
                self.mentions[nick] = []
                self.private_mentions[nick] = []
            else:
                self.send(nick, "No new mail.")
        elif cmd == "clear":
            self.mentions[nick] = []
            self.send(nick, "Mail cleared.")
        elif cmd == "enable" or cmd == "disable":
            if self.enabled[nick] != (cmd == "enable"):
                self.enabled[nick] = (cmd == "enable")
                self.mentions[nick] = []
            self.send(nick, "nimbot {0}d.".format(cmd))
        elif cmd == "send" and len(message.split(" ", 2)) == 3:
            target, msg = message.split(" ", 2)[1:]
            if not self.enabled[target]:
                self.send(nick, "{0} has disabled nimbot.".format(target))
            else:
                self.private_mentions[target].append(Mention(
                    msg, nickname, target, 0, datetime.now(), private=True))
                self.send(nick, "Message sent.")
        else:
            self.send(nick, '"/msg {0} help" for help.'.format(self.nickname))

        if self.mentions[nick] or self.private_mentions[nick]:
            self.send(nick, 'You have unread messages. "/msg {0} check" '
                            'to read.'.format(self.nickname))

    def on_message(self, message, nickname, target, is_query):
        if is_query:
            self.on_query(message, nickname)
            return

        self.msg_index += 1
        nick = nickname.lower()
        mentioned = defaultdict(bool)
        print("[{3}] [{0}] <{1}> {2}".format(
            target, nickname, message, datetime.now().replace(microsecond=0)))

        for name in self.names:
            if not self.enabled[name] or name == nick:
                continue
            if re.match(r"(\W*{0}\W|(\w+[:,] ?)+{0}[:])".format(
                    re.escape(name)), message, re.I):
                self.mentions[name].append(Mention(
                    message, nickname, name, self.msg_index, datetime.now()))
                mentioned[name] = True

        if mentioned:
            print("[mentioned] {0}".format(", ".join(mentioned)))
        if not self.enabled[nick]:
            return

        for mention in self.mentions[nick]:
            old_message = self.msg_index - mention.index > 50
            is_reply = mentioned[mention.sender]
            new_msg_exists = any(self.msg_index - m.index < 40 and
                                 m.sender.lower() == mention.sender.lower()
                                 for m in self.mentions[nick])
            if old_message and (not is_reply or new_msg_exists):
                self.deliver(nick, [mention])

        self.deliver(nick, self.private_mentions[nick])
        self.mentions[nick] = []
        self.private_mentions[nick] = []

    def on_join(self, nickname, channel, is_self):
        nick = nickname.lower()
        if is_self:
            return
        if nick not in self.names:
            self.names.append(nick)
            return
        if self.enabled[nick]:
            self.deliver(nick, self.mentions[nick])
            self.mentions[nick] = []

    def on_nick(self, nickname, new_nickname, is_self):
        if is_self:
            return
        nick = nickname.lower()
        new_nick = new_nickname.lower()
        if new_nick not in self.names:
            self.names.append(new_nick)
            self.enabled[new_nick] = self.enabled[nick]

    def on_names(self, channel, names):
        for name in [n.lower() for n in names]:
            if name not in self.names and name != self.nickname.lower():
                self.names.append(name)

    def print_prefs(self, file=sys.stdout):
        for name in self.names:
            print(name, self.enabled[name], file=file)

    def print_mentions(self, file=sys.stdout):
        for mentions in self.mentions.values():
            for m in mentions:
                print(m.to_string(self.msg_index), file=file)
        for mentions in self.private_mentions.values():
            for m in mentions:
                print(m.to_string(), file=file)

    def save_prefs(self):
        with open(self.prefs_path, "w") as f:
            print("# [name (lowercase)] [enabled (True/False)]", file=f)
            self.print_prefs(file=f)

    def save_mentions(self):
        with open(self.mentions_path, "w") as f:
            self.print_mentions(file=f)

    def read_prefs(self):
        if not os.path.isfile(self.prefs_path):
            return
        with open(self.prefs_path) as f:
            for line in f:
                if not line.startswith("#"):
                    name, enabled = line.rstrip().split(" ", 1)
                    self.names.append(name)
                    self.enabled[name] = enabled == "True"

    def read_mentions(self):
        if not os.path.isfile(self.mentions_path):
            return
        with open(self.mentions_path) as f:
            for line in f:
                m = Mention.from_string(line)
                if not m.private:
                    self.mentions[m.target].append(m)
                else:
                    self.private_mentions[m.target].append(m)

def command_loop(bot):
    while True:
        line = input()
        if line == "prefs":
            bot.print_prefs(file=sys.stderr)
        elif line == "mentions":
            bot.print_mentions(file=sys.stderr)
        else:
            print('Unknown command. Type "prefs" or "mentions".',
                  file=sys.stderr)

def main():
    args = docopt(__doc__)
    bot = Nimbot()
    bot.connect(args["<host>"], int(args["<port>"]))

    if args["--identify"]:
        print("Password: ", end="", file=sys.stderr)
        bot.password(input())
        print("Received password.", file=sys.stderr)
    bot.register(args["-n"])
    bot.join(args["<channel>"])

    t = threading.Thread(target=command_loop, args=[bot])
    t.daemon = True
    t.start()

    try:
        bot.listen()
    except KeyboardInterrupt:
        return
    finally:
        bot.save_prefs()
        bot.save_mentions()
    print("Disconnected from server.")

if __name__ == "__main__":
    main()
<commit_msg>Fix mention regex<commit_after>#!/usr/bin/env python3
# Copyright (C) 2015 nickolas360 (https://github.com/nickolas360)
#
# This file is part of nimbot.
#
# nimbot is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# nimbot is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with nimbot.  If not, see <http://www.gnu.org/licenses/>.
"""
Usage:
  nimbot <host> <port> <channel> [-i] [-n nick]

Options:
  -i --identify  Identify with NickServ. Accepts a password through stdin.
  -n <nick>      The nickname to use [default: nimbot].
"""
from pyrcb import IrcBot
from mention import Mention
from docopt import docopt
from collections import defaultdict
from datetime import datetime
from humanize import naturaltime
import os
import re
import sys
import threading

# If modified, replace the source URL with one to the modified version.
help_message = """\
nimbot: The non-intrusive mailbot.
Source: https://github.com/nickolas360/nimbot (AGPLv3 or later)
To send mail, begin your message with "[nickname]:".
You can specify multiple nicknames, separated by commas or colons.
nimbot is {0}.
Usage:
  help     Show this help message.
  check    Manually check for mail.
  clear    Clear all non-private mail without reading.
  enable   Enable nimbot.
  disable  Disable nimbot.
  send     Send a private message.
           Syntax: send [nickname] [message]
"""

class Nimbot(IrcBot):
    def __init__(self):
        super(Nimbot, self).__init__()
        self.msg_index = 0
        self.names = []

        self.mentions = defaultdict(list)
        self.private_mentions = defaultdict(list)
        self.enabled = defaultdict(lambda: True)

        self.script_dir = os.path.dirname(os.path.realpath(sys.argv[0]))
        self.prefs_path = os.path.join(self.script_dir, "prefs")
        self.mentions_path = os.path.join(self.script_dir, "saved_mentions")

        self.read_prefs()
        self.read_mentions()

    def deliver(self, nickname, mentions):
        for mention in mentions:
            message = "[{0}] <{1}> {2}".format(
                naturaltime(mention.time), mention.sender, mention.message)
            if mention.private:
                message = "[private] " + message
            self.send(nickname, message)
            print("[deliver -> {0}] {1}".format(nickname, message))

    def on_query(self, message, nickname):
        cmd = message.split(" ", 1)[0].lower()
        nick = nickname.lower()
        print("[{2}] [query] <{0}> {1}".format(
            nickname, message, datetime.now().replace(microsecond=0)))

        if cmd == "help":
            help_lines = help_message.format(
                ["disabled", "enabled"][self.enabled[nick]]).splitlines()
            for line in help_lines:
                self.send(nick, line)
        elif cmd == "check":
            if not self.enabled[nick]:
                self.send(nick, "nimbot is disabled.")
            elif self.mentions[nick] or self.private_mentions[nick]:
                self.deliver(nick, self.mentions[nick])
                self.deliver(nick, self.private_mentions[nick])
                self.mentions[nick] = []
                self.private_mentions[nick] = []
            else:
                self.send(nick, "No new mail.")
        elif cmd == "clear":
            self.mentions[nick] = []
            self.send(nick, "Mail cleared.")
        elif cmd == "enable" or cmd == "disable":
            if self.enabled[nick] != (cmd == "enable"):
                self.enabled[nick] = (cmd == "enable")
                self.mentions[nick] = []
            self.send(nick, "nimbot {0}d.".format(cmd))
        elif cmd == "send" and len(message.split(" ", 2)) == 3:
            target, msg = message.split(" ", 2)[1:]
            if not self.enabled[target]:
                self.send(nick, "{0} has disabled nimbot.".format(target))
            else:
                self.private_mentions[target].append(Mention(
                    msg, nickname, target, 0, datetime.now(), private=True))
                self.send(nick, "Message sent.")
        else:
            self.send(nick, '"/msg {0} help" for help.'.format(self.nickname))

        if self.mentions[nick] or self.private_mentions[nick]:
            self.send(nick, 'You have unread messages. "/msg {0} check" '
                            'to read.'.format(self.nickname))

    def on_message(self, message, nickname, target, is_query):
        if is_query:
            self.on_query(message, nickname)
            return

        self.msg_index += 1
        nick = nickname.lower()
        mentioned = defaultdict(bool)
        print("[{3}] [{0}] <{1}> {2}".format(
            target, nickname, message, datetime.now().replace(microsecond=0)))

        for name in self.names:
            if not self.enabled[name] or name == nick:
                continue
            if re.match(r"(\W*{0}\W|([a-zA-Z0-9[\]\\`_^{{|}}\-]+[:,] ?)"
                        r"+{0}[:,])".format(re.escape(name), message, re.I)):
                self.mentions[name].append(Mention(
                    message, nickname, name, self.msg_index, datetime.now()))
                mentioned[name] = True

        if mentioned:
            print("[mentioned] {0}".format(", ".join(mentioned)))
        if not self.enabled[nick]:
            return

        for mention in self.mentions[nick]:
            old_message = self.msg_index - mention.index > 50
            is_reply = mentioned[mention.sender]
            new_msg_exists = any(self.msg_index - m.index < 40 and
                                 m.sender.lower() == mention.sender.lower()
                                 for m in self.mentions[nick])
            if old_message and (not is_reply or new_msg_exists):
                self.deliver(nick, [mention])

        self.deliver(nick, self.private_mentions[nick])
        self.mentions[nick] = []
        self.private_mentions[nick] = []

    def on_join(self, nickname, channel, is_self):
        nick = nickname.lower()
        if is_self:
            return
        if nick not in self.names:
            self.names.append(nick)
            return
        if self.enabled[nick]:
            self.deliver(nick, self.mentions[nick])
            self.mentions[nick] = []

    def on_nick(self, nickname, new_nickname, is_self):
        if is_self:
            return
        nick = nickname.lower()
        new_nick = new_nickname.lower()
        if new_nick not in self.names:
            self.names.append(new_nick)
            self.enabled[new_nick] = self.enabled[nick]

    def on_names(self, channel, names):
        for name in [n.lower() for n in names]:
            if name not in self.names and name != self.nickname.lower():
                self.names.append(name)

    def print_prefs(self, file=sys.stdout):
        for name in self.names:
            print(name, self.enabled[name], file=file)

    def print_mentions(self, file=sys.stdout):
        for mentions in self.mentions.values():
            for m in mentions:
                print(m.to_string(self.msg_index), file=file)
        for mentions in self.private_mentions.values():
            for m in mentions:
                print(m.to_string(), file=file)

    def save_prefs(self):
        with open(self.prefs_path, "w") as f:
            print("# [name (lowercase)] [enabled (True/False)]", file=f)
            self.print_prefs(file=f)

    def save_mentions(self):
        with open(self.mentions_path, "w") as f:
            self.print_mentions(file=f)

    def read_prefs(self):
        if not os.path.isfile(self.prefs_path):
            return
        with open(self.prefs_path) as f:
            for line in f:
                if not line.startswith("#"):
                    name, enabled = line.rstrip().split(" ", 1)
                    self.names.append(name)
                    self.enabled[name] = enabled == "True"

    def read_mentions(self):
        if not os.path.isfile(self.mentions_path):
            return
        with open(self.mentions_path) as f:
            for line in f:
                m = Mention.from_string(line)
                if not m.private:
                    self.mentions[m.target].append(m)
                else:
                    self.private_mentions[m.target].append(m)

def command_loop(bot):
    while True:
        line = input()
        if line == "prefs":
            bot.print_prefs(file=sys.stderr)
        elif line == "mentions":
            bot.print_mentions(file=sys.stderr)
        else:
            print('Unknown command. Type "prefs" or "mentions".',
                  file=sys.stderr)

def main():
    args = docopt(__doc__)
    bot = Nimbot()
    bot.connect(args["<host>"], int(args["<port>"]))

    if args["--identify"]:
        print("Password: ", end="", file=sys.stderr)
        bot.password(input())
        print("Received password.", file=sys.stderr)
    bot.register(args["-n"])
    bot.join(args["<channel>"])

    t = threading.Thread(target=command_loop, args=[bot])
    t.daemon = True
    t.start()

    try:
        bot.listen()
    except KeyboardInterrupt:
        return
    finally:
        bot.save_prefs()
        bot.save_mentions()
    print("Disconnected from server.")

if __name__ == "__main__":
    main()
<|endoftext|>