<commit_before>import re
from clay.parserlib import *
from clay.tokens import *
from clay import linecol

__all__ = ["LexerError", "tokenize"]

class LexerInput(Input) :
    def __init__(self, data) :
        super(LexerInput,self).__init__(data)

    def consume_string(self, s) :
        self.max_pos = max(self.max_pos, self.pos)
        if not self.data.startswith(s, self.pos) :
            return Failure
        self.pos += len(s)
        return s

    def consume_regex(self, regex) :
        self.max_pos = max(self.max_pos, self.pos)
        match = regex.match(self.data, self.pos)
        if match is None :
            return Failure
        s = match.group()
        self.pos += len(s)
        return s

def string_parser(s) :
    def parser_proc(input) :
        return input.consume_string(s)
    return parser_proc

def regex_parser(regex) :
    def parser_proc(input) :
        return input.consume_regex(regex)
    return parser_proc

def not_ahead(parser) :
    def parser_proc(input) :
        input.begin()
        result = parser(input)
        input.rollback()
        if result is Failure :
            return ""
        return Failure
    return parser_proc

def token(parser, klass) :
    def parser_proc(input) :
        start = input.pos
        result = parser(input)
        if result is Failure :
            return result
        end = input.pos
        return klass(result, start, end)
    return parser_proc

#
# symbol
#

symbols = ("( ) [ ] { } "
           + "<< >> | & "
           + "<= <> != >= == < > "
           + ": -> = ; , "
           + "+ - ~ . ^ ").split()
symbols_regex = "|".join([re.escape(s) for s in symbols])
symbol = token(regex_parser(re.compile(symbols_regex)),
               klass=Symbol)

#
# keyword, identifier
#

keyword_list = ("record var def "
                + "break continue return if else while for in "
                + "or and not bitor bitand bitxor ").split()
keyword_set = set(keyword_list)

ident_char1 = condition(lambda x : x.isalpha() or (x == "_"))
ident_char2 = condition(lambda x : x.isalpha() or x.isdigit() or (x == "_"))
keyword_ident1 = modify(sequence(ident_char1, zeroplus(ident_char2)),
                        lambda x : x[0] + "".join(x[1]))
def keyword_ident_factory(s, start, end) :
    if s in keyword_set :
        return Keyword(s, start, end)
    else :
        return Identifier(s, start, end)

keyword_identifier = token(keyword_ident1, klass=keyword_ident_factory)

#
# make_string_parser
#

def make_string_parser(delim, is_single, is_unicode) :
    def mk(x) :
        if is_unicode :
            return unichr(x)
        return chr(x)
    def conv(c) :
        assert type(c) is str
        if is_unicode :
            c = unichr(ord(c))
        return c
    simple_escape = choice(modify(literal("n"), lambda x : conv("\n")),
                           modify(literal("r"), lambda x : conv("\r")),
                           modify(literal("t"), lambda x : conv("\t")),
                           modify(literal("a"), lambda x : conv("\a")),
                           modify(literal("b"), lambda x : conv("\b")),
                           modify(literal("f"), lambda x : conv("\f")),
                           modify(literal("v"), lambda x : conv("\v")),
                           modify(literal("\\"), lambda x : conv("\\")),
                           modify(literal("'"), lambda x : conv("'")),
                           modify(literal("\""), lambda x : conv("\"")))
    octal_digit = condition(lambda c : c in "01234567")
    octal_escape = modify(many(octal_digit, min=1, max=3),
                          lambda x : mk(int("".join(x), 8)))
    hex_digit = condition(lambda c : c in "0123456789ABCDEFabcdef")
    hex_escape = modify(sequence(literal("x"), many(hex_digit,min=2,max=2)),
                        lambda x : mk(int("".join(x[1]),16)))
    unicode_escape1 = modify(sequence(literal("u"), many(hex_digit,min=4,max=4)),
                             lambda x : mk(int("".join(x[1]),16)))
    unicode_escape2 = modify(sequence(literal("U"), many(hex_digit,min=8,max=8)),
                             lambda x : mk(int("".join(x[1]),16)))
    escapes = [simple_escape, octal_escape, hex_escape]
    if is_unicode :
        escapes.extend([unicode_escape1, unicode_escape2])
    escape_char = sequence(literal("\\"), choice(*escapes))
    simple_set = delim + "\\"
    simple_char = modify(condition(lambda c : c not in simple_set),
                         lambda x : conv(x))
    string_char = choice(simple_char, escape_char)
    if is_single :
        parser = modify(sequence(literal(delim), string_char,
                                 literal(delim)),
                        lambda x : x[1])
    else :
        parser = modify(sequence(literal(delim), zeroplus(string_char),
                                 literal(delim)),
                        lambda x : "".join(x[1]))
    return parser

#
# string_literal, char_literal, bytes_literal, byte_literal
#

string_literal1 = make_string_parser("\"", is_single=False, is_unicode=True)
string_literal = token(string_literal1, klass=StringLiteral)

char_literal1 = make_string_parser("\'", is_single=True, is_unicode=True)
char_literal = token(char_literal1, klass=CharLiteral)

bytes_literal1 = make_string_parser("\"", is_single=False, is_unicode=False)
bytes_literal2 = modify(sequence(literal("b"), bytes_literal1),
                        lambda x : x[1])
bytes_literal = token(bytes_literal2, klass=BytesLiteral)

byte_literal1 = make_string_parser("\'", is_single=True, is_unicode=False)
byte_literal2 = modify(sequence(literal("b"), byte_literal1),
                       lambda x : x[1])
byte_literal = token(byte_literal2, klass=ByteLiteral)

#
# int_literal
#

hex_digit = condition(lambda c : c in "0123456789ABCDEFabcdef")
hex_int = modify(sequence(literal("0"), literal("x"), oneplus(hex_digit)),
                 lambda x : int("".join(x[2]), 16))

binary_digit = condition(lambda c : c in "01")
binary_int = modify(sequence(literal("0"), literal("b"),
                             oneplus(binary_digit)),
                    lambda x : int("".join(x[2]), 2))

octal_digit = condition(lambda c : c in "01234567")
octal_int = modify(sequence(literal("0"), oneplus(octal_digit)),
                   lambda x : int("".join(x[1]), 8))

decimal_digit = condition(lambda c : c in "0123456789")
decimal_int = modify(oneplus(decimal_digit), lambda x : int("".join(x)))

unsigned_int = choice(hex_int, binary_int, octal_int, decimal_int)
positive_int = modify(sequence(literal("+"), unsigned_int),
                      lambda x : x[1])
negative_int = modify(sequence(literal("-"), unsigned_int),
                      lambda x : -x[1])
int_literal = token(choice(negative_int, positive_int, unsigned_int),
                    klass=IntLiteral)

#
# space, single_line_comment, multi_line_comment
#

space = token(oneplus(condition(lambda x : x.isspace())),
              klass=Space)

end_of_line = condition(lambda c : c in "\r\n")
any_char = condition(lambda c : True)
slc_char = modify(sequence(not_ahead(end_of_line), any_char),
                         lambda x : x[1])
slc_string1 = modify(zeroplus(slc_char), lambda x : "".join(x))
slc_string2 = modify(sequence(string_parser("//"), slc_string1),
                     lambda x : x[1])
single_line_comment = token(slc_string2, klass=SingleLineComment)

mlc_begin = string_parser("/*")
mlc_end = string_parser("*/")
mlc_char = modify(sequence(not_ahead(mlc_end), any_char),
                  lambda x : x[1])
mlc_string1 = modify(zeroplus(mlc_char), lambda x : "".join(x))
mlc_string2 = modify(sequence(mlc_begin, mlc_string1, mlc_end),
                     lambda x : x[1])

multi_line_comment = token(mlc_string2, klass=MultiLineComment)

#
# one_token
#

one_token = choice(space, single_line_comment, multi_line_comment,
                   symbol, keyword_identifier,
                   string_literal, char_literal,
                   bytes_literal, byte_literal,
                   int_literal)

#
# LexerError, Lexer
#

class LexerError(Exception) :
    def __init__(self, filename, line, column) :
        self.filename = filename
        self.line = line
        self.column = column

def tokenize(data, filename, remove_space=True) :
    tokens = []
    input = LexerInput(data)
    while input.pos < len(data) :
        token = one_token(input)
        if token is Failure :
            line,column = linecol.locate_line_column(data, input.max_pos)
            raise LexerError(filename, line, column)
        tokens.append(token)
    def is_space(t) :
        return type(t) in [Space,SingleLineComment,MultiLineComment]
    if remove_space :
        tokens = [t for t in tokens if not is_space(t)]
    return tokens
<commit_msg>added 'true', and 'false' as keywords in lexer.<commit_after>import re
from clay.parserlib import *
from clay.tokens import *
from clay import linecol

__all__ = ["LexerError", "tokenize"]

class LexerInput(Input) :
    def __init__(self, data) :
        super(LexerInput,self).__init__(data)

    def consume_string(self, s) :
        self.max_pos = max(self.max_pos, self.pos)
        if not self.data.startswith(s, self.pos) :
            return Failure
        self.pos += len(s)
        return s

    def consume_regex(self, regex) :
        self.max_pos = max(self.max_pos, self.pos)
        match = regex.match(self.data, self.pos)
        if match is None :
            return Failure
        s = match.group()
        self.pos += len(s)
        return s

def string_parser(s) :
    def parser_proc(input) :
        return input.consume_string(s)
    return parser_proc

def regex_parser(regex) :
    def parser_proc(input) :
        return input.consume_regex(regex)
    return parser_proc

def not_ahead(parser) :
    def parser_proc(input) :
        input.begin()
        result = parser(input)
        input.rollback()
        if result is Failure :
            return ""
        return Failure
    return parser_proc

def token(parser, klass) :
    def parser_proc(input) :
        start = input.pos
        result = parser(input)
        if result is Failure :
            return result
        end = input.pos
        return klass(result, start, end)
    return parser_proc

#
# symbol
#

symbols = ("( ) [ ] { } "
           + "<< >> | & "
           + "<= <> != >= == < > "
           + ": -> = ; , "
           + "+ - ~ . ^ ").split()
symbols_regex = "|".join([re.escape(s) for s in symbols])
symbol = token(regex_parser(re.compile(symbols_regex)),
               klass=Symbol)

#
# keyword, identifier
#

keyword_list = ("record var def "
                + "break continue return if else while for in "
                + "or and not bitor bitand bitxor "
                + "true false ").split()
keyword_set = set(keyword_list)

ident_char1 = condition(lambda x : x.isalpha() or (x == "_"))
ident_char2 = condition(lambda x : x.isalpha() or x.isdigit() or (x == "_"))
keyword_ident1 = modify(sequence(ident_char1, zeroplus(ident_char2)),
                        lambda x : x[0] + "".join(x[1]))
def keyword_ident_factory(s, start, end) :
    if s in keyword_set :
        return Keyword(s, start, end)
    else :
        return Identifier(s, start, end)

keyword_identifier = token(keyword_ident1, klass=keyword_ident_factory)

#
# make_string_parser
#

def make_string_parser(delim, is_single, is_unicode) :
    def mk(x) :
        if is_unicode :
            return unichr(x)
        return chr(x)
    def conv(c) :
        assert type(c) is str
        if is_unicode :
            c = unichr(ord(c))
        return c
    simple_escape = choice(modify(literal("n"), lambda x : conv("\n")),
                           modify(literal("r"), lambda x : conv("\r")),
                           modify(literal("t"), lambda x : conv("\t")),
                           modify(literal("a"), lambda x : conv("\a")),
                           modify(literal("b"), lambda x : conv("\b")),
                           modify(literal("f"), lambda x : conv("\f")),
                           modify(literal("v"), lambda x : conv("\v")),
                           modify(literal("\\"), lambda x : conv("\\")),
                           modify(literal("'"), lambda x : conv("'")),
                           modify(literal("\""), lambda x : conv("\"")))
    octal_digit = condition(lambda c : c in "01234567")
    octal_escape = modify(many(octal_digit, min=1, max=3),
                          lambda x : mk(int("".join(x), 8)))
    hex_digit = condition(lambda c : c in "0123456789ABCDEFabcdef")
    hex_escape = modify(sequence(literal("x"), many(hex_digit,min=2,max=2)),
                        lambda x : mk(int("".join(x[1]),16)))
    unicode_escape1 = modify(sequence(literal("u"), many(hex_digit,min=4,max=4)),
                             lambda x : mk(int("".join(x[1]),16)))
    unicode_escape2 = modify(sequence(literal("U"), many(hex_digit,min=8,max=8)),
                             lambda x : mk(int("".join(x[1]),16)))
    escapes = [simple_escape, octal_escape, hex_escape]
    if is_unicode :
        escapes.extend([unicode_escape1, unicode_escape2])
    escape_char = sequence(literal("\\"), choice(*escapes))
    simple_set = delim + "\\"
    simple_char = modify(condition(lambda c : c not in simple_set),
                         lambda x : conv(x))
    string_char = choice(simple_char, escape_char)
    if is_single :
        parser = modify(sequence(literal(delim), string_char,
                                 literal(delim)),
                        lambda x : x[1])
    else :
        parser = modify(sequence(literal(delim), zeroplus(string_char),
                                 literal(delim)),
                        lambda x : "".join(x[1]))
    return parser

#
# string_literal, char_literal, bytes_literal, byte_literal
#

string_literal1 = make_string_parser("\"", is_single=False, is_unicode=True)
string_literal = token(string_literal1, klass=StringLiteral)

char_literal1 = make_string_parser("\'", is_single=True, is_unicode=True)
char_literal = token(char_literal1, klass=CharLiteral)

bytes_literal1 = make_string_parser("\"", is_single=False, is_unicode=False)
bytes_literal2 = modify(sequence(literal("b"), bytes_literal1),
                        lambda x : x[1])
bytes_literal = token(bytes_literal2, klass=BytesLiteral)

byte_literal1 = make_string_parser("\'", is_single=True, is_unicode=False)
byte_literal2 = modify(sequence(literal("b"), byte_literal1),
                       lambda x : x[1])
byte_literal = token(byte_literal2, klass=ByteLiteral)

#
# int_literal
#

hex_digit = condition(lambda c : c in "0123456789ABCDEFabcdef")
hex_int = modify(sequence(literal("0"), literal("x"), oneplus(hex_digit)),
                 lambda x : int("".join(x[2]), 16))

binary_digit = condition(lambda c : c in "01")
binary_int = modify(sequence(literal("0"), literal("b"),
                             oneplus(binary_digit)),
                    lambda x : int("".join(x[2]), 2))

octal_digit = condition(lambda c : c in "01234567")
octal_int = modify(sequence(literal("0"), oneplus(octal_digit)),
                   lambda x : int("".join(x[1]), 8))

decimal_digit = condition(lambda c : c in "0123456789")
decimal_int = modify(oneplus(decimal_digit), lambda x : int("".join(x)))

unsigned_int = choice(hex_int, binary_int, octal_int, decimal_int)
positive_int = modify(sequence(literal("+"), unsigned_int),
                      lambda x : x[1])
negative_int = modify(sequence(literal("-"), unsigned_int),
                      lambda x : -x[1])
int_literal = token(choice(negative_int, positive_int, unsigned_int),
                    klass=IntLiteral)

#
# space, single_line_comment, multi_line_comment
#

space = token(oneplus(condition(lambda x : x.isspace())),
              klass=Space)

end_of_line = condition(lambda c : c in "\r\n")
any_char = condition(lambda c : True)
slc_char = modify(sequence(not_ahead(end_of_line), any_char),
                         lambda x : x[1])
slc_string1 = modify(zeroplus(slc_char), lambda x : "".join(x))
slc_string2 = modify(sequence(string_parser("//"), slc_string1),
                     lambda x : x[1])
single_line_comment = token(slc_string2, klass=SingleLineComment)

mlc_begin = string_parser("/*")
mlc_end = string_parser("*/")
mlc_char = modify(sequence(not_ahead(mlc_end), any_char),
                  lambda x : x[1])
mlc_string1 = modify(zeroplus(mlc_char), lambda x : "".join(x))
mlc_string2 = modify(sequence(mlc_begin, mlc_string1, mlc_end),
                     lambda x : x[1])

multi_line_comment = token(mlc_string2, klass=MultiLineComment)

#
# one_token
#

one_token = choice(space, single_line_comment, multi_line_comment,
                   symbol, keyword_identifier,
                   string_literal, char_literal,
                   bytes_literal, byte_literal,
                   int_literal)

#
# LexerError, Lexer
#

class LexerError(Exception) :
    def __init__(self, filename, line, column) :
        self.filename = filename
        self.line = line
        self.column = column

def tokenize(data, filename, remove_space=True) :
    tokens = []
    input = LexerInput(data)
    while input.pos < len(data) :
        token = one_token(input)
        if token is Failure :
            line,column = linecol.locate_line_column(data, input.max_pos)
            raise LexerError(filename, line, column)
        tokens.append(token)
    def is_space(t) :
        return type(t) in [Space,SingleLineComment,MultiLineComment]
    if remove_space :
        tokens = [t for t in tokens if not is_space(t)]
    return tokens
<|endoftext|>


<commit_before># This is the master class for the Python PS bot.
# Every general-purpose command is included in this file, with the sole exception
# being onMessage(), as derived applications may need to acces this function.
#
# As such, unless a valid onMessage() function is supplied when creating an
# instance, this will not run.
#
# To run this, the following modules are required:
# PyYAML == 3.11
# requests == 2.5.1
# simplejson == 3.6.5
# websocket-client == 0.23.0

import websocket
import requests
import json
import yaml
import datetime

import prettyText
from room import Room
from plugins.battling.battleHandler import BattleHandler

class PokemonShowdownBot:
    ''' Controls the most basic aspects of connecting to Pokemon Showdown as well as commands '''

    def __init__(self, url, onMessage = None):
        with open("details.yaml", 'r') as yaml_file:
            self.details = yaml.load(yaml_file)
            self.Groups = {' ':0,'+':1,'★':1,'%':2,'@':3,'&':4,'#':5,'~':6}
            self.splitMessage = onMessage if onMessage else self.onMessage
            self.intro()
            websocket.enableTrace(True)
            self.ws = websocket.WebSocketApp(url,
                                             on_message = onMessage,
                                             on_error = self.onError,
                                             on_close = self.onClose)
            self.ws.on_open = self.onOpen
            self.bh = BattleHandler(self.ws, self.details['user'])
            self.ws.run_forever()

    def onError(self, code, error):
        print(code, ':', error)
    def onClose(self, message):
        print('websocket closed')
    def onOpen(self, message):
        print('websocket opened')

    def intro(self):
        print(prettyText.intro)
    def log(self, msg, user):
        print('Command: {cmd} (user: {user})'.format(cmd = msg, user = user))
    def userIsSelf(self, user):
        return self.details['user'] == user

    def send(self, msg):
        self.ws.send(msg)

    def login(self, challenge, challengekeyid):
        payload = { 'act':'login',
                    'name': self.details['user'],
                    'pass': self.details['password'],
                    'challengekeyid': challengekeyid,
                    'challenge': challenge
                    }
        r = requests.post('http://play.pokemonshowdown.com/action.php', data=payload)
        assertion = json.loads(r.text[1:])['assertion']

        if assertion:
            self.send(('|/trn '+ self.details['user']+',0,'+str(assertion)).encode('utf-8'))
            return True
        else:
            print('Assertion failed')
            return False

    def joinRoom(self, room, data = None):
        self.send('|/join ' + room)
        self.details['rooms'][room] = Room(room, data)
    def leaveRoom(self, room):
        ''' Attempts to leave a PS room '''
        if room not in self.details['rooms']:
            print('Error! {name} not in {room}'.format(name=self.details['user'], room=room))
            return False
        self.send('|/leave ' + room)
        self.details['rooms'].pop(room, None)
        return True
    def getRoom(self, roomName):
        alias = {'nu':'neverused', 'tsb':'thestable'}
        if roomName in alias:
            roomName = alias[roomName]
        return self.details['rooms'][roomName]

    def say(self, room, msg):
        if '\n' in msg:
            # DO NOT ABUSE THIS
            for m in msg.split('\n'):
                self.send('{room}|{text}'.format(room = room, text = m))
        else:
            self.send('{room}|{text}'.format(room = room, text = msg))
    def sendPm(self, user, msg):
        self.send('|/pm {usr}, {text}'.format(usr = user, text = msg))

    def reply(self, room, user, response, samePlace):
        if samePlace:
            self.say(room, response)
        else:
            self.sendPm(user['name'], response)

    def escapeText(self, line):
        if line[0] == '/':
            return '/' + line
        elif line[0] == '!':
            return ' ' + line
        return line
    def extractCommand(self, msg):
        return msg[len(self.details['command']):].split(' ')[0].lower()
    def evalPermission(self, user):
        return self.Groups[user['group']] >= self.Groups[self.details['broadcastrank']] or self.details['master'] == user['name'] or user['name'] in self.details['whitelist']
    def takeAction(self, room, user, action, reason):
        self.send('{room}|/{act} {user}, {reason}'.format(room = room, act = action, user = user, reason = reason))

    # Default onMessage if none is given (This only support logging in, nothing else)
    # To get any actual use from the bot, create a custom onMessage function.
    def onMessage(self, ws, message):
        if not message: return
        parts = message.split('|')
        if parts[1] == 'challstr':
            print('Attempting to log in...')
            self.login(message[3], message[2])
        elif parts[1] == 'updateuser':
            if self.details['user'] not in parts[2]: return
            if parts[3] == '1':
                print('Loged in...')

<commit_msg>better error print out<commit_after># This is the master class for the Python PS bot.
# Every general-purpose command is included in this file, with the sole exception
# being onMessage(), as derived applications may need to acces this function.
#
# As such, unless a valid onMessage() function is supplied when creating an
# instance, this will not run.
#
# To run this, the following modules are required:
# PyYAML == 3.11
# requests == 2.5.1
# simplejson == 3.6.5
# websocket-client == 0.23.0

import websocket
import requests
import json
import yaml
import datetime

import prettyText
from room import Room
from plugins.battling.battleHandler import BattleHandler

class PokemonShowdownBot:
    ''' Controls the most basic aspects of connecting to Pokemon Showdown as well as commands '''

    def __init__(self, url, onMessage = None):
        with open("details.yaml", 'r') as yaml_file:
            self.details = yaml.load(yaml_file)
            self.Groups = {' ':0,'+':1,'★':1,'%':2,'@':3,'&':4,'#':5,'~':6}
            self.splitMessage = onMessage if onMessage else self.onMessage
            self.intro()
            websocket.enableTrace(True)
            self.ws = websocket.WebSocketApp(url,
                                             on_message = onMessage,
                                             on_error = self.onError,
                                             on_close = self.onClose)
            self.ws.on_open = self.onOpen
            self.bh = BattleHandler(self.ws, self.details['user'])
            self.ws.run_forever()

    def onError(self, ws, error):
        print(error)
    def onClose(self, message):
        print('websocket closed')
    def onOpen(self, message):
        print('websocket opened')

    def intro(self):
        print(prettyText.intro)
    def log(self, msg, user):
        print('Command: {cmd} (user: {user})'.format(cmd = msg, user = user))
    def userIsSelf(self, user):
        return self.details['user'] == user

    def send(self, msg):
        self.ws.send(msg)

    def login(self, challenge, challengekeyid):
        payload = { 'act':'login',
                    'name': self.details['user'],
                    'pass': self.details['password'],
                    'challengekeyid': challengekeyid,
                    'challenge': challenge
                    }
        r = requests.post('http://play.pokemonshowdown.com/action.php', data=payload)
        assertion = json.loads(r.text[1:])['assertion']

        if assertion:
            self.send(('|/trn '+ self.details['user']+',0,'+str(assertion)).encode('utf-8'))
            return True
        else:
            print('Assertion failed')
            return False

    def joinRoom(self, room, data = None):
        self.send('|/join ' + room)
        self.details['rooms'][room] = Room(room, data)
    def leaveRoom(self, room):
        ''' Attempts to leave a PS room '''
        if room not in self.details['rooms']:
            print('Error! {name} not in {room}'.format(name=self.details['user'], room=room))
            return False
        self.send('|/leave ' + room)
        self.details['rooms'].pop(room, None)
        return True
    def getRoom(self, roomName):
        alias = {'nu':'neverused', 'tsb':'thestable'}
        if roomName in alias:
            roomName = alias[roomName]
        return self.details['rooms'][roomName]

    def say(self, room, msg):
        if '\n' in msg:
            # DO NOT ABUSE THIS
            for m in msg.split('\n'):
                self.send('{room}|{text}'.format(room = room, text = m))
        else:
            self.send('{room}|{text}'.format(room = room, text = msg))
    def sendPm(self, user, msg):
        self.send('|/pm {usr}, {text}'.format(usr = user, text = msg))

    def reply(self, room, user, response, samePlace):
        if samePlace:
            self.say(room, response)
        else:
            self.sendPm(user['name'], response)

    def escapeText(self, line):
        if line[0] == '/':
            return '/' + line
        elif line[0] == '!':
            return ' ' + line
        return line
    def extractCommand(self, msg):
        return msg[len(self.details['command']):].split(' ')[0].lower()
    def evalPermission(self, user):
        return self.Groups[user['group']] >= self.Groups[self.details['broadcastrank']] or self.details['master'] == user['name'] or user['name'] in self.details['whitelist']
    def takeAction(self, room, user, action, reason):
        self.send('{room}|/{act} {user}, {reason}'.format(room = room, act = action, user = user, reason = reason))

    # Default onMessage if none is given (This only support logging in, nothing else)
    # To get any actual use from the bot, create a custom onMessage function.
    def onMessage(self, ws, message):
        if not message: return
        parts = message.split('|')
        if parts[1] == 'challstr':
            print('Attempting to log in...')
            self.login(message[3], message[2])
        elif parts[1] == 'updateuser':
            if self.details['user'] not in parts[2]: return
            if parts[3] == '1':
                print('Loged in...')

<|endoftext|>


<commit_before>######################################################################
#  CliNER - cli.py                                                   #
#                                                                    #
#  Willie Boag                                      wboag@cs.uml.edu #
#                                                                    #
#  Purpose: Command Line Interface for working with CliNER.          #
######################################################################

__author__ = 'Willie Boag'
__date__   = 'Oct. 5, 2014'

import click
import os
import sys
import subprocess
import glob

from note import Note

@click.group()
def clicon():
    pass

supported_formats_help = "Data format ( " + ' | '.join(Note.supportedFormats()) + " )"

# Train
@clicon.command()
@click.option('--annotations'   , help='Concept files for training.'  )
@click.option('--model'         , help='Model output by train.'       )
@click.option('--format'        , help=supported_formats_help         )
@click.option('--grid/--no-grid', help='Flag that enables grid search',
              default=False)
@click.option('--crf/--no-crf'  , help='Flag that enables crfsuite'   ,
              default=True)
@click.argument('input')
def train(annotations, model, format, grid, crf, input):

    # training data needs concept file annotations
    if not annotations:
        print >>sys.stderr, '\n\tError: Must provide annotations for text files'
        print >>sys.stderr,  ''
        exit(1)

    # Base directory
    BASE_DIR = os.environ.get('CLICON_DIR')
    if not BASE_DIR:
        raise Exception('Environment variable CLICON_DIR must be defined')

    # Executable
    runable = os.path.join(BASE_DIR, 'clicon/train.py')

    # Build command
    cmd = ['python', runable, '-t', input]

    # Arguments
    if annotations:
        cmd += ['-c', annotations]
    if model:
        cmd += ['-m',       model]
    if format:
        cmd += ['-f',      format]
    if grid:
        cmd += ['-g']
    if not crf:
        cmd += ['-no-crf']

    # Execute train.py
    subprocess.call(cmd)

# Predict
@clicon.command()
@click.option('--out'   , help='The directory to write the output')
@click.option('--model' , help='Model used to predict on files'   )
@click.option('--format', help=supported_formats_help             )
@click.argument('input')
def predict(model, out, format, input):

    # Base directory
    BASE_DIR = os.environ.get('CLICON_DIR')
    if not BASE_DIR:
        raise Exception('Environment variable CLICON_DIR must be defined')

    # Executable
    runable = os.path.join(BASE_DIR,'clicon/predict.py')

    # Build command
    cmd = ['python', runable, '-i', input]

    # Optional arguments
    if out:
        cmd += ['-o',    out]
    if model:
        cmd += ['-m',  model]
    if format:
        cmd += ['-f', format]

    # Execute train.py
    subprocess.call(cmd)

# Evaluate
@clicon.command()
@click.option('--predictions', help='Directory where predictions  are stored.')
@click.option('--gold'       , help='Directory where gold standard is stored.')
@click.option('--out'        , help='Output file'                             )
@click.option('--format'     , help=supported_formats_help                    )
@click.argument('input')
def evaluate(predictions, gold, out, format, input):

    # Base directory
    BASE_DIR = os.environ.get('CLICON_DIR')
    if not BASE_DIR:
        raise Exception('Environment variable CLICON_DIR must be defined')

    # Executable
    runable = os.path.join(BASE_DIR,'clicon/evaluate.py')

    # Build command
    cmd = ['python', runable, '-t', input]

    # Optional arguments
    if predictions:
        cmd += ['-c', predictions]
    if gold:
        cmd += ['-r',        gold]
    if out:
        cmd += ['-o',         out]
    if format:
        cmd += ['-f',      format]

    # Execute train.py
    subprocess.call(cmd)

# Format
@clicon.command()
@click.option('--annotations', help='Concept files for training.')
@click.option('--format'     , help=supported_formats_help       )
@click.option('--out'        , help='File to write the output.'  )
@click.argument('input')
def format(annotations, format, out, input):

    # Base directory
    BASE_DIR = os.environ.get('CLICON_DIR')
    if not BASE_DIR:
        raise Exception('Environment variable CLICON_DIR must be defined')

    # Executable
    runable = os.path.join(BASE_DIR,'clicon/format.py')

    # Build command
    cmd = ['python', runable, flag, input]

    # Optional arguments
    if annotations:
        cmd += ['-a', annotations]
    if out:
        cmd += ['-o',         out]
    if format:
        cmd += ['-f',      format]

    # Execute train.py
    subprocess.call(cmd)

if __name__ == '__main__':
    clicon()

<commit_msg>fixed issue with note in master<commit_after>######################################################################
#  CliNER - cli.py                                                   #
#                                                                    #
#  Willie Boag                                      wboag@cs.uml.edu #
#                                                                    #
#  Purpose: Command Line Interface for working with CliNER.          #
######################################################################

__author__ = 'Willie Boag'
__date__   = 'Oct. 5, 2014'

import click
import os
import sys
import subprocess
import glob

sys.path.append( os.environ['CLICON_DIR'] + "/clicon/notes" )

from note import Note

@click.group()
def clicon():
    pass

supported_formats_help = "Data format ( " + ' | '.join(Note.supportedFormats()) + " )"

# Train
@clicon.command()
@click.option('--annotations'   , help='Concept files for training.'  )
@click.option('--model'         , help='Model output by train.'       )
@click.option('--format'        , help=supported_formats_help         )
@click.option('--grid/--no-grid', help='Flag that enables grid search',
              default=False)
@click.option('--crf/--no-crf'  , help='Flag that enables crfsuite'   ,
              default=True)
@click.argument('input')
def train(annotations, model, format, grid, crf, input):

    # training data needs concept file annotations
    if not annotations:
        print >>sys.stderr, '\n\tError: Must provide annotations for text files'
        print >>sys.stderr,  ''
        exit(1)

    # Base directory
    BASE_DIR = os.environ.get('CLICON_DIR')
    if not BASE_DIR:
        raise Exception('Environment variable CLICON_DIR must be defined')

    # Executable
    runable = os.path.join(BASE_DIR, 'clicon/train.py')

    # Build command
    cmd = ['python', runable, '-t', input]

    # Arguments
    if annotations:
        cmd += ['-c', annotations]
    if model:
        cmd += ['-m',       model]
    if format:
        cmd += ['-f',      format]
    if grid:
        cmd += ['-g']
    if not crf:
        cmd += ['-no-crf']

    # Execute train.py
    subprocess.call(cmd)

# Predict
@clicon.command()
@click.option('--out'   , help='The directory to write the output')
@click.option('--model' , help='Model used to predict on files'   )
@click.option('--format', help=supported_formats_help             )
@click.argument('input')
def predict(model, out, format, input):

    # Base directory
    BASE_DIR = os.environ.get('CLICON_DIR')
    if not BASE_DIR:
        raise Exception('Environment variable CLICON_DIR must be defined')

    # Executable
    runable = os.path.join(BASE_DIR,'clicon/predict.py')

    # Build command
    cmd = ['python', runable, '-i', input]

    # Optional arguments
    if out:
        cmd += ['-o',    out]
    if model:
        cmd += ['-m',  model]
    if format:
        cmd += ['-f', format]

    # Execute train.py
    subprocess.call(cmd)

# Evaluate
@clicon.command()
@click.option('--predictions', help='Directory where predictions  are stored.')
@click.option('--gold'       , help='Directory where gold standard is stored.')
@click.option('--out'        , help='Output file'                             )
@click.option('--format'     , help=supported_formats_help                    )
@click.argument('input')
def evaluate(predictions, gold, out, format, input):

    # Base directory
    BASE_DIR = os.environ.get('CLICON_DIR')
    if not BASE_DIR:
        raise Exception('Environment variable CLICON_DIR must be defined')

    # Executable
    runable = os.path.join(BASE_DIR,'clicon/evaluate.py')

    # Build command
    cmd = ['python', runable, '-t', input]

    # Optional arguments
    if predictions:
        cmd += ['-c', predictions]
    if gold:
        cmd += ['-r',        gold]
    if out:
        cmd += ['-o',         out]
    if format:
        cmd += ['-f',      format]

    # Execute train.py
    subprocess.call(cmd)

# Format
@clicon.command()
@click.option('--annotations', help='Concept files for training.')
@click.option('--format'     , help=supported_formats_help       )
@click.option('--out'        , help='File to write the output.'  )
@click.argument('input')
def format(annotations, format, out, input):

    # Base directory
    BASE_DIR = os.environ.get('CLICON_DIR')
    if not BASE_DIR:
        raise Exception('Environment variable CLICON_DIR must be defined')

    # Executable
    runable = os.path.join(BASE_DIR,'clicon/format.py')

    # Build command
    cmd = ['python', runable, flag, input]

    # Optional arguments
    if annotations:
        cmd += ['-a', annotations]
    if out:
        cmd += ['-o',         out]
    if format:
        cmd += ['-f',      format]

    # Execute train.py
    subprocess.call(cmd)

if __name__ == '__main__':
    clicon()

<|endoftext|>


<commit_before>from __future__ import print_function

import itertools as it
import abc

import numpy as np

from constraints import IntervalCons
import cellmanager as CM
import err
from utils import print

import matplotlib.pyplot as plt

class Q(object):
    __metaclass__ = abc.ABCMeta

    @abc.abstractmethod
    def split(self, *args):
        return

#     @abc.abstractproperty
#     def dim(self):
#         return

#     @abc.abstractmethod
#     def getxy_ignoramous(self, N, sim, t0=0):
#         """TODO: EXPLICITLY ignores t, d, pvt, ci, pi
#         """
#         return

    @abc.abstractmethod
    def modelQ(self, rm):
        return

    @abc.abstractmethod
    def errorQ(self, include_err, X, Y, rm):
        return

    @abc.abstractmethod
    def __hash__(self):
        return hash((self.cell, tuple(self.eps)))

    @abc.abstractmethod
    def __eq__(self, c):
        return self.cell == c.cell and tuple(self.eps) == tuple(c.eps)

class Qxw(Q):
    # wic is the pi_cons of the overall system and has nothing to
    # do with wcell (of course wcell must be \in wic, but that is
    # all.
    wic = None

    @classmethod
    def init(cls, wic):
        cls.wic = wic

    def __init__(self, xcell, wcell):
        """__init__

        Parameters
        ----------
        abs_state : abstract states
        w_cells : cells associated with the abstract state defining
        range of inputs
        """
        if Qxw.wic is None:
            raise NameError('Class was not initialized. wic is None')

        assert(isinstance(xcell, CM.Cell))
        assert(isinstance(wcell, CM.Cell))

        self.xcell = xcell
        self.wcell = wcell
        self.xwcell = CM.Cell.concatenate(xcell, wcell)
        self.sample_UR_x = self.xcell.sample_UR
        self.sample_UR_w = self.wcell.sample_UR
        self.xdim = xcell.dim
        self.wdim = wcell.dim
        self.dim = xcell.dim + wcell.dim
        self.ival_constraints = self.xwcell.ival_constraints
        return

    def split(self, *args):
        qsplits = self.qx.splits(*args)
        return [Qxw(qsplits, self.wcell) for q in qsplits]

    def sim(self, step_sim, xw_array):
        """TODO: EXPLICITLY ignores t, d, pvt, ci, pi
        """
        d, pvt, s = [np.array([])]*3
        ci = [np.array([])]*2
        t0 = 0
        Yl = []
        x_array = xw_array[:, 0:self.xdim]
        w_array = xw_array[:, self.xdim:]

        for x, pi in zip(x_array, w_array):
            (t_, x_, s_, d_, pvt_, u_) = step_sim(t0, x, s, d, pvt, ci, pi)
            Yl.append(x_)

        # return yw_array
        return np.hstack((np.vstack(Yl), w_array))

    def get_rels(self, N, sim):
        """TODO: EXPLICITLY ignores t, d, pvt, ci, pi
        """
        d, pvt, s = [np.array([])]*3
        ci = np.array([])
        t0 = 0
        Yl = []

        x_array = self.sample_UR_x(N)
        pi_array = self.sample_UR_w(N)
        for x, pi in zip(x_array, pi_array):
            print(pi)
            (t_, x_, s_, d_, pvt_, u_) = sim(t0, x, s, d, pvt, ci, pi)
            Yl.append(x_)

        return np.hstack((x_array, pi_array)), np.vstack(Yl)

    def sat(self, XW):
        """returns a sat array, whose elements are false when unsat
        and true when sat"""
        return self.xcell.ival_constraints.sat(XW[:, 0:self.xdim])

    def modelQ(self, rm):

        #print('error%:', rm.max_error_pc(X, Y))
        # Matrices are extended to include w/pi
        # A = [AB]
        #     [00]
        # AB denotes matrix concatenation.
        # Hence a reset: x' =  Ax + Bw + b
        # can be mimicked as below
        #
        # [x']   = [a00 a01 a02...b00 b01...] * [x] + b + [e0]
        # [w']     [     ...  0 ...         ]   [w]       [e1]
        #
        # This makes x' \in Ax + Bw + b + [el, eh], and
        # makes w' \in [el, eh]
        # We use this to incorporate error and reset w to new values,
        # which in the case of ZOH are just the ranges of w (or pi).

        q = self
        A = np.vstack((rm.A, np.zeros((q.wdim, q.dim))))
        b = np.hstack((rm.b, np.zeros(q.wdim)))
        C, d = q.ival_constraints.poly()
        try:
            assert(A.shape[0] == b.shape[0])    # num lhs (states) is the same
            assert(A.shape[1] == C.shape[1])    # num vars (states + ip) are the same
            assert(C.shape[0] == d.shape[0])    # num constraints are the same
        except AssertionError as e:
            print('\n', A, '\n', b)
            print('\n', C, '\n', d)
            print(A.shape[0], b.shape[0], C.shape[1], d.shape[0])
            raise e
        return A, b

    def errorQ(self, include_err, X, Y, rm):
        q = self
        xic = (rm.error(X, Y) if include_err
               else IntervalCons([0.0]*q.xdim, [0.0]*q.xdim))

        e = IntervalCons.concatenate(xic, Qxw.wic)
        return e

    def __hash__(self):
        return hash(self.xwcell)

    def __eq__(self, qxw):
        return self.xwcell == qxw.xwcell

    def __str__(self):
        return str(self.xwcell)

    def __repr__(self):
        return 'Qxw'+str(self.xwcell)

class Qx(Q):
    def __init__(self, xcell):
        assert(isinstance(xcell, CM.Cell))

        self.xcell = xcell
        self.ival_constraints = xcell.ival_constraints
        self.xdim = xcell.dim
        self.dim = xcell.dim
        return

    def split(self, *args):
        return [Qx(c) for c in self.xcell.split(*args)]

    def sim(self, step_sim, x_array):
        """TODO: EXPLICITLY ignores t, d, pvt, ci, pi
        """
        d, pvt, s = [np.array([])]*3
        ci, pi = [np.array([])]*2
        t0 = 0
        Yl = []

        for x in x_array:
            (t_, x_, s_, d_, pvt_, u_) = step_sim(t0, x, s, d, pvt, ci, pi)
            Yl.append(x_)

        return np.vstack(Yl)

    def get_rels(self, N, sim):
        """TODO: EXPLICITLY ignores t, d, pvt, ci, pi
        """
        d, pvt, s = [np.array([])]*3
        ci, pi = [np.array([])]*2
        t0 = 0
        Yl = []

        #plt.figure()

        x_array = self.xcell.sample_UR(N)
        #print(t0)
        #print(x_array)
        for x in x_array:
            (t_, x_, s_, d_, pvt_, u_) = sim(t0, x, s, d, pvt, ci, pi)
            Yl.append(x_)
        if __debug__:
            #plt.title('ignore')
            #plt.show()
            plt.close()

        return x_array, np.vstack(Yl)

    def sat(self, X):
        """returns a sat array, whose elements are false when unsat
        and true when sat"""
        return self.ival_constraints.sat(X)

    def modelQ(self, rm):
        A, b = rm.A, rm.b
        return A, b

    def errorQ(self, include_err, X, Y, rm):
        e = (rm.error(X, Y) if include_err
             else IntervalCons([0.0]*self.xdim, [0.0]*self.xdim))
        return e

    def __hash__(self):
        return hash(self.xcell)

    def __eq__(self, q):
        return self.xcell == q.xcell

    def __str__(self):
        return str(self.xcell)

    def __repr__(self):
        return 'Qx'+str(self.xcell)

# Unused...should probably delete it if a usecase is not found.
class Qqxw(Q):
    # wic is the pi_cons of the overall system and has nothing to
    # do with wcell (of course wcell must be \in wic, but that is
    # all.
    wic = None

    @classmethod
    def init(cls, wic):
        cls.wic = wic

    def __init__(self, qx, wcell):
        """__init__

        Parameters
        ----------
        abs_state : abstract states
        w_cells : cells associated with the abstract state defining
        range of inputs
        """
        if Qxw.wic is None:
            raise NameError('Class was not initialized. wic is None')

        assert(isinstance(qx, Qx))
        assert(isinstance(wcell, CM.Cell))

        xcell = qx.xcell
        self.xcell = xcell
        self.wcell = wcell
        self.xwcell = CM.Cell.concatenate(xcell, wcell)
        self.sample_UR_x = self.xcell.sample_UR
        self.sample_UR_w = self.wcell.sample_UR
        self.xdim = xcell.dim
        self.wdim = wcell.dim
        self.ival_constraints = self.xwcell.ival_constraints
        return

    def split(self, *args):
        qsplits = self.qx.splits(*args)
        return [Qxw(qsplits, self.wcell) for q in qsplits]

    def get_rels(self, N, sim):
        """TODO: EXPLICITLY ignores t, d, pvt, ci, pi
        """
        d, pvt, s = [np.array([])]*3
        ci = np.array([])
        t0 = 0
        Yl = []

        x_array = self.sample_UR_x(N)
        pi_array = self.sample_UR_w(N)
        for x, pi in zip(x_array, pi_array):
            (t_, x_, s_, d_, pvt_, u_) = sim(t0, x, s, d, pvt, ci, pi)
            Yl.append(x_)

        return np.hstack((x_array, pi_array)), np.vstack(Yl)

    def sat(self, X):
        """returns a sat array, whose elements are false when unsat
        and true when sat"""
        return self.xcell.ival_constraints.sat(X)

    def modelQ(self, rm):

        #print('error%:', rm.max_error_pc(X, Y))
        # Matrices are extended to include w/pi
        # A = [AB]
        #     [00]
        # AB denotes matrix concatenation.
        # Hence a reset: x' =  Ax + Bw + b
        # can be mimicked as below
        #
        # [x']   = [a00 a01 a02...b00 b01...] * [x] + b + [e0]
        # [w']     [     ...  0 ...         ]   [w]       [e1]
        #
        # This makes x' \in Ax + Bw + b + [el, eh], and
        # makes w' \in [el, eh]
        # We use this to incorporate error and reset w to new values,
        # which in the case of ZOH are just the ranges of w (or pi).

        q = self
        A = np.vstack((rm.A, np.zeros((q.wdim, q.xdim + q.wdim))))
        b = np.hstack((rm.b, np.zeros(q.wdim)))
        C, d = q.ival_constraints.poly()
        try:
            assert(A.shape[0] == b.shape[0])    # num lhs (states) is the same
            assert(A.shape[1] == C.shape[1])    # num vars (states + ip) are the same
            assert(C.shape[0] == d.shape[0])    # num constraints are the same
        except AssertionError as e:
            print('\n', A, '\n', b)
            print('\n', C, '\n', d)
            print(A.shape[0], b.shape[0], C.shape[1], d.shape[0])
            raise e
        return A, b

    def errorQ(self, *args):
        xic = self.qx.errorQ(*args)
        e = IntervalCons.concatenate(xic, Qxw.wic)
        return e

    def __hash__(self):
        return hash(self.xwcell)

    def __eq__(self, qxw):
        return self.xwcell == qxw.xwcell

    def __str__(self):
        return str(self.xwcell)

    def __repr__(self):
        return 'Qxw'+str(self.xwcell)
<commit_msg>added debug plots<commit_after>from __future__ import print_function

import itertools as it
import abc

import numpy as np

from constraints import IntervalCons
import cellmanager as CM
import err
from utils import print

if __debug__:
    import matplotlib.pyplot as plt

class Q(object):
    __metaclass__ = abc.ABCMeta

    @abc.abstractmethod
    def split(self, *args):
        return

#     @abc.abstractproperty
#     def dim(self):
#         return

#     @abc.abstractmethod
#     def getxy_ignoramous(self, N, sim, t0=0):
#         """TODO: EXPLICITLY ignores t, d, pvt, ci, pi
#         """
#         return

    @abc.abstractmethod
    def modelQ(self, rm):
        return

    @abc.abstractmethod
    def errorQ(self, include_err, X, Y, rm):
        return

    @abc.abstractmethod
    def __hash__(self):
        return hash((self.cell, tuple(self.eps)))

    @abc.abstractmethod
    def __eq__(self, c):
        return self.cell == c.cell and tuple(self.eps) == tuple(c.eps)

class Qxw(Q):
    # wic is the pi_cons of the overall system and has nothing to
    # do with wcell (of course wcell must be \in wic, but that is
    # all.
    wic = None

    @classmethod
    def init(cls, wic):
        cls.wic = wic

    def __init__(self, xcell, wcell):
        """__init__

        Parameters
        ----------
        abs_state : abstract states
        w_cells : cells associated with the abstract state defining
        range of inputs
        """
        if Qxw.wic is None:
            raise NameError('Class was not initialized. wic is None')

        assert(isinstance(xcell, CM.Cell))
        assert(isinstance(wcell, CM.Cell))

        self.xcell = xcell
        self.wcell = wcell
        self.xwcell = CM.Cell.concatenate(xcell, wcell)
        self.sample_UR_x = self.xcell.sample_UR
        self.sample_UR_w = self.wcell.sample_UR
        self.xdim = xcell.dim
        self.wdim = wcell.dim
        self.dim = xcell.dim + wcell.dim
        self.ival_constraints = self.xwcell.ival_constraints
        return

    def split(self, *args):
        qsplits = self.qx.splits(*args)
        return [Qxw(qsplits, self.wcell) for q in qsplits]

    def sim(self, step_sim, xw_array):
        """TODO: EXPLICITLY ignores t, d, pvt, ci, pi
        """
        d, pvt, s = [np.array([])]*3
        ci = [np.array([])]*2
        t0 = 0
        Yl = []
        x_array = xw_array[:, 0:self.xdim]
        w_array = xw_array[:, self.xdim:]

        for x, pi in zip(x_array, w_array):
            (t_, x_, s_, d_, pvt_, u_) = step_sim(t0, x, s, d, pvt, ci, pi)
            Yl.append(x_)

        # return yw_array
        return np.hstack((np.vstack(Yl), w_array))

    def get_rels(self, N, sim):
        """TODO: EXPLICITLY ignores t, d, pvt, ci, pi
        """
        d, pvt, s = [np.array([])]*3
        ci = np.array([])
        t0 = 0
        Yl = []

        x_array = self.sample_UR_x(N)
        pi_array = self.sample_UR_w(N)
        for x, pi in zip(x_array, pi_array):
            print(pi)
            (t_, x_, s_, d_, pvt_, u_) = sim(t0, x, s, d, pvt, ci, pi)
            Yl.append(x_)

        return np.hstack((x_array, pi_array)), np.vstack(Yl)

    def sat(self, XW):
        """returns a sat array, whose elements are false when unsat
        and true when sat"""
        return self.xcell.ival_constraints.sat(XW[:, 0:self.xdim])

    def modelQ(self, rm):

        #print('error%:', rm.max_error_pc(X, Y))
        # Matrices are extended to include w/pi
        # A = [AB]
        #     [00]
        # AB denotes matrix concatenation.
        # Hence a reset: x' =  Ax + Bw + b
        # can be mimicked as below
        #
        # [x']   = [a00 a01 a02...b00 b01...] * [x] + b + [e0]
        # [w']     [     ...  0 ...         ]   [w]       [e1]
        #
        # This makes x' \in Ax + Bw + b + [el, eh], and
        # makes w' \in [el, eh]
        # We use this to incorporate error and reset w to new values,
        # which in the case of ZOH are just the ranges of w (or pi).

        q = self
        A = np.vstack((rm.A, np.zeros((q.wdim, q.dim))))
        b = np.hstack((rm.b, np.zeros(q.wdim)))
        C, d = q.ival_constraints.poly()
        try:
            assert(A.shape[0] == b.shape[0])    # num lhs (states) is the same
            assert(A.shape[1] == C.shape[1])    # num vars (states + ip) are the same
            assert(C.shape[0] == d.shape[0])    # num constraints are the same
        except AssertionError as e:
            print('\n', A, '\n', b)
            print('\n', C, '\n', d)
            print(A.shape[0], b.shape[0], C.shape[1], d.shape[0])
            raise e
        return A, b

    def errorQ(self, include_err, X, Y, rm):
        q = self
        xic = (rm.error(X, Y) if include_err
               else IntervalCons([0.0]*q.xdim, [0.0]*q.xdim))

        e = IntervalCons.concatenate(xic, Qxw.wic)
        return e

    def __hash__(self):
        return hash(self.xwcell)

    def __eq__(self, qxw):
        return self.xwcell == qxw.xwcell

    def __str__(self):
        return str(self.xwcell)

    def __repr__(self):
        return 'Qxw'+str(self.xwcell)

class Qx(Q):
    def __init__(self, xcell):
        assert(isinstance(xcell, CM.Cell))

        self.xcell = xcell
        self.ival_constraints = xcell.ival_constraints
        self.xdim = xcell.dim
        self.dim = xcell.dim
        return

    def split(self, *args):
        return [Qx(c) for c in self.xcell.split(*args)]

    def sim(self, step_sim, x_array):
        """TODO: EXPLICITLY ignores t, d, pvt, ci, pi
        """
        d, pvt, s = [np.array([])]*3
        ci, pi = [np.array([])]*2
        t0 = 0
        Yl = []

        for x in x_array:
            (t_, x_, s_, d_, pvt_, u_) = step_sim(t0, x, s, d, pvt, ci, pi)
            Yl.append(x_)

        if __debug__:
            print('plotting grids Qx')
            #fig, ax = plt.subplots()
            ax = plt.gca()
#             ax.set_yticks([0.2, 0.6, 0.8], minor=False)
#             ax.set_yticks([0.3, 0.55, 0.7], minor=True)
#             ax.yaxis.grid(True, which='major')
#             ax.yaxis.grid(True, which='minor')

            # plot errors
            eps = 0.51
            for i in np.arange(0, 9, eps):
                ax.axhline(i, linestyle='-', color='k')
            for i in np.arange(0, -9, -eps):
                ax.axhline(i, linestyle='-', color='k')
            for i in np.arange(0, 3, eps):
                ax.axvline(i, linestyle='-', color='k')
            for i in np.arange(0, -3, -eps):
                ax.axvline(i, linestyle='-', color='k')

            # plot error states
            ax.axhline(-5.6, linestyle='-', color='r')
            ax.axhline(-6.5, linestyle='-', color='r')
            ax.axvline(-1, linestyle='-', color='r')
            ax.axvline(-0.7, linestyle='-', color='r')

        return np.vstack(Yl)

    def get_rels(self, N, sim):
        """TODO: EXPLICITLY ignores t, d, pvt, ci, pi
        """
        d, pvt, s = [np.array([])]*3
        ci, pi = [np.array([])]*2
        t0 = 0
        Yl = []

        #plt.figure()

        x_array = self.xcell.sample_UR(N)
        #print(t0)
        #print(x_array)
        for x in x_array:
            (t_, x_, s_, d_, pvt_, u_) = sim(t0, x, s, d, pvt, ci, pi)
            Yl.append(x_)
        if __debug__:
            #plt.title('ignore')
            #plt.show()
            plt.close()

        return x_array, np.vstack(Yl)

    def sat(self, X):
        """returns a sat array, whose elements are false when unsat
        and true when sat"""
        return self.ival_constraints.sat(X)

    def modelQ(self, rm):
        A, b = rm.A, rm.b
        return A, b

    def errorQ(self, include_err, X, Y, rm):
        e = (rm.error(X, Y) if include_err
             else IntervalCons([0.0]*self.xdim, [0.0]*self.xdim))
        return e

    def __hash__(self):
        return hash(self.xcell)

    def __eq__(self, q):
        return self.xcell == q.xcell

    def __str__(self):
        return str(self.xcell)

    def __repr__(self):
        return 'Qx'+str(self.xcell)

# Unused...should probably delete it if a usecase is not found.
class Qqxw(Q):
    # wic is the pi_cons of the overall system and has nothing to
    # do with wcell (of course wcell must be \in wic, but that is
    # all.
    wic = None

    @classmethod
    def init(cls, wic):
        cls.wic = wic

    def __init__(self, qx, wcell):
        """__init__

        Parameters
        ----------
        abs_state : abstract states
        w_cells : cells associated with the abstract state defining
        range of inputs
        """
        if Qxw.wic is None:
            raise NameError('Class was not initialized. wic is None')

        assert(isinstance(qx, Qx))
        assert(isinstance(wcell, CM.Cell))

        xcell = qx.xcell
        self.xcell = xcell
        self.wcell = wcell
        self.xwcell = CM.Cell.concatenate(xcell, wcell)
        self.sample_UR_x = self.xcell.sample_UR
        self.sample_UR_w = self.wcell.sample_UR
        self.xdim = xcell.dim
        self.wdim = wcell.dim
        self.ival_constraints = self.xwcell.ival_constraints
        return

    def split(self, *args):
        qsplits = self.qx.splits(*args)
        return [Qxw(qsplits, self.wcell) for q in qsplits]

    def get_rels(self, N, sim):
        """TODO: EXPLICITLY ignores t, d, pvt, ci, pi
        """
        d, pvt, s = [np.array([])]*3
        ci = np.array([])
        t0 = 0
        Yl = []

        x_array = self.sample_UR_x(N)
        pi_array = self.sample_UR_w(N)
        for x, pi in zip(x_array, pi_array):
            (t_, x_, s_, d_, pvt_, u_) = sim(t0, x, s, d, pvt, ci, pi)
            Yl.append(x_)

        return np.hstack((x_array, pi_array)), np.vstack(Yl)

    def sat(self, X):
        """returns a sat array, whose elements are false when unsat
        and true when sat"""
        return self.xcell.ival_constraints.sat(X)

    def modelQ(self, rm):

        #print('error%:', rm.max_error_pc(X, Y))
        # Matrices are extended to include w/pi
        # A = [AB]
        #     [00]
        # AB denotes matrix concatenation.
        # Hence a reset: x' =  Ax + Bw + b
        # can be mimicked as below
        #
        # [x']   = [a00 a01 a02...b00 b01...] * [x] + b + [e0]
        # [w']     [     ...  0 ...         ]   [w]       [e1]
        #
        # This makes x' \in Ax + Bw + b + [el, eh], and
        # makes w' \in [el, eh]
        # We use this to incorporate error and reset w to new values,
        # which in the case of ZOH are just the ranges of w (or pi).

        q = self
        A = np.vstack((rm.A, np.zeros((q.wdim, q.xdim + q.wdim))))
        b = np.hstack((rm.b, np.zeros(q.wdim)))
        C, d = q.ival_constraints.poly()
        try:
            assert(A.shape[0] == b.shape[0])    # num lhs (states) is the same
            assert(A.shape[1] == C.shape[1])    # num vars (states + ip) are the same
            assert(C.shape[0] == d.shape[0])    # num constraints are the same
        except AssertionError as e:
            print('\n', A, '\n', b)
            print('\n', C, '\n', d)
            print(A.shape[0], b.shape[0], C.shape[1], d.shape[0])
            raise e
        return A, b

    def errorQ(self, *args):
        xic = self.qx.errorQ(*args)
        e = IntervalCons.concatenate(xic, Qxw.wic)
        return e

    def __hash__(self):
        return hash(self.xwcell)

    def __eq__(self, qxw):
        return self.xwcell == qxw.xwcell

    def __str__(self):
        return str(self.xwcell)

    def __repr__(self):
        return 'Qxw'+str(self.xwcell)
<|endoftext|>


<commit_before>class PropertyChecker():

    def __init__(self, final_cons):
        self.final_cons = final_cons
        return

    def check_array(self, T, Y):
        """check_array

        Parameters
        ----------
        T : Time Vector of the trace
        Y : Array of state vectors of the trace
        """
        # XXX: any() seems to work although np.any will be the riight
        # function. Looks like any() just works on the array as an
        # iterator.
        return any(self.final_cons.contains(Y))
        #return np.any(self.final_cons.contains(Y))

    def check(self, t, y):
        """check

        Parameters
        ----------
        t : time value
        y : state vector
        """
        return y in self.final_cons

class PropertyCheckerNeverDetects():

    def __init__(self):
        return

    def check_array(self, T, Y):
        return False

    def check(self, t, y):
        return False
<commit_msg>added __str__<commit_after>class PropertyChecker():

    def __init__(self, final_cons):
        self.final_cons = final_cons
        return

    def check_array(self, T, Y):
        """check_array

        Parameters
        ----------
        T : Time Vector of the trace
        Y : Array of state vectors of the trace
        """
        # XXX: any() seems to work although np.any will be the riight
        # function. Looks like any() just works on the array as an
        # iterator.
        return any(self.final_cons.contains(Y))
        #return np.any(self.final_cons.contains(Y))

    def check(self, t, y):
        """check

        Parameters
        ----------
        t : time value
        y : state vector
        """
        return y in self.final_cons

    def __str__(self):
        return str(self.final_cons)

class PropertyCheckerNeverDetects():

    def __init__(self):
        return

    def check_array(self, T, Y):
        return False

    def check(self, t, y):
        return False
<|endoftext|>


<commit_before>import numpy as np

from deepchem.utils.typing import PymatgenStructure
from deepchem.feat import MaterialStructureFeaturizer
from deepchem.utils import pad_array

class SineCoulombMatrix(MaterialStructureFeaturizer):
  """
  Calculate sine Coulomb matrix for crystals.

  A variant of Coulomb matrix for periodic crystals.

  The sine Coulomb matrix is identical to the Coulomb matrix, except
  that the inverse distance function is replaced by the inverse of
  sin**2 of the vector between sites which are periodic in the
  dimensions of the crystal lattice.

  Features are flattened into a vector of matrix eigenvalues by default
  for ML-readiness. To ensure that all feature vectors are equal
  length, the maximum number of atoms (eigenvalues) in the input
  dataset must be specified.

  This featurizer requires the optional dependencies pymatgen and
  matminer. It may be useful when crystal structures with 3D coordinates
  are available.

  See [1]_ for more details.

  References
  ----------
  .. [1] Faber et al. Inter. J. Quantum Chem. 115, 16, 2015.

  Examples
  --------
  >>> import pymatgen as mg
  >>> lattice = mg.Lattice.cubic(4.2)
  >>> structure = mg.Structure(lattice, ["Cs", "Cl"], [[0, 0, 0], [0.5, 0.5, 0.5]])
  >>> featurizer = SineCoulombMatrix(max_atom=2)
  >>> features = featurizer.featurize([structure])

  Note
  ----
  This class requires matminer and Pymatgen to be installed.
  """

  def __init__(self, max_atoms: int, flatten: bool = True):
    """
    Parameters
    ----------
    max_atoms: int
      Maximum number of atoms for any crystal in the dataset. Used to
      pad the Coulomb matrix.
    flatten: bool (default True)
      Return flattened vector of matrix eigenvalues.
    """

    self.max_atoms = max_atoms
    self.flatten = flatten

  def _featurize(self, struct: PymatgenStructure) -> np.ndarray:
    """
    Calculate sine Coulomb matrix from pymatgen structure.

    Parameters
    ----------
    struct: pymatgen.Structure
      A periodic crystal composed of a lattice and a sequence of atomic
      sites with 3D coordinates and elements.

    Returns
    -------
    features: np.ndarray
      2D sine Coulomb matrix with shape (max_atoms, max_atoms),
      or 1D matrix eigenvalues with shape (max_atoms,).
    """

    try:
      from matminer.featurizers.structure import SineCoulombMatrix as SCM
    except ModuleNotFoundError:
      raise ValueError("This class requires matminer to be installed.")

    # Get full N x N SCM
    scm = SCM(flatten=False)
    sine_mat = scm.featurize(struct)

    if self.flatten:
      eigs, _ = np.linalg.eig(sine_mat)
      zeros = np.zeros((1, self.max_atoms))
      zeros[:len(eigs)] = eigs
      features = zeros
    else:
      features = pad_array(sine_mat, self.max_atoms)

    features = np.asarray(features)

    return features
<commit_msg>:rotating_light: fix lint<commit_after>import numpy as np

from deepchem.utils.typing import PymatgenStructure
from deepchem.feat import MaterialStructureFeaturizer
from deepchem.utils import pad_array

class SineCoulombMatrix(MaterialStructureFeaturizer):
  """
  Calculate sine Coulomb matrix for crystals.

  A variant of Coulomb matrix for periodic crystals.

  The sine Coulomb matrix is identical to the Coulomb matrix, except
  that the inverse distance function is replaced by the inverse of
  sin**2 of the vector between sites which are periodic in the
  dimensions of the crystal lattice.

  Features are flattened into a vector of matrix eigenvalues by default
  for ML-readiness. To ensure that all feature vectors are equal
  length, the maximum number of atoms (eigenvalues) in the input
  dataset must be specified.

  This featurizer requires the optional dependencies pymatgen and
  matminer. It may be useful when crystal structures with 3D coordinates
  are available.

  See [1]_ for more details.

  References
  ----------
  .. [1] Faber et al. Inter. J. Quantum Chem. 115, 16, 2015.

  Examples
  --------
  >>> import pymatgen as mg
  >>> lattice = mg.Lattice.cubic(4.2)
  >>> structure = mg.Structure(lattice, ["Cs", "Cl"], [[0, 0, 0], [0.5, 0.5, 0.5]])
  >>> featurizer = SineCoulombMatrix(max_atoms=2)
  >>> features = featurizer.featurize([structure])

  Note
  ----
  This class requires matminer and Pymatgen to be installed.
  """

  def __init__(self, max_atoms: int, flatten: bool = True):
    """
    Parameters
    ----------
    max_atoms: int
      Maximum number of atoms for any crystal in the dataset. Used to
      pad the Coulomb matrix.
    flatten: bool (default True)
      Return flattened vector of matrix eigenvalues.
    """

    self.max_atoms = max_atoms
    self.flatten = flatten

  def _featurize(self, struct: PymatgenStructure) -> np.ndarray:
    """
    Calculate sine Coulomb matrix from pymatgen structure.

    Parameters
    ----------
    struct: pymatgen.Structure
      A periodic crystal composed of a lattice and a sequence of atomic
      sites with 3D coordinates and elements.

    Returns
    -------
    features: np.ndarray
      2D sine Coulomb matrix with shape (max_atoms, max_atoms),
      or 1D matrix eigenvalues with shape (max_atoms,).
    """

    try:
      from matminer.featurizers.structure import SineCoulombMatrix as SCM
    except ModuleNotFoundError:
      raise ValueError("This class requires matminer to be installed.")

    # Get full N x N SCM
    scm = SCM(flatten=False)
    sine_mat = scm.featurize(struct)

    if self.flatten:
      eigs, _ = np.linalg.eig(sine_mat)
      zeros = np.zeros((1, self.max_atoms))
      zeros[:len(eigs)] = eigs
      features = zeros
    else:
      features = pad_array(sine_mat, self.max_atoms)

    features = np.asarray(features)

    return features
<|endoftext|>


<commit_before># -*- mode: python; coding: utf-8; -*-
#http://www.martin-geber.com/thought/2007/10/27/markdown-syntax-highlighting-django/
from django import template
from django.conf import settings
from django.template.defaultfilters import stringfilter

import urllib
import re
import markdown

register = template.Library()

try:
    ESV_API_URL = settings.ESV_API_URL
except AttributeError:
    ESV_API_URL = 'http://www.esvapi.org/v2/rest/passageQuery?'

ESV_DICT = {}
ESV_DICT['output-format'] = 'html'
ESV_DICT['include-footnotes'] = 0
ESV_DICT['include-passage-references'] = 1
ESV_DICT['include-first-verse-numbers'] = 0
ESV_DICT['include-passage-horizontal-lines'] = 0
ESV_DICT['include-heading-horizontal-lines'] = 0
ESV_DICT['include-headings'] = 0
ESV_DICT['key'] = 'IP'

BIBLE_RE = re.compile(r'\[\[bible ([^\]]+)\]\]', re.I)

ESV_QUERY_METHOD = 'passage'
ESV_QUERY_URL = ''

@register.filter(name='esv')
@stringfilter
def esv(value, args=''):
    """
    Use ESV API to get a Bible Passage
    http://www.esvapi.org/v2/rest/passageQuery?key=IP&passage=Gen+1:5-10&output-format=plain-text

    Looking for [[bible PASSAGE]]

    Usage::

        {{ text|esv}}
        {{ text|esv:"option1:value,option2:value"}}
    """
    if BIBLE_RE.search(value) is None:
        return value
    esv_dict = ESV_DICT.copy()
    esv_args = args.split(',')
    if len(esv_args) > 0:
        for arg in esv_args:
            try:
                key, val = arg.split(':')
                if esv_dict.has_key(key):
                    esv_dict[key] = val
            except ValueError:
                pass
    global ESV_QUERY_URL
    ESV_QUERY_URL = ESV_API_URL+'&'.join([k+'='+urllib.quote(str(v)) for (k,v) in esv_dict.items()])
    return BIBLE_RE.sub(_get_esv_txt, value)
esv.is_safe = True

def _get_esv_txt(matchObj):
    passage = matchObj.group(1)
    try:
        return markdown.markdown(
            urllib.urlopen(ESV_QUERY_URL+'&'+ESV_QUERY_METHOD+'='+urllib.quote(passage)).read()
        )
    except IOError:
        return passage

@register.filter(name='markdown')
@stringfilter
def markdowner(value, arg=''):
    """
    Filter to create HTML out of Markdown, using custom extensions.

    The diffrence between this filter and the django-internal markdown
    filter (located in ``django/contrib/markup/templatetags/markup.py``)
    is that this filter enables extensions to be load.

    Usage::

        {{ object.text|markdown }}
        {{ object.text|markdown:"save" }}
        {{ object.text|markdown:"codehilite" }}
        {{ object.text|markdown:"save,codehilite" }}

    This code is taken from
    http://www.freewisdom.org/projects/python-markdown/Django
    """
    extensions=arg.split(",")
    if len(extensions) > 0 and extensions[0] == "safe" :
        extensions = extensions[1:]
        safe_mode = True
    else :
        safe_mode = False
    return markdown.markdown(value, extensions, safe_mode=safe_mode)
<commit_msg>using getattrs for default settings in esv filter<commit_after># -*- mode: python; coding: utf-8; -*-
#http://www.martin-geber.com/thought/2007/10/27/markdown-syntax-highlighting-django/
from django import template
from django.conf import settings
from django.template.defaultfilters import stringfilter

import urllib
import re
import markdown

register = template.Library()

ESV_API_URL = getattr(settings, 'ESV_API_URL', 'http://www.esvapi.org/v2/rest/passageQuery?')

ESV_DICT = {}
ESV_DICT['output-format'] = 'html'
ESV_DICT['include-footnotes'] = 0
ESV_DICT['include-passage-references'] = 1
ESV_DICT['include-first-verse-numbers'] = 0
ESV_DICT['include-passage-horizontal-lines'] = 0
ESV_DICT['include-heading-horizontal-lines'] = 0
ESV_DICT['include-headings'] = 0
ESV_DICT['key'] = 'IP'

BIBLE_RE = re.compile(r'\[\[bible ([^\]]+)\]\]', re.I)

ESV_QUERY_METHOD = 'passage'
ESV_QUERY_URL = ''

@register.filter(name='esv')
@stringfilter
def esv(value, args=''):
    """
    Use ESV API to get a Bible Passage
    http://www.esvapi.org/v2/rest/passageQuery?key=IP&passage=Gen+1:5-10&output-format=plain-text

    Looking for [[bible PASSAGE]]

    Usage::

        {{ text|esv}}
        {{ text|esv:"option1:value,option2:value"}}
    """
    if BIBLE_RE.search(value) is None:
        return value
    esv_dict = ESV_DICT.copy()
    esv_args = args.split(',')
    if len(esv_args) > 0:
        for arg in esv_args:
            try:
                key, val = arg.split(':')
                if esv_dict.has_key(key):
                    esv_dict[key] = val
            except ValueError:
                pass
    global ESV_QUERY_URL
    ESV_QUERY_URL = ESV_API_URL+'&'.join([k+'='+urllib.quote(str(v)) for (k,v) in esv_dict.items()])
    return BIBLE_RE.sub(_get_esv_txt, value)
esv.is_safe = True

def _get_esv_txt(matchObj):
    passage = matchObj.group(1)
    try:
        return markdown.markdown(
            urllib.urlopen(ESV_QUERY_URL+'&'+ESV_QUERY_METHOD+'='+urllib.quote(passage)).read()
        )
    except IOError:
        return passage

@register.filter(name='markdown')
@stringfilter
def markdowner(value, arg=''):
    """
    Filter to create HTML out of Markdown, using custom extensions.

    The diffrence between this filter and the django-internal markdown
    filter (located in ``django/contrib/markup/templatetags/markup.py``)
    is that this filter enables extensions to be load.

    Usage::

        {{ object.text|markdown }}
        {{ object.text|markdown:"save" }}
        {{ object.text|markdown:"codehilite" }}
        {{ object.text|markdown:"save,codehilite" }}

    This code is taken from
    http://www.freewisdom.org/projects/python-markdown/Django
    """
    extensions=arg.split(",")
    if len(extensions) > 0 and extensions[0] == "safe" :
        extensions = extensions[1:]
        safe_mode = True
    else :
        safe_mode = False
    return markdown.markdown(value, extensions, safe_mode=safe_mode)
<|endoftext|>


<commit_before># coding=utf8
from mytypes import types
from stitchpoles import stitch
from hashtable import hashtable
from coordinatesystems import systems
from bounds import bound

e = 1e-6
def isInfinit(n):
	return abs(n)==float('inf')

def topology (objects, options=False):
	Q = 1e4; # precision of quantization
	id = lambda d:d['id']
	def propertyTransform ():
		pass
	stitchPoles = True;
	verbose = False;
	emax = 0
	system = False
	arcs = []
	if type(options)==type({}):
		if options.has_key('verbose'):
			verbose = not not options['verbose']
		if options.has_key('stitch-poles'):
			stitchPoles = not not options["stitch-poles"]
		if options.has_key('coordinate-system'):
			system = systems[options["coordinate-system"]]
		if options.has_key('quantization'):
			Q = float(options["quantization"])
		if options.has_key('id'):
			id = options['id']
		if options.has_key('property-transform'):
			propertyTransform = options["property-transform"]

	coincidences = hashtable(Q * 10);
	arcsByPoint = hashtable(Q * 10);
	pointsByPoint = hashtable(Q * 10);

	def each(r):
		t=r()
		out = t.obj(objects)
		return out

	[x0,x1,y0,y1]=bound(objects)

	oversize = x0 < -180 - e or x1 > 180 + e or y0 < -90 - e or y1 > 90 + e
	if not system:
		if oversize:
			system = systems["cartesian"]
		else:
			system = systems["spherical"]
		if type(options)==type({}):
			options["coordinate-system"] = system['name']
	if system == systems['spherical']:
		if oversize:
			raise Exception(u"spherical coordinates outside of [±180°, ±90°]")
		if stitchPoles:
			stitch(objects)
			[x0,x1,y0,y1]=bound(objects)
		if x0 < -180 + e:
			x0 = -180
		if x1 > 180 - e:
			x1 = 180
		if y0 < -90 + e:
			y0 = -90
		if y1 > 90 - e:
			y1 = 90;
	if isInfinit(x0):
		x0 = 0
	if isInfinit(x1):
		x1 = 0;

	if isInfinit(y0):
		y0 = 0;
	if isInfinit(y1):
		y1 = 0;
	[kx,ky]=makeKs(Q,x0,x1,y0,y1)
	if not Q:
		Q = x1 + 1
		x0 = y0 = 0
	class newPointFunc(types):
		def __init__(self):
			self.emax=0
		def point(self,point):
			x1 = point[0]
			y1 = point[1]
			x = round((x1 - x0) * kx)
			y = round((y1 - y0) * ky)
			ee = system['distance'](x1, y1, x / kx + x0, y / ky + y0)
			if ee > self.emax:
				self.emax = ee
			point[0] = x
			point[1] = y
	finde=newPointFunc()
	finde.obj(objects)
	emax = finde.emax
	class newLineFunc(types):
		def line(self,line):
			for point in line:
				lines = coincidences.get(point)
				if not line in lines:
					lines.append(line)
	each(newLineFunc)
	def line(points, open):
		lineArcs = [];
		n = len(points)
		a = []
		k = -1
		p=False
		if not open:
			points.pop()
			n-=1
		while k<n:
			k+=1
			t = coincidences.peak(points[k])
			if open:
				break
			if p and not linesEqual(p, t):
				tInP = all(map(lambda line: line in p,t))
				pInT = all(map(lambda line: line in t,p))
				if tInP and not pInT:
					k-=1
				break;
			p = t;
		# If no shared starting point is found for closed lines, rotate to minimum.
		if k == n and len(p) > 1:
			point0 = points[0]
			i = -1
			k=0
			while i<n:
				i+=1
				point = points[i];
				if pointCompare(point0, point) > 0:
					point0 = point
					k = i
		i = -1
		m = n if open else n + 1
		while i < m:
			i+=1
			point = points[(i + k) % n]
			p = coincidences.peak(point)
			if  not linesEqual(p, t):
				tInP = all(map(lambda line: line in p,t))
				pInT = all(map(lambda line: line in t,p))
				if tInP:
					a.append(point);
				arc(a)
				if not tInP and not pInT:
					arc([a[-1], point])
				if pInT:
					a = [a[-1]]
				else:
					a = [];
			if not len(a) or pointCompare(a[-1], point):
				a.append(point) # skip duplicate points
			t = p
		arc(a, True)
		def arc(a, last):
			n = len(a)
			point=False
			if last and not len(lineArcs) and n == 1:
				point = a[0]
				index = pointsByPoint.get(point)
				if len(index):
					lineArcs.append(index[0])
				else:
					index[0] = len(arcs)
					lineArcs.append(index[0])
					arcs.append(a)
			elif n > 1:
				a0 = a[0]
				a1 = a[-1]
				point = a0 if pointCompare(a0, a1) < 0 else a1
				pointArcs = arcsByPoint.get(point)
				if any(map(matchForward,pointArcs)) or any(map(matchBackward,pointArcs)):
					return
				pointArcs.append(a)
				a['index']=len(arcs)
				lineArcs.append(a['index'])
				arcs.append(a)
		def matchForward(b):
			i = 0;
			if len(b) != n:
				return False
			while i < n:
				if pointCompare(a[i], b[i]):
					return False;
				i+=1
			lineArcs.append(b['index'])
			return True;

		def matchBackward(b):
			i = 0
			if len(b) != n:
				return False
			while i<n:
				if pointCompare(a[i], b[n - i - 1]):
					return False
				i+=1
			lineArcs.append(~b['index'])
			return True
		return lineArcs
	polygon = lambda poly:map(lineClosed,poly)
	lineClosed = lambda points:line(points,False)
	lineOpen = lambda points:line(points,True)
	#Convert features to geometries, and stitch together arcs.
	class bigEach(types):
		def Feature (self,feature):
			geometry = feature["geometry"]
			if feature['geometry'] == None:
				geometry = {};
			if feature.has_key('id'):
				geometry['id'] = feature['id']
			if feature.has_key('properties'):
				geometry['properties'] = feature['properties']
			return self.geometry(geometry);
		def FeatureCollection(self,collection):
			collection['type'] = "GeometryCollection";
			collection['geometries'] = map(self.Feature,collection['features'])
			del collection.features
			return collection
		def GeometryCollection(self,collection):
			collection['geometries'] = map(self.geometry,collection['geometries'])
		def MultiPolygon(self,multiPolygon):
			multiPolygon['arcs'] = map(polygon,multiPolygon['coordinates'])
		def Polygon(self,polygon):
			 polygon['arcs'] = map(lineClosed,polygon['coordinates'])
		def MultiLineString(self,multiLineString):
			multiLineString['arcs'] = map(lineOpen,multiLineString['coordinates'])
		def LineString(self,lineString):
			lineString['arcs'] = lineOpen(lineString['coordinates'])
		def geometry(self,geometry):
			if geometry == None:
				geometry = {};
			else:
				types.geometry(self,geometry)
			geometry['id'] = id(geometry)
			if geometry['id'] == None:
				del geometry['id']
			properties0 = geometry.properties
			if properties0:
				properties1 = {}
				del geometry['properties']
				for key0 in properties0:
					if propertyTransform(properties1, key0, properties0[key0]):
						geometry['properties'] = properties1
			if geometry.has_key('arcs'):
				del geometry['coordinates']
			return geometry;
	objects = each(bigEach)

	coincidences = arcsByPoint = pointsByPoint = None

	return {
		'type': "Topology",
		'bbox': [x0, y0, x1, y1],
		'transform': {
			'scale': [1.0 / kx, 1.0 / ky],
			'translate': [x0, y0]
		},
		'obj': objects,
		'arcs': makeArcs(arcs)
	}

makeArcs = lambda arcs:map(mapFunc,arcs)

def mapFunc (arc):
	i = 1;
	n = len(arc)
	point = arc[0]
	x1 = point[0]
	x2= dx =y2 = dy=False
	y1 = point[1]
	points = [[x1, y1]]
	while i < n:
		point = arc[i]
		x2 = point[0]
		y2 = point[1]
		dx = x2 - x1
		dy = y2 - y1
		if dx or dy:
			points.append([dx, dy])
			x1 = x2
			y1 = y2
		i+=1
	return points

def makeKs(Q,x0,x1,y0,y1):
	if Q:
		return [(Q - 1) / (x1 - x0) if x1 - x0 else 1,(Q - 1) / (y1 - y0) if y1 - y0 else 1]
	else:
		return [1,1]
def linesEqual(a, b):
	n = len(a);
	i = 0
	if len(b) != n:
		return False
	while i < n:
		if a[i] != b[i]:
			return False;
		i+=1
	return True;

def pointCompare(a, b):
	return a[0] - b[0] or a[1] - b[1]
<commit_msg>still not done<commit_after># coding=utf8
from mytypes import types
from stitchpoles import stitch
from hashtable import hashtable
from coordinatesystems import systems
from bounds import bound

e = 1e-6
def isInfinit(n):
	return abs(n)==float('inf')

def topology (objects, options=False):
	Q = 1e4; # precision of quantization
	id = lambda d:d['id']
	def propertyTransform ():
		pass
	stitchPoles = True;
	verbose = False;
	emax = 0
	system = False
	arcs = []
	if type(options)==type({}):
		if options.has_key('verbose'):
			verbose = not not options['verbose']
		if options.has_key('stitch-poles'):
			stitchPoles = not not options["stitch-poles"]
		if options.has_key('coordinate-system'):
			system = systems[options["coordinate-system"]]
		if options.has_key('quantization'):
			Q = float(options["quantization"])
		if options.has_key('id'):
			id = options['id']
		if options.has_key('property-transform'):
			propertyTransform = options["property-transform"]

	coincidences = hashtable(Q * 10);
	arcsByPoint = hashtable(Q * 10);
	pointsByPoint = hashtable(Q * 10);

	def each(r):
		t=r()
		out = t.obj(objects)
		return out

	[x0,x1,y0,y1]=bound(objects)

	oversize = x0 < -180 - e or x1 > 180 + e or y0 < -90 - e or y1 > 90 + e
	if not system:
		if oversize:
			system = systems["cartesian"]
		else:
			system = systems["spherical"]
		if type(options)==type({}):
			options["coordinate-system"] = system['name']
	if system == systems['spherical']:
		if oversize:
			raise Exception(u"spherical coordinates outside of [±180°, ±90°]")
		if stitchPoles:
			stitch(objects)
			[x0,x1,y0,y1]=bound(objects)
		if x0 < -180 + e:
			x0 = -180
		if x1 > 180 - e:
			x1 = 180
		if y0 < -90 + e:
			y0 = -90
		if y1 > 90 - e:
			y1 = 90;
	if isInfinit(x0):
		x0 = 0
	if isInfinit(x1):
		x1 = 0;

	if isInfinit(y0):
		y0 = 0;
	if isInfinit(y1):
		y1 = 0;
	[kx,ky]=makeKs(Q,x0,x1,y0,y1)
	if not Q:
		Q = x1 + 1
		x0 = y0 = 0
	class newPointFunc(types):
		def __init__(self):
			self.emax=0
		def point(self,point):
			x1 = point[0]
			y1 = point[1]
			x = round((x1 - x0) * kx)
			y = round((y1 - y0) * ky)
			ee = system['distance'](x1, y1, x / kx + x0, y / ky + y0)
			if ee > self.emax:
				self.emax = ee
			point[0] = x
			point[1] = y
	finde=newPointFunc()
	finde.obj(objects)
	emax = finde.emax
	class newLineFunc(types):
		def line(self,line):
			for point in line:
				lines = coincidences.get(point)
				if not line in lines:
					lines.append(line)
	each(newLineFunc)
	def line(points, open):
		lineArcs = [];
		n = len(points)
		a = []
		k = -1
		p=False
		if not open:
			points.pop()
			n-=1
		while k<n:
			k+=1
			t = coincidences.peak(points[k])
			if open:
				break
			if p and not linesEqual(p, t):
				tInP = all(map(lambda line: line in p,t))
				pInT = all(map(lambda line: line in t,p))
				if tInP and not pInT:
					k-=1
				break;
			p = t;
		# If no shared starting point is found for closed lines, rotate to minimum.
		if k == n and len(p) > 1:
			point0 = points[0]
			i = -1
			k=0
			while i<n:
				i+=1
				point = points[i];
				if pointCompare(point0, point) > 0:
					point0 = point
					k = i
		i = -1
		m = n if open else n + 1
		def matchForward(b):
			i = 0;
			if len(b) != n:
				return False
			while i < n:
				if pointCompare(a[i], b[i]):
					return False;
				i+=1
			lineArcs.append(b['index'])
			return True;

		def matchBackward(b):
			i = 0
			if len(b) != n:
				return False
			while i<n:
				if pointCompare(a[i], b[n - i - 1]):
					return False
				i+=1
			lineArcs.append(~b['index'])
			return True
		def arc(a, last=False):
			n = len(a)
			point=False
			if last and not len(lineArcs) and n == 1:
				point = a[0]
				index = pointsByPoint.get(point)
				if len(index):
					lineArcs.append(index[0])
				else:
					index[0] = len(arcs)
					lineArcs.append(index[0])
					arcs.append(a)
			elif n > 1:
				a0 = a[0]
				a1 = a[-1]
				point = a0 if pointCompare(a0, a1) < 0 else a1
				pointArcs = arcsByPoint.get(point)
				if any(map(matchForward,pointArcs)) or any(map(matchBackward,pointArcs)):
					return
				pointArcs.append(a)
				a['index']=len(arcs)
				lineArcs.append(a['index'])
				arcs.append(a)
		while i < m:
			i+=1
			point = points[(i + k) % n]
			p = coincidences.peak(point)
			if  not linesEqual(p, t):
				tInP = all(map(lambda line: line in p,t))
				pInT = all(map(lambda line: line in t,p))
				if tInP:
					a.append(point);
				arc(a)
				if not tInP and not pInT:
					arc([a[-1], point])
				if pInT:
					a = [a[-1]]
				else:
					a = [];
			if not len(a) or pointCompare(a[-1], point):
				a.append(point) # skip duplicate points
			t = p
		arc(a, True)

		return lineArcs
	polygon = lambda poly:map(lineClosed,poly)
	lineClosed = lambda points:line(points,False)
	lineOpen = lambda points:line(points,True)
	#Convert features to geometries, and stitch together arcs.
	class bigEach(types):
		def Feature (self,feature):
			geometry = feature["geometry"]
			if feature['geometry'] == None:
				geometry = {};
			if feature.has_key('id'):
				geometry['id'] = feature['id']
			if feature.has_key('properties'):
				geometry['properties'] = feature['properties']
			return self.geometry(geometry);
		def FeatureCollection(self,collection):
			collection['type'] = "GeometryCollection";
			collection['geometries'] = map(self.Feature,collection['features'])
			del collection.features
			return collection
		def GeometryCollection(self,collection):
			collection['geometries'] = map(self.geometry,collection['geometries'])
		def MultiPolygon(self,multiPolygon):
			multiPolygon['arcs'] = map(polygon,multiPolygon['coordinates'])
		def Polygon(self,polygon):
			 polygon['arcs'] = map(lineClosed,polygon['coordinates'])
		def MultiLineString(self,multiLineString):
			multiLineString['arcs'] = map(lineOpen,multiLineString['coordinates'])
		def LineString(self,lineString):
			lineString['arcs'] = lineOpen(lineString['coordinates'])
		def geometry(self,geometry):
			if geometry == None:
				geometry = {};
			else:
				types.geometry(self,geometry)
			geometry['id'] = id(geometry)
			if geometry['id'] == None:
				del geometry['id']
			properties0 = geometry.properties
			if properties0:
				properties1 = {}
				del geometry['properties']
				for key0 in properties0:
					if propertyTransform(properties1, key0, properties0[key0]):
						geometry['properties'] = properties1
			if geometry.has_key('arcs'):
				del geometry['coordinates']
			return geometry;
	objects = each(bigEach)

	coincidences = arcsByPoint = pointsByPoint = None

	return {
		'type': "Topology",
		'bbox': [x0, y0, x1, y1],
		'transform': {
			'scale': [1.0 / kx, 1.0 / ky],
			'translate': [x0, y0]
		},
		'obj': objects,
		'arcs': makeArcs(arcs)
	}

makeArcs = lambda arcs:map(mapFunc,arcs)

def mapFunc (arc):
	i = 1;
	n = len(arc)
	point = arc[0]
	x1 = point[0]
	x2= dx =y2 = dy=False
	y1 = point[1]
	points = [[x1, y1]]
	while i < n:
		point = arc[i]
		x2 = point[0]
		y2 = point[1]
		dx = x2 - x1
		dy = y2 - y1
		if dx or dy:
			points.append([dx, dy])
			x1 = x2
			y1 = y2
		i+=1
	return points

def makeKs(Q,x0,x1,y0,y1):
	if Q:
		return [(Q - 1) / (x1 - x0) if x1 - x0 else 1,(Q - 1) / (y1 - y0) if y1 - y0 else 1]
	else:
		return [1,1]
def linesEqual(a, b):
	n = len(a);
	i = 0
	if len(b) != n:
		return False
	while i < n:
		if a[i] != b[i]:
			return False;
		i+=1
	return True;

def pointCompare(a, b):
	return a[0] - b[0] or a[1] - b[1]
<|endoftext|>