<commit_before>#!/usr/bin/python

#============================ adjust path =====================================

import sys
import os
if __name__ == "__main__":
    here = sys.path[0]
    sys.path.insert(0, os.path.join(here, 'smartmeshsdk-master'))
    sys.path.insert(0, os.path.join(here, '..', 'Sol'))

#============================ imports =========================================

import time
import threading
import json
from   optparse                             import OptionParser

import OpenCli
import basestation_version

# DustThread
from   SmartMeshSDK                         import FormatUtils, \
                                                   HrParser,    \
                                                   sdk_version
from   SmartMeshSDK.IpMgrConnectorSerial    import IpMgrConnectorSerial
from   SmartMeshSDK.IpMgrConnectorMux       import IpMgrSubscribe

# JsonThread
import bottle
import Sol
import SolVersion
import SolDefines

#============================ defines =========================================

DEFAULT_SERIALPORT = 'COM14'
DEFAULT_TCPPORT    = 8080

#============================ helpers =========================================

def printException(err):
    output  = []
    output += ["ERROR:"]
    output += [str(err)]
    output  = '\n'.join(output)
    print output

#============================ classes =========================================

class DustThread(threading.Thread):

    def __init__(self, serialport):

        # store params
        self.serialport      = serialport

        # local variables
        self.reconnectEvent  = threading.Event()
        self.hrParser        = HrParser.HrParser()
        self.sol             = Sol.Sol()
        self.dataLock        = threading.RLock()
        self.goOn            = True

        # start the thread
        threading.Thread.__init__(self)
        self.name            = 'DustThread'
        self.start()

    def run(self):

        # wait for banner to print
        time.sleep(0.5)

        while self.goOn:

            try:
                print 'Connecting to {0}...'.format(self.serialport),

                # connect to the manager
                self.connector          = IpMgrConnectorSerial.IpMgrConnectorSerial()
                self.connector.connect({
                    'port': self.serialport,
                })

                # get MAC address of manager
                temp = self.dn_getSystemInfo()
                self.managerMac = temp.macAddress

                # sync network-UTC time
                temp  = self.dn_getTime()
                netTs = self._calcNetTs(temp)
                self._syncNetTsToUtc(netTs)

                # subscribe to notifications
                self.subscriber = IpMgrSubscribe.IpMgrSubscribe(self.connector)
                self.subscriber.start()
                self.subscriber.subscribe(
                    notifTypes =    [
                                        IpMgrSubscribe.IpMgrSubscribe.NOTIFDATA,
                                    ],
                    fun =           self._notifData,
                    isRlbl =        False,
                )
                self.subscriber.subscribe(
                    notifTypes =    [
                                        IpMgrSubscribe.IpMgrSubscribe.NOTIFEVENT,
                                    ],
                    fun =           self._notifEvent,
                    isRlbl =        True,
                )
                self.subscriber.subscribe(
                    notifTypes =    [
                                        IpMgrSubscribe.IpMgrSubscribe.NOTIFHEALTHREPORT,
                                    ],
                    fun =           self._notifHealthReport,
                    isRlbl =        True,
                )
                self.subscriber.subscribe(
                    notifTypes =    [
                                        IpMgrSubscribe.IpMgrSubscribe.NOTIFIPDATA,
                                    ],
                    fun =           self._notifIPData,
                    isRlbl =        False,
                )
                self.subscriber.subscribe(
                    notifTypes =    [
                                        IpMgrSubscribe.IpMgrSubscribe.NOTIFLOG,
                                    ],
                    fun =           self._notifLog,
                    isRlbl =        True,
                )
                self.subscriber.subscribe(
                    notifTypes =    [
                                        IpMgrSubscribe.IpMgrSubscribe.ERROR,
                                        IpMgrSubscribe.IpMgrSubscribe.FINISH,
                                    ],
                    fun =           self._notifErrorFinish,
                    isRlbl =        True,
                )

                print "TODO: periodically sync NetTs to UTC"

            except Exception as err:
                print 'FAIL.'

                try:
                   self.connector.disconnect()
                except:
                   pass

                # wait to reconnect
                time.sleep(1)

            else:
                print 'PASS.'
                self.reconnectEvent.clear()
                self.reconnectEvent.wait()

                try:
                   self.connector.disconnect()
                except:
                   pass

    #======================== public ==========================================

    def close(self):

        try:
            self.connector.disconnect()
        except:
            pass

        self.goOn = False

    #======================== private =========================================

    #=== Dust API notifications

    def _notifData(self, notifName, notifParams):

        try:
            assert notifName==IpMgrSubscribe.IpMgrSubscribe.NOTIFDATA

            # extract the important data
            netTs      = self._calcNetTs(notifParams)
            macAddress = notifParams.macAddress
            srcPort    = notifParams.srcPort
            dstPort    = notifParams.dstPort
            data       = notifParams.data

            isSol = False

            if dstPort==SolDefines.SOL_PORT:
                # try to decode as objects
                try:
                    raise NotImplementedError()
                except:
                    pass
                else:
                    isSol = True

            if not isSol:

                # create sensor object (NOTIF_DATA_RAW)
                sobject = {
                    'mac':       macAddress,
                    'timestamp': self._netTsToEpoch(netTs),
                    'type':      SolDefines.SOL_TYPE_NOTIF_DATA_RAW,
                    'value':     self.sol.create_value_NOTIF_DATA_RAW(
                        srcPort = srcPort,
                        dstPort = dstPort,
                        payload = data,
                    ),
                }

            # publish sensor object
            self._publishObject(sobject)

        except Exception as err:
            printException(err)

    def _notifEvent(self,notifName,notifParams):

        try:
            assert notifName==IpMgrSubscribe.IpMgrSubscribe.NOTIFEVENT

            # extract the important data
            eventId    = notifParams.eventId
            eventType  = notifParams.eventType
            data       = notifParams.eventData

            # create sensor object (SOL_TYPE_NOTIF_EVENT)
            sobject = {
                'mac':       self.managerMac,
                'timestamp': time.gmtime(),
                'type':      SolDefines.SOL_TYPE_NOTIF_EVENT,
                'value':     self.sol.create_value_NOTIF_EVENT(
                    eventID       = eventId,
                    eventType     = eventType,
                    payload       = data,
                ),
            }

            # publish sensor object
            self._publishObject(sobject)

        except Exception as err:
            printException(err)

    def _notifHealthReport(self,notifName,notifParams):

        try:
            assert notifName==IpMgrSubscribe.IpMgrSubscribe.NOTIFHEALTHREPORT

            # extract the important data
            netTs      = self._calcNetTs(notifParams)
            macAddress = notifParams.macAddress
            data       = notifParams.data

            # create sensor object (SOL_TYPE_NOTIF_HEALTHREPORT)
            sobject = {
                'mac':       macAddress,
                'timestamp': self._netTsToEpoch(netTs),
                'type':      SolDefines.SOL_TYPE_NOTIF_HEALTHREPORT,
                'value':     data,
            }

            # publish sensor object
            self._publishObject(sobject)

        except Exception as err:
            printException(err)

    def _notifIPData(self, notifName, notifParams):

        try:
            assert notifName==IpMgrSubscribe.IpMgrSubscribe.NOTIFIPDATA

            # create sensor object (SOL_TYPE_NOTIF_IPDATA)
            sobject = {
                'mac':       macAddress,
                'timestamp': time.gmtime(),
                'type':      SolDefines.SOL_TYPE_NOTIF_IPDATA,
                'value':     data,
            }

            # publish sensor object
            self._publishObject(sobject)

        except Exception as err:
            printException(err)

    def _notifErrorFinish(self,notifName,notifParams):

        try:
            assert notifName in [
                IpMgrSubscribe.IpMgrSubscribe.ERROR,
                IpMgrSubscribe.IpMgrSubscribe.FINISH,
            ]

            if not self.reconnectEvent.isSet():
                self.reconnectEvent.set()
        except Exception as err:
            printException(err)

    #=== misc

    def _calcNetTs(self,notif):
        return float(notif.utcSecs)+float(notif.utcUsecs/1000000.0)

    def _syncNetTsToUtc(self,netTs):
        with self.dataLock:
            self.tsDiff = time.gmtime()-netTs

    def _netTsToEpoch(self,netTs):
        with self.dataLock:
            return netTs+self.tsDiff

    def _publishObject(self,object):
        print "========== _publishObject"
        print "TODO store to file"
        print "TODO send to server"

class JsonThread(threading.Thread):

    def __init__(self,tcpport):

        # store params
        self.tcpport    = tcpport

        # initialize web server
        self.web        = bottle.Bottle()
        self.web.route(path='/api/v1/echo.json',     method='POST', callback=self._cb_echo_POST)
        self.web.route(path='/api/v1/status.json',   method='GET',  callback=self._cb_status_GET)
        self.web.route(path='/api/v1/config.json',   method='POST', callback=self._cb_config_POST)
        self.web.route(path='/api/v1/config.json',   method='GET',  callback=self._cb_config_GET)
        self.web.route(path='/api/v1/flows.json',    method='GET',  callback=self._cb_flows_GET)
        self.web.route(path='/api/v1/flows.json',    method='POST', callback=self._cb_flows_POST)
        self.web.route(path='/api/v1/resend.json',   method='POST', callback=self._cb_resend_POST)
        self.web.route(path='/api/v1/snapshot.json', method='POST', callback=self._cb_snapshot_POST)

        # start the thread
        threading.Thread.__init__(self)
        self.name       = 'JsonThread'
        self.start()

    def run(self):

        # wait for banner to print
        time.sleep(0.5)

        self.web.run(
            host   = 'localhost',
            port   = self.tcpport,
            quiet  = True,
            debug  = False,
        )

    #======================== public ==========================================

    def close(self):
        print 'TODO JsonThread.close()'

    #======================== private ==========================================

    def _cb_echo_POST(self):
        # TODO: echo
        bottle.response.status = 501
        bottle.response.content_type = 'application/json'
        return json.dumps({'error': 'Not Implemented yet :-('})

    def _cb_status_GET(self):
        # TODO: echo
        bottle.response.status = 501
        bottle.response.content_type = 'application/json'
        return json.dumps({'error': 'Not Implemented yet :-('})

    def _cb_config_POST(self):
        # TODO: echo
        bottle.response.status = 501
        bottle.response.content_type = 'application/json'
        return json.dumps({'error': 'Not Implemented yet :-('})

    def _cb_config_GET(self):
        # TODO: echo
        bottle.response.status = 501
        bottle.response.content_type = 'application/json'
        return json.dumps({'error': 'Not Implemented yet :-('})

    def _cb_flows_GET(self):
        # TODO: echo
        bottle.response.status = 501
        bottle.response.content_type = 'application/json'
        return json.dumps({'error': 'Not Implemented yet :-('})

    def _cb_flows_POST(self):
        # TODO: echo
        bottle.response.status = 501
        bottle.response.content_type = 'application/json'
        return json.dumps({'error': 'Not Implemented yet :-('})

    def _cb_resend_POST(self):
        # TODO: echo
        bottle.response.status = 501
        bottle.response.content_type = 'application/json'
        return json.dumps({'error': 'Not Implemented yet :-('})

    def _cb_snapshot_POST(self):
        # TODO: echo
        bottle.response.status = 501
        bottle.response.content_type = 'application/json'
        return json.dumps({'error': 'Not Implemented yet :-('})

class Basestation(object):

    def __init__(self,serialport,tcpport):
        self.dustThread = DustThread(serialport)
        # TODO: add DataThread which periodically stores data to file
        # TODO: add SendThread which periodically send data to server
        self.jsonThread = JsonThread(tcpport)

    def close(self):
        self.dustApiThread.close()
        self.jsonThread.close()

#============================ main ============================================

basestation = None

def quitCallback():
    global basestation

    basestation.close()

def main(serialport,tcpport):
    global basestation

    # create the basestation instance
    basestation = Basestation(
        serialport,
        tcpport,
    )

    # start the CLI interface
    OpenCli.OpenCli(
        "Basestation",
        basestation_version.VERSION,
        quitCallback,
        [
            ("SmartMesh SDK",sdk_version.VERSION),
            (
                "Sol",
                (
                    SolVersion.SOL_VERSION['SOL_VERSION_MAJOR'],
                    SolVersion.SOL_VERSION['SOL_VERSION_MINOR'],
                    SolVersion.SOL_VERSION['SOL_VERSION_PATCH'],
                    SolVersion.SOL_VERSION['SOL_VERSION_BUILD'],
                ),
            ),
        ],
    )

if __name__ == '__main__':

    # parse the command line
    parser = OptionParser("usage: %prog [options]")
    parser.add_option(
        "-s", "--serialport", dest="serialport",
        default=DEFAULT_SERIALPORT,
        help="Serial port of the SmartMesh IP manager."
    )
    parser.add_option(
        "-t", "--tcpport", dest="tcpport",
        default=DEFAULT_TCPPORT,
        help="TCP port to start the JSON API on."
    )
    (options, args) = parser.parse_args()

    main(
        options.serialport,
        options.tcpport,
    )
<commit_msg>linking to issues<commit_after>#!/usr/bin/python

#============================ adjust path =====================================

import sys
import os
if __name__ == "__main__":
    here = sys.path[0]
    sys.path.insert(0, os.path.join(here, 'smartmeshsdk-master'))
    sys.path.insert(0, os.path.join(here, '..', 'Sol'))

#============================ imports =========================================

import time
import threading
import json
from   optparse                             import OptionParser

import OpenCli
import basestation_version

# DustThread
from   SmartMeshSDK                         import FormatUtils, \
                                                   HrParser,    \
                                                   sdk_version
from   SmartMeshSDK.IpMgrConnectorSerial    import IpMgrConnectorSerial
from   SmartMeshSDK.IpMgrConnectorMux       import IpMgrSubscribe

# JsonThread
import bottle
import Sol
import SolVersion
import SolDefines

#============================ defines =========================================

DEFAULT_SERIALPORT = 'COM14'
DEFAULT_TCPPORT    = 8080

#============================ helpers =========================================

def printException(err):
    output  = []
    output += ["ERROR:"]
    output += [str(err)]
    output  = '\n'.join(output)
    print output

#============================ classes =========================================

class DustThread(threading.Thread):

    def __init__(self, serialport):

        # store params
        self.serialport      = serialport

        # local variables
        self.reconnectEvent  = threading.Event()
        self.hrParser        = HrParser.HrParser()
        self.sol             = Sol.Sol()
        self.dataLock        = threading.RLock()
        self.goOn            = True

        # start the thread
        threading.Thread.__init__(self)
        self.name            = 'DustThread'
        self.start()

    def run(self):

        # wait for banner to print
        time.sleep(0.5)

        while self.goOn:

            try:
                print 'Connecting to {0}...'.format(self.serialport),

                # connect to the manager
                self.connector          = IpMgrConnectorSerial.IpMgrConnectorSerial()
                self.connector.connect({
                    'port': self.serialport,
                })

                # get MAC address of manager
                temp = self.dn_getSystemInfo()
                self.managerMac = temp.macAddress

                # sync network-UTC time
                temp  = self.dn_getTime()
                netTs = self._calcNetTs(temp)
                self._syncNetTsToUtc(netTs)

                # subscribe to notifications
                self.subscriber = IpMgrSubscribe.IpMgrSubscribe(self.connector)
                self.subscriber.start()
                self.subscriber.subscribe(
                    notifTypes =    [
                                        IpMgrSubscribe.IpMgrSubscribe.NOTIFDATA,
                                    ],
                    fun =           self._notifData,
                    isRlbl =        False,
                )
                self.subscriber.subscribe(
                    notifTypes =    [
                                        IpMgrSubscribe.IpMgrSubscribe.NOTIFEVENT,
                                    ],
                    fun =           self._notifEvent,
                    isRlbl =        True,
                )
                self.subscriber.subscribe(
                    notifTypes =    [
                                        IpMgrSubscribe.IpMgrSubscribe.NOTIFHEALTHREPORT,
                                    ],
                    fun =           self._notifHealthReport,
                    isRlbl =        True,
                )
                self.subscriber.subscribe(
                    notifTypes =    [
                                        IpMgrSubscribe.IpMgrSubscribe.NOTIFIPDATA,
                                    ],
                    fun =           self._notifIPData,
                    isRlbl =        False,
                )
                self.subscriber.subscribe(
                    notifTypes =    [
                                        IpMgrSubscribe.IpMgrSubscribe.NOTIFLOG,
                                    ],
                    fun =           self._notifLog,
                    isRlbl =        True,
                )
                self.subscriber.subscribe(
                    notifTypes =    [
                                        IpMgrSubscribe.IpMgrSubscribe.ERROR,
                                        IpMgrSubscribe.IpMgrSubscribe.FINISH,
                                    ],
                    fun =           self._notifErrorFinish,
                    isRlbl =        True,
                )

                print "TODO: periodically sync NetTs to UTC (#4)"

            except Exception as err:
                print 'FAIL.'

                try:
                   self.connector.disconnect()
                except:
                   pass

                # wait to reconnect
                time.sleep(1)

            else:
                print 'PASS.'
                self.reconnectEvent.clear()
                self.reconnectEvent.wait()

                try:
                   self.connector.disconnect()
                except:
                   pass

    #======================== public ==========================================

    def close(self):

        try:
            self.connector.disconnect()
        except:
            pass

        self.goOn = False

    #======================== private =========================================

    #=== Dust API notifications

    def _notifData(self, notifName, notifParams):

        try:
            assert notifName==IpMgrSubscribe.IpMgrSubscribe.NOTIFDATA

            # extract the important data
            netTs      = self._calcNetTs(notifParams)
            macAddress = notifParams.macAddress
            srcPort    = notifParams.srcPort
            dstPort    = notifParams.dstPort
            data       = notifParams.data

            isSol = False

            if dstPort==SolDefines.SOL_PORT:
                # try to decode as objects
                try:
                    raise NotImplementedError()
                except:
                    pass
                else:
                    isSol = True

            if not isSol:

                # create sensor object (NOTIF_DATA_RAW)
                sobject = {
                    'mac':       macAddress,
                    'timestamp': self._netTsToEpoch(netTs),
                    'type':      SolDefines.SOL_TYPE_NOTIF_DATA_RAW,
                    'value':     self.sol.create_value_NOTIF_DATA_RAW(
                        srcPort = srcPort,
                        dstPort = dstPort,
                        payload = data,
                    ),
                }

            # publish sensor object
            self._publishObject(sobject)

        except Exception as err:
            printException(err)

    def _notifEvent(self,notifName,notifParams):

        try:
            assert notifName==IpMgrSubscribe.IpMgrSubscribe.NOTIFEVENT

            # extract the important data
            eventId    = notifParams.eventId
            eventType  = notifParams.eventType
            data       = notifParams.eventData

            # create sensor object (SOL_TYPE_NOTIF_EVENT)
            sobject = {
                'mac':       self.managerMac,
                'timestamp': time.gmtime(),
                'type':      SolDefines.SOL_TYPE_NOTIF_EVENT,
                'value':     self.sol.create_value_NOTIF_EVENT(
                    eventID       = eventId,
                    eventType     = eventType,
                    payload       = data,
                ),
            }

            # publish sensor object
            self._publishObject(sobject)

        except Exception as err:
            printException(err)

    def _notifHealthReport(self,notifName,notifParams):

        try:
            assert notifName==IpMgrSubscribe.IpMgrSubscribe.NOTIFHEALTHREPORT

            # extract the important data
            netTs      = self._calcNetTs(notifParams)
            macAddress = notifParams.macAddress
            data       = notifParams.data

            # create sensor object (SOL_TYPE_NOTIF_HEALTHREPORT)
            sobject = {
                'mac':       macAddress,
                'timestamp': self._netTsToEpoch(netTs),
                'type':      SolDefines.SOL_TYPE_NOTIF_HEALTHREPORT,
                'value':     data,
            }

            # publish sensor object
            self._publishObject(sobject)

        except Exception as err:
            printException(err)

    def _notifIPData(self, notifName, notifParams):

        try:
            assert notifName==IpMgrSubscribe.IpMgrSubscribe.NOTIFIPDATA

            # create sensor object (SOL_TYPE_NOTIF_IPDATA)
            sobject = {
                'mac':       macAddress,
                'timestamp': time.gmtime(),
                'type':      SolDefines.SOL_TYPE_NOTIF_IPDATA,
                'value':     data,
            }

            # publish sensor object
            self._publishObject(sobject)

        except Exception as err:
            printException(err)

    def _notifErrorFinish(self,notifName,notifParams):

        try:
            assert notifName in [
                IpMgrSubscribe.IpMgrSubscribe.ERROR,
                IpMgrSubscribe.IpMgrSubscribe.FINISH,
            ]

            if not self.reconnectEvent.isSet():
                self.reconnectEvent.set()
        except Exception as err:
            printException(err)

    #=== misc

    def _calcNetTs(self,notif):
        return float(notif.utcSecs)+float(notif.utcUsecs/1000000.0)

    def _syncNetTsToUtc(self,netTs):
        with self.dataLock:
            self.tsDiff = time.gmtime()-netTs

    def _netTsToEpoch(self,netTs):
        with self.dataLock:
            return netTs+self.tsDiff

    def _publishObject(self,object):
        print "========== _publishObject"
        print "TODO store to file"
        print "TODO send to server"

class JsonThread(threading.Thread):

    def __init__(self,tcpport):

        # store params
        self.tcpport    = tcpport

        # initialize web server
        self.web        = bottle.Bottle()
        self.web.route(path='/api/v1/echo.json',     method='POST', callback=self._cb_echo_POST)
        self.web.route(path='/api/v1/status.json',   method='GET',  callback=self._cb_status_GET)
        self.web.route(path='/api/v1/config.json',   method='POST', callback=self._cb_config_POST)
        self.web.route(path='/api/v1/config.json',   method='GET',  callback=self._cb_config_GET)
        self.web.route(path='/api/v1/flows.json',    method='GET',  callback=self._cb_flows_GET)
        self.web.route(path='/api/v1/flows.json',    method='POST', callback=self._cb_flows_POST)
        self.web.route(path='/api/v1/resend.json',   method='POST', callback=self._cb_resend_POST)
        self.web.route(path='/api/v1/snapshot.json', method='POST', callback=self._cb_snapshot_POST)

        # start the thread
        threading.Thread.__init__(self)
        self.name       = 'JsonThread'
        self.start()

    def run(self):

        # wait for banner to print
        time.sleep(0.5)

        self.web.run(
            host   = 'localhost',
            port   = self.tcpport,
            quiet  = True,
            debug  = False,
        )

    #======================== public ==========================================

    def close(self):
        print 'TODO JsonThread.close() (#5)'

    #======================== private ==========================================

    def _cb_echo_POST(self):
        # TODO: implement (#6)
        bottle.response.status = 501
        bottle.response.content_type = 'application/json'
        return json.dumps({'error': 'Not Implemented yet :-('})

    def _cb_status_GET(self):
        # TODO: implement (#7)
        bottle.response.status = 501
        bottle.response.content_type = 'application/json'
        return json.dumps({'error': 'Not Implemented yet :-('})

    def _cb_config_POST(self):
        # TODO: implement (#8)
        bottle.response.status = 501
        bottle.response.content_type = 'application/json'
        return json.dumps({'error': 'Not Implemented yet :-('})

    def _cb_config_GET(self):
        # TODO: implement (#9)
        bottle.response.status = 501
        bottle.response.content_type = 'application/json'
        return json.dumps({'error': 'Not Implemented yet :-('})

    def _cb_flows_GET(self):
        # TODO: implement (#10)
        bottle.response.status = 501
        bottle.response.content_type = 'application/json'
        return json.dumps({'error': 'Not Implemented yet :-('})

    def _cb_flows_POST(self):
        # TODO: implement (#11)
        bottle.response.status = 501
        bottle.response.content_type = 'application/json'
        return json.dumps({'error': 'Not Implemented yet :-('})

    def _cb_resend_POST(self):
        # TODO: implement (#12)
        bottle.response.status = 501
        bottle.response.content_type = 'application/json'
        return json.dumps({'error': 'Not Implemented yet :-('})

    def _cb_snapshot_POST(self):
        # TODO: implement (#13)
        bottle.response.status = 501
        bottle.response.content_type = 'application/json'
        return json.dumps({'error': 'Not Implemented yet :-('})

class Basestation(object):

    def __init__(self,serialport,tcpport):
        self.dustThread = DustThread(serialport)
        # TODO: add DataThread which periodically stores data to file (#14)
        # TODO: add SendThread which periodically sends data to server (#15)
        self.jsonThread = JsonThread(tcpport)

    def close(self):
        self.dustApiThread.close()
        self.jsonThread.close()

#============================ main ============================================

basestation = None

def quitCallback():
    global basestation

    basestation.close()

def main(serialport,tcpport):
    global basestation

    # create the basestation instance
    basestation = Basestation(
        serialport,
        tcpport,
    )

    # start the CLI interface
    OpenCli.OpenCli(
        "Basestation",
        basestation_version.VERSION,
        quitCallback,
        [
            ("SmartMesh SDK",sdk_version.VERSION),
            (
                "Sol",
                (
                    SolVersion.SOL_VERSION['SOL_VERSION_MAJOR'],
                    SolVersion.SOL_VERSION['SOL_VERSION_MINOR'],
                    SolVersion.SOL_VERSION['SOL_VERSION_PATCH'],
                    SolVersion.SOL_VERSION['SOL_VERSION_BUILD'],
                ),
            ),
        ],
    )

if __name__ == '__main__':

    # parse the command line
    parser = OptionParser("usage: %prog [options]")
    parser.add_option(
        "-s", "--serialport", dest="serialport",
        default=DEFAULT_SERIALPORT,
        help="Serial port of the SmartMesh IP manager."
    )
    parser.add_option(
        "-t", "--tcpport", dest="tcpport",
        default=DEFAULT_TCPPORT,
        help="TCP port to start the JSON API on."
    )
    (options, args) = parser.parse_args()

    main(
        options.serialport,
        options.tcpport,
    )
<|endoftext|>


<commit_before>import pymongo
import os
import abc
import string
import util
from textblob import TextBlob, Word, Blobber
from textblob.taggers import NLTKTagger
from textblob.taggers import PatternTagger
from textblob_aptagger import PerceptronTagger
from textblob.wordnet import ADV, ADJ, NOUN, VERB

class BaseModel(object):
	"""docstring for BaseModel class that represents and generic corpora in mongodb"""

	__metaclass__ = abc.ABCMeta

	def __init__(self, database_name, domain='localhost', port=27017):
		super(BaseModel, self).__init__()
		self.client = pymongo.MongoClient(domain, port)
		self.database_name = database_name
		self.database = self.client[database_name]
		self.documents = self.database.documents

		self.PENN_ADVERBS_TAGS = ['RB', 'RBR', 'RBS', 'RP']
		self.PENN_ADJECTIVES_TAGS = ['JJ','JJR','JJS']
		self.PENN_NOUNS_TAGS = ['NN','NNS','NNP','NNPS']
		self.PENN_VERBS_TAGS = ['MD','VB','VBZ','VBP','VBD','VBN','VBG']
		self.ADVERB_ADJECTIVE_BIGRAMS = ["RB/JJ","RB/JJR", "RB/JJS",
											"RBR/JJ","RBR/JJR", "RBR/JJS",
											"RBS/JJ","RBS/JJR", "RBS/JJS",
											"RP/JJ","RP/JJR", "RP/JJS"]

	@abc.abstractmethod
	def read_corpora_source(self):
		"""This method should be implemented by each subclass that defines the way of reading each corpora.
		It must returns a list of dictionaries elements.
		"""

		pass

	@abc.abstractmethod
	def create_database(self):
		"""Creates the mongodb database and its documents"""

		pass

	def is_adverb(self, word_tag):
		"""Checks if the passed tag is an adverb tag.

		Keyword arguments:
		word_tag -- Penn tag from word in ngram
		"""

		return word_tag in self.PENN_ADVERBS_TAGS

	def is_adjective(self, word_tag):
		"""Checks if the passed tag is an adjective tag.

		Keyword arguments:
		word_tag -- Penn tag from word in ngram
		"""

		return word_tag in self.PENN_ADJECTIVES_TAGS

	def is_noun(self, word_tag):
		"""Checks if the passed tag is an noun tag.

		Keyword arguments:
		word_tag -- Penn tag from word in ngram
		"""

		return word_tag in self.PENN_NOUNS_TAGS

	def is_verb(self, word_tag):
		"""Checks if the passed tag is an verb tag.

		Keyword arguments:
		word_tag -- Penn tag from word in ngram
		"""

		return word_tag in self.PENN_VERBS_TAGS

	def is_adverb_adjective_bigram(self, bigram, type="ADV_ADJ"):
		"""Checks if the passed bigram is an adverb_adjective bigram.

		Keyword arguments:
		bigram -- should be in the following pattern: tag1/tag2
		type -- passes the type of bigram to be validated
		"""

		return bigram in self.ADVERB_ADJECTIVE_BIGRAMS

	def tags(self, blob):
		parsed_text = blob.parse().split()
		tags = []
		for elem in parsed_text[0]:
			tags.append((elem[0],elem[1]))

		return tags

	def pre_process_adverbs(self, tagger="PerceptronTagger"):
		"""This method extracts all adverbs from each document in the documents collection

			Keyword:
			tagger -- tagger choosed. It could be among the following:
                      PerceptronTagger (default) and PatternTagger
		"""

		pt = Blobber(pos_tagger=PerceptronTagger())
		if tagger == "PatternTagger":
			pt = Blobber(pos_tagger=PatternTagger())
		else:
			print "PerceptronTagger will be used"

		for ndoc in self.documents.find():
			blob = pt(ndoc['text'])
			advs = []
			for word, tag in self.tags(blob):
				is_adv = len(Word(word).get_synsets(pos=ADV)) > 0
				if tag in self.PENN_ADVERBS_TAGS and is_adv:
					advs.append(word)
			self.documents.update({'name':ndoc['name']},{'$set':{'adverbs':advs}})

	def pre_process_nouns(self, tagger="PerceptronTagger"):
		"""This method extracts all nouns from each document in the documents collection

			Keyword:
			tagger -- tagger choosed. It could be among the following:
                      PerceptronTagger (default) and PatternTagger
		"""

		pt = Blobber(pos_tagger=PerceptronTagger())
		if tagger == "PatternTagger":
			pt = Blobber(pos_tagger=PatternTagger())
		else:
			print "PerceptronTagger will be used"

		for ndoc in self.documents.find():
			blob = pt(ndoc['text'])
			nouns = []
			for word, tag in self.tags(blob):
				is_noun = len(Word(word).get_synsets(pos=NOUN)) > 0
				if tag in self.PENN_NOUNS_TAGS and is_noun:
					nouns.append(word)
			self.documents.update({'name':ndoc['name']},{'$set':{'nouns':nouns}})

	def pre_process_adjectives(self, tagger="PerceptronTagger"):
		"""This method extracts all adjectives from each document in the documents collection

			Keyword:
			tagger -- tagger choosed. It could be among the following:
                      PerceptronTagger (default) and PatternTagger
		"""

		pt = Blobber(pos_tagger=PerceptronTagger())
		if tagger == "PatternTagger":
			pt = Blobber(pos_tagger=PatternTagger())
		else:
			print "PerceptronTagger will be used"

		for ndoc in self.documents.find():
			blob = pt(ndoc['text'])
			adjectives = []
			for word, tag in self.tags(blob):
				is_adjective = len(Word(word).get_synsets(pos=ADJ)) > 0
				if tag in self.PENN_ADJECTIVES_TAGS and is_adjective:
					adjectives.append(word)
			self.documents.update({'name':ndoc['name']},{'$set':{'adjectives':adjectives}})

	def pre_process_adv_adj_bigrams(self, tagger="PerceptronTagger"):
		"""This method extracts all adv_adj_bigrams from each document in the documents collection

			Keyword:
			tagger -- tagger choosed. It could be among the following:
                      PerceptronTagger (default) and PatternTagger
		"""

		pt = Blobber(pos_tagger=PerceptronTagger())
		if tagger == "PatternTagger":
			pt = Blobber(pos_tagger=PatternTagger())
		else:
			print "PerceptronTagger will be used"

		for ndoc in self.documents.find():
			blob = TextBlob(ndoc['text'])
			valid_bigrams = []
			for s in blob.sentences:
				sentence = pt(s.dict['raw'])
				sentence = pt(sentence.parse())
				bigrams = sentence.ngrams(n=2)
				valid_bigrams = valid_bigrams + util.get_adv_adj_bigrams(bigrams, self.ADVERB_ADJECTIVE_BIGRAMS)
			self.documents.update({'name':ndoc['name']},{'$set':{'adv_adj_bigrams':valid_bigrams}})

	def parse_elements_adv_adj_bigrams(self):
		"""This method extracs adjectives and adverbs from adv_adj_bigrams"""

		for ndoc in self.documents.find():
			advs_adv_adj_bigram = []
			adjs_adv_adj_bigram = []
			for bigram in ndoc['adv_adj_bigrams']:
				element_1 = bigram[0].split('/')
				element_2 = bigram[1].split('/')
				if element_1[1] in self.PENN_ADVERBS_TAGS:
					advs_adv_adj_bigram.append(element_1[0])

				if element_2[1] in self.PENN_ADJECTIVES_TAGS:
					adjs_adv_adj_bigram.append(element_2[0])

			self.documents.update({'name':ndoc['name']},{'$set':{'advs_adv_adj_bigram':advs_adv_adj_bigram}})
			self.documents.update({'name':ndoc['name']},{'$set':{'adjs_adv_adj_bigram':adjs_adv_adj_bigram}})

	def create_or_update_collection_from_file(self,file_name, collection_name):
		""" File must have only a pair of values per line, separated by ; """

		f = open(file_name)
		collection = self.database[collection_name]
		for line in f.readlines():
			values = line.split('\n')[0]
			values = values.split(';')
			adverb = values[0]
			factor = values[1]
			collection.insert({'word':adverb,'factor':factor})
		f.close()

	def pre_process_ngrams(self, tagger="PerceptronTagger"):
		"""This method calls the other methods for each type of ngram. It is a shorcut instead of call
			the other one by one.

			Keyword:
			tagger -- tagger choosed. It could be among the following:
                      PerceptronTagger (default) and PatternTagger
		"""

		print 'Pre processing adjectives...This can take awhile, depending on corpora size. Cofee, maybe?'
		self.pre_process_adjectives(tagger)
		print 'Pre processing noun...A snack, perhaps?'
		self.pre_process_nouns(tagger)
		print 'Pre processing adverbs...Go read a book or something else, what do you think?'
		self.pre_process_adverbs(tagger)
		print 'Pre processing adv/adj bigram...Boy, this last one is big!'
		self.pre_process_adv_adj_bigrams(tagger)

class TripAdvisorModel(BaseModel):
	"""docstring for TripAdvisorModel"""

	def __init__(self,database_name="TripAdvisor"):
		BaseModel.__init__(self, database_name)

	def read_corpora_source(self):

		source_5255 = os.path.abspath(os.curdir) + '/corpora/trip_advisor/TripAdvisor_5255.txt'
		source_10508 = os.path.abspath(os.curdir) + '/corpora/trip_advisor/TripAdvisor_10508.txt'
		source_file_5255 = open(source_5255,'r')
		source_file_10508 = open(source_10508,'r')

		list_of_dict_units = []

		for line in source_file_5255.readlines():
			parts = line.split()
			name = parts[0]
			degree = parts[len(parts) - 1]

			cons = parts[len(parts) - 2]
			cons = cons.decode('Windows-1252').encode('utf-8')

			pros = parts[len(parts) - 3]
			pros = pros.decode('Windows-1252').encode('utf-8')

			text = string.join(parts[1:len(parts)-3])
			list_of_dict_units.append({'name':name,'text':text,'degree':degree,'pros':pros,'cons':cons})

		for line in source_file_10508.readlines():
			parts = line.split()
			name = parts[0]
			degree = parts[len(parts) - 1]

			cons = parts[len(parts) - 2]
			cons = cons.decode('Windows-1252').encode('utf-8')

			pros = parts[len(parts) - 3]
			pros = pros.decode('Windows-1252').encode('utf-8')

			text = string.join(parts[1:len(parts)-3])
			list_of_dict_units.append({'name':name,'text':text,'degree':degree,'pros':pros,'cons':cons})

		return list_of_dict_units

	def create_database(self):

		docs = self.read_corpora_source()
		#inserts documents into collection
		for d in docs:
			self.documents.insert(d)

		#search for documents with NULL information and attaches the doc id to turn the name unique
		for ndoc in self.documents.find():
			if 'NULL' in ndoc['name']:
				new_ndoc_name = ndoc['name'] + "_" + str(ndoc['_id'])
				self.documents.update({'_id':ndoc['_id']},{'$set':{'name':new_ndoc_name}})

class CornellMoviesModel(BaseModel):
	"""docstring for CornellMoviesModel"""

	def __init__(self, database_name="CornellMovies"):
		BaseModel.__init__(self, database_name)

	def read_corpora_source(self):

		POS_DOCS_PATH = os.path.abspath(os.curdir) + '/corpora/cs_cornell_edu/txt_sentoken/pos'
		NEG_DOCS_PATH = os.path.abspath(os.curdir) + '/corpora/cs_cornell_edu/txt_sentoken/neg'
		files_pos = os.listdir(POS_DOCS_PATH)
		files_neg = os.listdir(NEG_DOCS_PATH)
		list_of_dict_units = []

		for fn in files_pos:
			if fn.find('txt') != -1:
				fn_name = POS_DOCS_PATH + '/' + fn
				doc = {'name': fn,
						'text':open(fn_name).read(),
						'polarity':1}
				list_of_dict_units.append(doc)

		for fn in files_neg:
			if fn.find('txt') != -1:
				fn_name = NEG_DOCS_PATH + '/' + fn
				doc = {'name': fn,
						'text':open(fn_name).read(),
						'polarity':0}

				list_of_dict_units.append(doc)

		return list_of_dict_units

	def create_database(self):

		docs = self.read_corpora_source()
		#inserts documents into collection
		for d in docs:
			self.documents.insert(d)

<commit_msg>added a function that processes adv/verb bigrams<commit_after>import pymongo
import os
import abc
import string
import util
from textblob import TextBlob, Word, Blobber
from textblob.taggers import NLTKTagger
from textblob.taggers import PatternTagger
from textblob_aptagger import PerceptronTagger
from textblob.wordnet import ADV, ADJ, NOUN, VERB

class BaseModel(object):
	"""docstring for BaseModel class that represents and generic corpora in mongodb"""

	__metaclass__ = abc.ABCMeta

	def __init__(self, database_name, domain='localhost', port=27017):
		super(BaseModel, self).__init__()
		self.client = pymongo.MongoClient(domain, port)
		self.database_name = database_name
		self.database = self.client[database_name]
		self.documents = self.database.documents

		self.PENN_ADVERBS_TAGS = ['RB', 'RBR', 'RBS', 'RP']
		self.PENN_ADJECTIVES_TAGS = ['JJ','JJR','JJS']
		self.PENN_NOUNS_TAGS = ['NN','NNS','NNP','NNPS']
		self.PENN_VERBS_TAGS = ['MD','VB','VBZ','VBP','VBD','VBN','VBG']
		self.ADVERB_ADJECTIVE_BIGRAMS = ["RB/JJ","RB/JJR", "RB/JJS",
											"RBR/JJ","RBR/JJR", "RBR/JJS",
											"RBS/JJ","RBS/JJR", "RBS/JJS",
											"RP/JJ","RP/JJR", "RP/JJS"]

		self.ADVERB_VERB_BIGRAMS = ['RB/MD','RB/VB','RB/VBZ','RB/VBP','RB/VBD','RB/VBN','RB/VBG',
									'RBR/MD','RBR/VB','RBR/VBZ','RBR/VBP','RBR/VBD','RBR/VBN','RBR/VBG',
									'RBS/MD','RBS/VB','RBS/VBZ','RBS/VBP','RBS/VBD','RBS/VBN','RBS/VBG',
									'RP/MD','RP/VB','RP/VBZ','RP/VBP','RP/VBD','RP/VBN','RP/VBG']

	@abc.abstractmethod
	def read_corpora_source(self):
		"""This method should be implemented by each subclass that defines the way of reading each corpora.
		It must returns a list of dictionaries elements.
		"""

		pass

	@abc.abstractmethod
	def create_database(self):
		"""Creates the mongodb database and its documents"""

		pass

	def is_adverb(self, word_tag):
		"""Checks if the passed tag is an adverb tag.

		Keyword arguments:
		word_tag -- Penn tag from word in ngram
		"""

		return word_tag in self.PENN_ADVERBS_TAGS

	def is_adjective(self, word_tag):
		"""Checks if the passed tag is an adjective tag.

		Keyword arguments:
		word_tag -- Penn tag from word in ngram
		"""

		return word_tag in self.PENN_ADJECTIVES_TAGS

	def is_noun(self, word_tag):
		"""Checks if the passed tag is an noun tag.

		Keyword arguments:
		word_tag -- Penn tag from word in ngram
		"""

		return word_tag in self.PENN_NOUNS_TAGS

	def is_verb(self, word_tag):
		"""Checks if the passed tag is an verb tag.

		Keyword arguments:
		word_tag -- Penn tag from word in ngram
		"""

		return word_tag in self.PENN_VERBS_TAGS

	def is_adverb_adjective_bigram(self, bigram, type="ADV_ADJ"):
		"""Checks if the passed bigram is an adverb_adjective bigram.

		Keyword arguments:
		bigram -- should be in the following pattern: tag1/tag2
		type -- passes the type of bigram to be validated
		"""

		return bigram in self.ADVERB_ADJECTIVE_BIGRAMS

	def tags(self, blob):
		parsed_text = blob.parse().split()
		tags = []
		for elem in parsed_text[0]:
			tags.append((elem[0],elem[1]))

		return tags

	def pre_process_adverbs(self, tagger="PerceptronTagger"):
		"""This method extracts all adverbs from each document in the documents collection

			Keyword:
			tagger -- tagger choosed. It could be among the following:
                      PerceptronTagger (default) and PatternTagger
		"""

		pt = Blobber(pos_tagger=PerceptronTagger())
		if tagger == "PatternTagger":
			pt = Blobber(pos_tagger=PatternTagger())
		else:
			print "PerceptronTagger will be used"

		for ndoc in self.documents.find():
			blob = pt(ndoc['text'])
			advs = []
			for word, tag in self.tags(blob):
				is_adv = len(Word(word).get_synsets(pos=ADV)) > 0
				if tag in self.PENN_ADVERBS_TAGS and is_adv:
					advs.append(word)
			self.documents.update({'name':ndoc['name']},{'$set':{'adverbs':advs}})

	def pre_process_nouns(self, tagger="PerceptronTagger"):
		"""This method extracts all nouns from each document in the documents collection

			Keyword:
			tagger -- tagger choosed. It could be among the following:
                      PerceptronTagger (default) and PatternTagger
		"""

		pt = Blobber(pos_tagger=PerceptronTagger())
		if tagger == "PatternTagger":
			pt = Blobber(pos_tagger=PatternTagger())
		else:
			print "PerceptronTagger will be used"

		for ndoc in self.documents.find():
			blob = pt(ndoc['text'])
			nouns = []
			for word, tag in self.tags(blob):
				is_noun = len(Word(word).get_synsets(pos=NOUN)) > 0
				if tag in self.PENN_NOUNS_TAGS and is_noun:
					nouns.append(word)
			self.documents.update({'name':ndoc['name']},{'$set':{'nouns':nouns}})

	def pre_process_adjectives(self, tagger="PerceptronTagger"):
		"""This method extracts all adjectives from each document in the documents collection

			Keyword:
			tagger -- tagger choosed. It could be among the following:
                      PerceptronTagger (default) and PatternTagger
		"""

		pt = Blobber(pos_tagger=PerceptronTagger())
		if tagger == "PatternTagger":
			pt = Blobber(pos_tagger=PatternTagger())
		else:
			print "PerceptronTagger will be used"

		for ndoc in self.documents.find():
			blob = pt(ndoc['text'])
			adjectives = []
			for word, tag in self.tags(blob):
				is_adjective = len(Word(word).get_synsets(pos=ADJ)) > 0
				if tag in self.PENN_ADJECTIVES_TAGS and is_adjective:
					adjectives.append(word)
			self.documents.update({'name':ndoc['name']},{'$set':{'adjectives':adjectives}})

	def pre_process_adv_adj_bigrams(self, tagger="PerceptronTagger"):
		"""This method extracts all adv_adj_bigrams from each document in the documents collection

			Keyword:
			tagger -- tagger choosed. It could be among the following:
                      PerceptronTagger (default) and PatternTagger
		"""

		pt = Blobber(pos_tagger=PerceptronTagger())
		if tagger == "PatternTagger":
			pt = Blobber(pos_tagger=PatternTagger())
		else:
			print "PerceptronTagger will be used"

		for ndoc in self.documents.find():
			blob = TextBlob(ndoc['text'])
			valid_bigrams = []
			for s in blob.sentences:
				sentence = pt(s.dict['raw'])
				sentence = pt(sentence.parse())
				bigrams = sentence.ngrams(n=2)
				valid_bigrams = valid_bigrams + util.get_bigrams(bigrams, self.ADVERB_ADJECTIVE_BIGRAMS)
			self.documents.update({'name':ndoc['name']},{'$set':{'adv_adj_bigrams':valid_bigrams}})

	def parse_elements_adv_adj_bigrams(self):
		"""This method extracs adjectives and adverbs from adv_adj_bigrams"""

		for ndoc in self.documents.find():
			advs_adv_adj_bigram = []
			adjs_adv_adj_bigram = []
			for bigram in ndoc['adv_adj_bigrams']:
				element_1 = bigram[0].split('/')
				element_2 = bigram[1].split('/')
				if element_1[1] in self.PENN_ADVERBS_TAGS:
					advs_adv_adj_bigram.append(element_1[0])

				if element_2[1] in self.PENN_ADJECTIVES_TAGS:
					adjs_adv_adj_bigram.append(element_2[0])

			self.documents.update({'name':ndoc['name']},{'$set':{'advs_adv_adj_bigram':advs_adv_adj_bigram}})
			self.documents.update({'name':ndoc['name']},{'$set':{'adjs_adv_adj_bigram':adjs_adv_adj_bigram}})

	def pre_process_adv_verb_bigram(self,tagger="PerceptronTagger"):
		"""
			Keyword:
			tagger -- tagger choosed. It could be among the following:
					PerceptronTagger (default) and PatternTagger

		"""

		pt = Blobber(pos_tagger=PerceptronTagger())
		if tagger == "PatternTagger":
			pt = Blobber(pos_tagger=PatternTagger())
		else:
			print "PerceptronTagger will be used"

		for ndoc in self.documents.find():
			blob = TextBlob(ndoc['text'])
			valid_bigrams = []
			for s in blob.sentences:
				sentence = pt(s.dict['raw'])
				sentence = pt(sentence.parse())
				bigrams = sentence.ngrams(n=2)
				valid_bigrams = valid_bigrams + util.get_bigrams(bigrams, self.ADVERB_VERB_BIGRAMS)
			self.documents.update({'name':ndoc['name']},{'$set':{'adv_verb_bigrams':valid_bigrams}})

	def create_or_update_collection_from_file(self,file_name, collection_name):
		""" File must have only a pair of values per line, separated by ; """

		f = open(file_name)
		collection = self.database[collection_name]
		for line in f.readlines():
			values = line.split('\n')[0]
			values = values.split(';')
			adverb = values[0]
			factor = values[1]
			collection.insert({'word':adverb,'factor':factor})
		f.close()

	def pre_process_ngrams(self, tagger="PerceptronTagger"):
		"""This method calls the other methods for each type of ngram. It is a shorcut instead of call
			the other one by one.

			Keyword:
			tagger -- tagger choosed. It could be among the following:
                      PerceptronTagger (default) and PatternTagger
		"""

		print 'Pre processing adjectives...This can take awhile, depending on corpora size. Cofee, maybe?'
		self.pre_process_adjectives(tagger)
		print 'Pre processing noun...A snack, perhaps?'
		self.pre_process_nouns(tagger)
		print 'Pre processing adverbs...Go read a book or something else, what do you think?'
		self.pre_process_adverbs(tagger)
		print 'Pre processing adv/adj bigram...Boy, this last one is big!'
		self.pre_process_adv_adj_bigrams(tagger)

class TripAdvisorModel(BaseModel):
	"""docstring for TripAdvisorModel"""

	def __init__(self,database_name="TripAdvisor"):
		BaseModel.__init__(self, database_name)

	def read_corpora_source(self):

		source_5255 = os.path.abspath(os.curdir) + '/corpora/trip_advisor/TripAdvisor_5255.txt'
		source_10508 = os.path.abspath(os.curdir) + '/corpora/trip_advisor/TripAdvisor_10508.txt'
		source_file_5255 = open(source_5255,'r')
		source_file_10508 = open(source_10508,'r')

		list_of_dict_units = []

		for line in source_file_5255.readlines():
			parts = line.split()
			name = parts[0]
			degree = parts[len(parts) - 1]

			cons = parts[len(parts) - 2]
			cons = cons.decode('Windows-1252').encode('utf-8')

			pros = parts[len(parts) - 3]
			pros = pros.decode('Windows-1252').encode('utf-8')

			text = string.join(parts[1:len(parts)-3])
			list_of_dict_units.append({'name':name,'text':text,'degree':degree,'pros':pros,'cons':cons})

		for line in source_file_10508.readlines():
			parts = line.split()
			name = parts[0]
			degree = parts[len(parts) - 1]

			cons = parts[len(parts) - 2]
			cons = cons.decode('Windows-1252').encode('utf-8')

			pros = parts[len(parts) - 3]
			pros = pros.decode('Windows-1252').encode('utf-8')

			text = string.join(parts[1:len(parts)-3])
			list_of_dict_units.append({'name':name,'text':text,'degree':degree,'pros':pros,'cons':cons})

		return list_of_dict_units

	def create_database(self):

		docs = self.read_corpora_source()
		#inserts documents into collection
		for d in docs:
			self.documents.insert(d)

		#search for documents with NULL information and attaches the doc id to turn the name unique
		for ndoc in self.documents.find():
			if 'NULL' in ndoc['name']:
				new_ndoc_name = ndoc['name'] + "_" + str(ndoc['_id'])
				self.documents.update({'_id':ndoc['_id']},{'$set':{'name':new_ndoc_name}})

class CornellMoviesModel(BaseModel):
	"""docstring for CornellMoviesModel"""

	def __init__(self, database_name="CornellMovies"):
		BaseModel.__init__(self, database_name)

	def read_corpora_source(self):

		POS_DOCS_PATH = os.path.abspath(os.curdir) + '/corpora/cs_cornell_edu/txt_sentoken/pos'
		NEG_DOCS_PATH = os.path.abspath(os.curdir) + '/corpora/cs_cornell_edu/txt_sentoken/neg'
		files_pos = os.listdir(POS_DOCS_PATH)
		files_neg = os.listdir(NEG_DOCS_PATH)
		list_of_dict_units = []

		for fn in files_pos:
			if fn.find('txt') != -1:
				fn_name = POS_DOCS_PATH + '/' + fn
				doc = {'name': fn,
						'text':open(fn_name).read(),
						'polarity':1}
				list_of_dict_units.append(doc)

		for fn in files_neg:
			if fn.find('txt') != -1:
				fn_name = NEG_DOCS_PATH + '/' + fn
				doc = {'name': fn,
						'text':open(fn_name).read(),
						'polarity':0}

				list_of_dict_units.append(doc)

		return list_of_dict_units

	def create_database(self):

		docs = self.read_corpora_source()
		#inserts documents into collection
		for d in docs:
			self.documents.insert(d)
<|endoftext|>


<commit_before>#!/usr/bin/python -tt
# Copyright 2010 Google Inc.
# Licensed under the Apache License, Version 2.0
# http://www.apache.org/licenses/LICENSE-2.0

# Google's Python Class
# http://code.google.com/edu/languages/google-python-class/

# Additional basic list exercises

# D. Given a list of numbers, return a list where
# all adjacent == elements have been reduced to a single element,
# so [1, 2, 2, 3] returns [1, 2, 3]. You may create a new list or
# modify the passed in list.
def remove_adjacent(nums):
  nums_no_runs = []
  for index, num in enumerate(nums):
    if ((0 == index)
        or (nums[index-1] != num)):
      nums_no_runs.append(num)

  return nums_no_runs

# E. Given two lists sorted in increasing order, create and return a merged
# list of all the elements in sorted order. You may modify the passed in lists.
# Ideally, the solution should work in "linear" time, making a single
# pass of both lists.
def linear_merge(list1, list2):

  merged_list = []
  list_merge_length = (len(list1) + len(list2))

  for index in range(0, list_merge_length):
    if (0 == len(list1)):
      merged_list.append(list2.pop(-1))
    elif (0 == len(list2)):
      merged_list.append(list1.pop(-1))
    elif list1[-1] >= list2[-1]:
      merged_list.append(list1.pop(-1))
    else:
      merged_list.append(list2.pop(-1))

  print merged_list

  merged_list.reverse()
  return merged_list

  # Note: the solution above is kind of cute, but unforunately list.pop(0)
  # is not constant time with the standard python list implementation, so
  # the above is not strictly linear time.
  # An alternate approach uses pop(-1) to remove the endmost elements
  # from each list, building a solution list which is backwards.
  # Then use reversed() to put the result back in the correct order. That
  # solution works in linear time, but is more ugly.

# Simple provided test() function used in main() to print
# what each function returns vs. what it's supposed to return.
def test(got, expected):
  if got == expected:
    prefix = ' OK '
  else:
    prefix = '  X '
  print '%s got: %s expected: %s' % (prefix, repr(got), repr(expected))

# Calls the above functions with interesting inputs.
def main():
  print 'remove_adjacent'
  test(remove_adjacent([1, 2, 2, 3]), [1, 2, 3])
  test(remove_adjacent([2, 2, 3, 3, 3]), [2, 3])
  test(remove_adjacent([]), [])

  print
  print 'linear_merge'
  test(linear_merge(['aa', 'xx', 'zz'], ['bb', 'cc']),
       ['aa', 'bb', 'cc', 'xx', 'zz'])
  test(linear_merge(['aa', 'xx'], ['bb', 'cc', 'zz']),
       ['aa', 'bb', 'cc', 'xx', 'zz'])
  test(linear_merge(['aa', 'aa'], ['aa', 'bb', 'bb']),
       ['aa', 'aa', 'aa', 'bb', 'bb'])

if __name__ == '__main__':
  main()
<commit_msg>In list2.py revise comments and change to docstring.<commit_after>#!/usr/bin/python -tt
# Copyright 2010 Google Inc.
# Licensed under the Apache License, Version 2.0
# http://www.apache.org/licenses/LICENSE-2.0

# Google's Python Class
# http://code.google.com/edu/languages/google-python-class/

# Additional basic list exercises

# D. Given a list of numbers, return a list where
# all adjacent == elements have been reduced to a single element,
# so [1, 2, 2, 3] returns [1, 2, 3]. You may create a new list or
# modify the passed in list.
def remove_adjacent(nums):
  nums_no_runs = []
  for index, num in enumerate(nums):
    if ((0 == index)
        or (nums[index-1] != num)):
      nums_no_runs.append(num)

  return nums_no_runs

# E. Given two lists sorted in increasing order, create and return a merged
# list of all the elements in sorted order. You may modify the passed in lists.
# Ideally, the solution should work in "linear" time, making a single
# pass of both lists.
def linear_merge(list1, list2):
  """
  Unforunately list.pop(0) is not constant time with the standard python list implementation.
  Use pop(-1) to remove the endmost elements from each list, building a solution list which is backwards.
  Then use reversed() to put the result back in the correct order.
  This solution works in linear time, but is more ugly.
  """

  merged_list = []
  list_merge_length = (len(list1) + len(list2))

  for index in range(0, list_merge_length):
    if (0 == len(list1)):
      merged_list.append(list2.pop(-1))
    elif (0 == len(list2)):
      merged_list.append(list1.pop(-1))
    elif list1[-1] >= list2[-1]:
      merged_list.append(list1.pop(-1))
    else:
      merged_list.append(list2.pop(-1))

  print merged_list

  merged_list.reverse()
  return merged_list

# Simple provided test() function used in main() to print
# what each function returns vs. what it's supposed to return.
def test(got, expected):
  if got == expected:
    prefix = ' OK '
  else:
    prefix = '  X '
  print '%s got: %s expected: %s' % (prefix, repr(got), repr(expected))

# Calls the above functions with interesting inputs.
def main():
  print 'remove_adjacent'
  test(remove_adjacent([1, 2, 2, 3]), [1, 2, 3])
  test(remove_adjacent([2, 2, 3, 3, 3]), [2, 3])
  test(remove_adjacent([]), [])

  print
  print 'linear_merge'
  test(linear_merge(['aa', 'xx', 'zz'], ['bb', 'cc']),
       ['aa', 'bb', 'cc', 'xx', 'zz'])
  test(linear_merge(['aa', 'xx'], ['bb', 'cc', 'zz']),
       ['aa', 'bb', 'cc', 'xx', 'zz'])
  test(linear_merge(['aa', 'aa'], ['aa', 'bb', 'bb']),
       ['aa', 'aa', 'aa', 'bb', 'bb'])

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


<commit_before>""" Text GAN

Adverserial networks applied to language models using Gumbel Softmax.

Can be used as pure language model.
"""
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

import tensorflow as tf

# -- local imports
from data_loader import build_vocab, preprocess, get_and_run_input_queues
from layers import (
    embedding_layer, recurrent_layer, reshape_layer, dense_layer, softmax_layer,
    cross_entropy_layer, mean_loss_by_example_layer
)

# TODO: add to flags
HIDDEN_DIMS = 128

class Model:
    def __init__(self, path, **model_params):
        self.path = path
        self.model_params = model_params

        self.word2idx, self.idx2word = build_vocab(self.path)
        self.vocab_size = len(self.word2idx)

        self.enqueue_data, self.source, self.target, self.sequence_length = \
            prepare_data(self.path, self.word2idx)

        with tf.variable_scope("generator"):
            # TODO: rename
            g_tensors = generator(self.source, self.target, self.sequence_length, self.vocab_size)
            self.flat_logits, self.probs, self.loss, self.cost = g_tensors

        optim = tf.train.AdamOptimizer(learning_rate=0.005)
        self.train_op = optim.minimize(self.cost)

        d_tensors = discriminator()

def prepare_data(path, word2idx, batch_size=32):
    with tf.device("/cpu:0"):
        enqueue_data, dequeue_batch = get_and_run_input_queues(path, word2idx, batch_size=batch_size)
        source, target, sequence_length = preprocess(dequeue_batch)
    return enqueue_data, source, target, sequence_length

def generator(source, target, sequence_length, vocab_size):
    flat_logits = (
        source >>
        embedding_layer(vocab_size, HIDDEN_DIMS) >>
        recurrent_layer(sequence_length=sequence_length) >>
        reshape_layer(shape=(-1, HIDDEN_DIMS)) >>
        dense_layer(hidden_dims=vocab_size)
    )

    probs = flat_logits >> softmax_layer() >> reshape_layer(shape=tf.shape(target))

    loss = (
        flat_logits >>
        cross_entropy_layer(target=target) >>
        reshape_layer(shape=tf.shape(target)) >>
        mean_loss_by_example_layer(sequence_length=sequence_length)
    )

    cost = tf.reduce_mean(loss)
    return flat_logits, probs, loss, cost

def discriminator():
    pass

if __name__ == "__main__":
    from data_loader import DATA_PATH
    path = DATA_PATH["ptb"]["train"]

    model = Model(path)<commit_msg>added discriminator<commit_after>""" Text GAN

Adverserial networks applied to language models using Gumbel Softmax.

Can be used as pure language model.
"""
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

from collections import namedtuple

import tensorflow as tf

# -- local imports
from data_loader import build_vocab, preprocess, get_and_run_input_queues
from layers import (
    embedding_layer, recurrent_layer, reshape_layer, dense_layer, softmax_layer,
    cross_entropy_layer, sigmoid_cross_entropy_layer, mean_loss_by_example_layer, dropout_layer, relu_layer,
)

# TODO: add to flags
HIDDEN_DIMS = 128

GeneratorTuple = namedtuple("Generator",
    ["rnn_outputs", "flat_logits", "probs", "loss"])
DiscriminatorTuple = namedtuple("Discriminator",
    ["rnn_final_state", "prediction_logits", "loss"])

class Model:
    def __init__(self, path, **model_params):
        self.path = path
        self.model_params = model_params

        self.word2idx, self.idx2word = build_vocab(self.path)
        self.vocab_size = len(self.word2idx)

        self.enqueue_data, self.source, self.target, self.sequence_length = \
            prepare_data(self.path, self.word2idx)

        self.generator_template = tf.make_template("generator", generator)
        self.discriminator_template = tf.make_template("discriminator", discriminator)

        self.g_tensors = self.generator_template(self.source, self.target, self.sequence_length, self.vocab_size, is_pretrain=True)
        self.d_tensors = self.discriminator_template(self.g_tensors[0], self.sequence_length, self.vocab_size, is_real=True)

def prepare_data(path, word2idx, batch_size=32):
    with tf.device("/cpu:0"):
        enqueue_data, dequeue_batch = get_and_run_input_queues(path, word2idx, batch_size=batch_size)
        source, target, sequence_length = preprocess(dequeue_batch)
    return enqueue_data, source, target, sequence_length

def prepare_decoder():
    from decoders import gumbel_output_fn

    pass

# TODO: generalize model_params
def generator(source, target, sequence_length, vocab_size, is_pretrain=True):
    rnn_outputs = (
        source >>
        embedding_layer(vocab_size, HIDDEN_DIMS, name="embedding_matrix") >>
        recurrent_layer(sequence_length=sequence_length)
    )

    flat_logits = (
        rnn_outputs >>
        reshape_layer(shape=(-1, HIDDEN_DIMS)) >>
        dense_layer(hidden_dims=vocab_size, name="output_projections")
    )

    probs = flat_logits >> softmax_layer() >> reshape_layer(shape=tf.shape(target))

    loss = (
        flat_logits >>
        cross_entropy_layer(target=target) >>
        reshape_layer(shape=tf.shape(target)) >>
        mean_loss_by_example_layer(sequence_length=sequence_length)
    )

    return GeneratorTuple(rnn_outputs=rnn_outputs, flat_logits=flat_logits, probs=probs, loss=loss)

def discriminator(input_vectors, sequence_length, vocab_size, is_real=True):
    """
    Args:
    """
    rnn_final_state = (
        input_vectors >>
        dense_layer(hidden_dims=HIDDEN_DIMS) >>  # projection layer keep shape [B, T, H]
        recurrent_layer(sequence_length=sequence_length, return_final_state=True)
    )

    prediction_logits = (
        rnn_final_state >>
        dense_layer(hidden_dims=HIDDEN_DIMS) >>
        relu_layer() >>
        dropout_layer() >>
        dense_layer(hidden_dims=HIDDEN_DIMS) >>
        relu_layer() >>
        dropout_layer() >>
        dense_layer(hidden_dims=1)
    )

    target = tf.zeros(shape=tf.shape(prediction_logits), dtype=tf.float32)
    target += 1.0 if is_real else 0.0

    loss = (
        prediction_logits >>
        sigmoid_cross_entropy_layer(target=target)
    )

    return DiscriminatorTuple(rnn_final_state=rnn_final_state, prediction_logits=prediction_logits, loss=loss)

if __name__ == "__main__":
    from data_loader import DATA_PATH
    path = DATA_PATH["ptb"]["train"]

    model = Model(path)<|endoftext|>


<commit_before># import functions
from random import randint
from math import ceil

# define game-play functions
def printWelcome():
    print("###################################################################")
    print("#####                Welcome to Battleships!                  #####")
    print("###################################################################")

def playerChooseBoardSize(): # player chooses the size of the square board (i.e. the number of rows)
    global nRows, nCols, rangeRow, rangeCol
    print("\nHow big do you want the square board to be?\n")
    while True:
        nRows = int(input("Choose the number of rows (3 - 9):"))
        if nRows >= 3 and nRows <= 9:
            break
    nCols = nRows
    rangeRow = range(nRows)
    rangeCol = range(nCols)

def createBoards(): # creates two boards (one visible and the other invisible to the player)
    global boardVisib, boardInvis
    boardVisib = []
    for x in rangeRow:
        boardVisib.append(["#"] * nCols)
    boardInvis = []
    for x in rangeRow:
        boardInvis.append(["#"] * nCols)

def calculateNumberOfShips(): # calculate the number of battleships
    global nShips, nShipsLeft
    nShips = ceil(nRows * nCols / 8)
    nShipsLeft = ceil(nRows * nCols / 8)

def calculateNumberOfTurns():
    global nTurns, currentTurn
    nFields = nRows * nCols
    nTurns = ceil(((nShips / (nFields - 1)) ** 0.5) * nFields * (10 + nRows) / 10)
    currentTurn = 1

def placeShipsOnBoardInvis():
    global rangeRow, rangeCol, boardInvis
    def randomFromRange(range):
        return randint(0, len(range) - 1)
    for ship in range(nShips):
        shipRow = randomFromRange(rangeRow)
        shipCol = randomFromRange(rangeCol)
        while boardInvis[shipRow][shipCol] == "X" or boardInvis[shipRow][shipCol] == "%":
            shipRow = randomFromRange(rangeRow)
            shipCol = randomFromRange(rangeCol)
        boardInvis[shipRow][shipCol] = "X"
        shipSpacing(board = boardInvis, row = shipRow, col = shipCol, symbol = "%")

def printBeginGame():
    printTitle("   Let's play!   ")
    print("You have %s turns." % (nTurns))
    print("There are %s ships.\n" % (nShips))
    printBoard(boardVisib)

def printTurn():
    printTitle(title = (" Turn %s out of %s " % (currentTurn, nTurns)))

def playerGuess():
    global guessRow
    guessRow = -1
    global guessCol
    guessCol = -1
    while guessRow not in rangeRow:
        guessRow = int(input("Guess Row (1 - %s):" % (nRows))) - 1
    while guessCol not in rangeCol:
        guessCol = int(input("Guess Col (1 - %s):" % (nCols))) - 1

def checkGuessedAlready():
    global guessedAlready
    if (boardVisib[guessRow][guessCol] == "O") or (boardVisib[guessRow][guessCol] == "X"):
        guessedAlready = True
        print("\nYou guessed that one already.")
    else:
        guessedAlready = False

def checkHitOrMiss():
    if (boardInvis[guessRow][guessCol] == "X"): # Hit
        global nShipsLeft
        nShipsLeft -= 1
        if nShipsLeft > 0:
            print("\nYou sank one of my battleships!")
        editBoards(trigger = 'Hit')
    else:
        print("\nYou missed my battleships!")
        editBoards(trigger = 'Miss')

def calculateNextTurnNumber():
    global currentTurn
    currentTurn += 1

def checkWinOrLose(): # Have all ships been sunken?
    if nShipsLeft > 0: # Lose
        printTitle("    GAME OVER    ")
        if nShipsLeft == 1:
            print("\nThere is one survivor:")
        else:
            print("\nThere are a few survivors:")
        editBoards(trigger = 'GameOver') # edit the invisible board before showing it to the player
        printBoard(boardInvis)
    elif nShipsLeft == 0: # Win
        printTitle("     YOU WON!     ")
        print("Congratulations! You sank all of my battleships!\n\n")

# define helper functions

def printTitle(title):
    print("\n>>>>>>>>>>>>>>>>", title, "<<<<<<<<<<<<<<<<")

def printBoard(board):
    print("~~~~~~~~~~~~~~~~~~~~~~~~~~")
    for row in board:
        print(" ".join(row))
    print("~~~~~~~~~~~~~~~~~~~~~~~~~~")

def shipSpacing(board, row, col, symbol): # inserts a "symbol" in all fields that boarder the ship (located with "row" and "col")
    shipSpace = [[-1, 0, 1, 1, 1, 0, -1, -1], [1, 1, 1, 0, -1, -1, -1, 0]]
    for i in range(8):
        shipSpace[0][i] = row + shipSpace[0][i]
        shipSpace[1][i] = col + shipSpace[1][i]
    for i in range(8):
        if (shipSpace[0][i] in rangeRow) and (shipSpace[1][i] in rangeCol):
            board[shipSpace[0][i]][shipSpace[1][i]] = symbol

def editBoards(trigger):
    if trigger == 'Hit':
        boardVisib[guessRow][guessCol] = "X"
        boardInvis[guessRow][guessCol] = "O"
        # Uncover the fields on the visible board that boarder the sunken ship
        shipSpacing(board = boardVisib, row = guessRow, col = guessCol, symbol = "O")
    elif trigger == 'Miss':
        boardVisib[guessRow][guessCol] = "O"
        boardInvis[guessRow][guessCol] = "O"
    elif trigger == 'GameOver':
        for row in rangeRow:
            for col in rangeCol:
                if boardInvis[row][col] == "%" or boardInvis[row][col] == "#":
                    boardInvis[row][col] = "O"

############################## GAME EXECUTION #################################
printWelcome()
playerChooseBoardSize()
createBoards()
calculateNumberOfShips()
calculateNumberOfTurns()
placeShipsOnBoardInvis()
printBeginGame()

    # loop through the turns
while currentTurn <= nTurns and nShipsLeft > 0:
    printTurn()
    while True:
        playerGuess()
        checkGuessedAlready()
        if not guessedAlready:
            break
    checkHitOrMiss()
    printBoard(boardVisib)
    calculateNextTurnNumber()

checkWinOrLose()
<commit_msg>Change how functions are named & implement player_wants_to_play_again.<commit_after># import functions
from random import randint
from math import ceil

# define game-play functions
def print_welcome():
    print("\n\n\n\n")
    print("###################################################################")
    print("#####                 Welcome to Battleships!                 #####")
    print("###################################################################")
    print("""\nYou stumble upon a perfectly square ocean. """)

def player_chooses_board_size(): # player chooses the size of the square board (i.e. the number of rows)
    global nRows, nCols, rangeRow, rangeCol
    print("""\nIn this game you have to try to sink all of my battleships.
My ships are hidden in a perfectly square ocean.
How long do you want one side of this ocean to be?\n""")
    while True:
        nRows = int(input("\tChoose a number (3 - 9):"))
        if nRows >= 3 and nRows <= 9:
            break
    nCols = nRows
    rangeRow = range(nRows)
    rangeCol = range(nCols)

def create_boards(): # creates two boards (one visible and the other invisible to the player)
    global boardVisib, boardInvis
    boardVisib = []
    for x in rangeRow:
        boardVisib.append(["#"] * nCols)
    boardInvis = []
    for x in rangeRow:
        boardInvis.append(["#"] * nCols)

def calculate_size_of_board(): # calculate the number of battleships
    global nShips, nShipsLeft
    nShips = ceil(nRows * nCols / 8)
    nShipsLeft = ceil(nRows * nCols / 8)

def calculate_number_of_turns():
    global nTurns, currentTurn
    nFields = nRows * nCols
    nTurns = ceil(((nShips / (nFields - 1)) ** 0.5) * nFields * (10 + nRows) / 10)
    currentTurn = 1

def place_ships_on_board_invis():
    global rangeRow, rangeCol, boardInvis
    def randomFromRange(range):
        return randint(0, len(range) - 1)
    for ship in range(nShips):
        shipRow = randomFromRange(rangeRow)
        shipCol = randomFromRange(rangeCol)
        while boardInvis[shipRow][shipCol] == "X" or boardInvis[shipRow][shipCol] == "%":
            shipRow = randomFromRange(rangeRow)
            shipCol = randomFromRange(rangeCol)
        boardInvis[shipRow][shipCol] = "X"
        add_space_around_ships(board = boardInvis, row = shipRow, col = shipCol, symbol = "%")

def print_begin_game():
    print_title("   Let's play!   ")
    print("You have %s turns." % (nTurns))
    print("There are %s ships hiding in the ocean.\n" % (nShips))
    print_board(boardVisib)

def print_turn():
    print_title(title = (" Turn %s out of %s " % (currentTurn, nTurns)))

def player_guesses():
    global guessRow
    guessRow = -1
    global guessCol
    guessCol = -1
    while guessRow not in rangeRow:
        guessRow = int(input("\tGuess Row (1 - %s):" % (nRows))) - 1
    while guessCol not in rangeCol:
        guessCol = int(input("\tGuess Col (1 - %s):" % (nCols))) - 1

def check_guessed_already():
    global guessedAlready
    if (boardVisib[guessRow][guessCol] == "O") or (boardVisib[guessRow][guessCol] == "X"):
        guessedAlready = True
        print("\nYou guessed that one already.")
    else:
        guessedAlready = False

def check_hit_or_miss():
    if (boardInvis[guessRow][guessCol] == "X"): # Hit
        global nShipsLeft
        nShipsLeft -= 1
        if nShipsLeft > 0:
            print("\nYou sank one of my battleships!")
        edit_boards(trigger = 'Hit')
    else:
        print("\nYou missed my battleships!")
        edit_boards(trigger = 'Miss')

def calculate_next_turn_number():
    global currentTurn
    currentTurn += 1

def check_win_or_lose(): # Have all ships been sunken?
    if nShipsLeft > 0: # Lose
        print_title("    GAME OVER    ")
        if nShipsLeft == 1:
            print("\nThere is one survivor:")
        else:
            print("\nThere are a few survivors:")
        edit_boards(trigger = 'GameOver') # edit the invisible board before showing it to the player
        print_board(boardInvis)
    elif nShipsLeft == 0: # Win
        print_title("     YOU WON!     ")
        print("Congratulations! You sank all of my battleships!\n\n")

def player_wants_to_play_again():
    while True:
        playerInput = input("\tDo you want to play again? (yes or no?):").lower()
        if playerInput == "yes" or playerInput == "y":
            return True
            break
        elif playerInput == "no" or playerInput == "n":
            return False
            break

# define helper functions

def print_title(title):
    print("\n>>>>>>>>>>>>>>>>", title, "<<<<<<<<<<<<<<<<")

def print_board(board):
    print("~~~~~~~~~~~~~~~~~~~~~~~~~~")
    for row in board:
        print(" ".join(row))
    print("~~~~~~~~~~~~~~~~~~~~~~~~~~")

def add_space_around_ships(board, row, col, symbol): # inserts a "symbol" in all fields that boarder the ship (located with "row" and "col")
    shipSpace = [[-1, 0, 1, 1, 1, 0, -1, -1], [1, 1, 1, 0, -1, -1, -1, 0]]
    for i in range(8):
        shipSpace[0][i] = row + shipSpace[0][i]
        shipSpace[1][i] = col + shipSpace[1][i]
    for i in range(8):
        if (shipSpace[0][i] in rangeRow) and (shipSpace[1][i] in rangeCol):
            board[shipSpace[0][i]][shipSpace[1][i]] = symbol

def edit_boards(trigger):
    if trigger == 'Hit':
        boardVisib[guessRow][guessCol] = "X"
        boardInvis[guessRow][guessCol] = "O"
        # Uncover the fields on the visible board that boarder the sunken ship
        add_space_around_ships(board = boardVisib, row = guessRow, col = guessCol, symbol = "O")
    elif trigger == 'Miss':
        boardVisib[guessRow][guessCol] = "O"
        boardInvis[guessRow][guessCol] = "O"
    elif trigger == 'GameOver':
        for row in rangeRow:
            for col in rangeCol:
                if boardInvis[row][col] == "%" or boardInvis[row][col] == "#":
                    boardInvis[row][col] = "O"
# define the game

def runGame():
    print_welcome()
    player_chooses_board_size()
    create_boards()
    calculate_size_of_board()
    calculate_number_of_turns()
    place_ships_on_board_invis()
    print_begin_game()

        # loop through the turns
    while currentTurn <= nTurns and nShipsLeft > 0:
        print_turn()
        while True:
            player_guesses()
            check_guessed_already()
            if not guessedAlready:
                break
        check_hit_or_miss()
        print_board(boardVisib)
        calculate_next_turn_number()

    check_win_or_lose()

############################## GAME EXECUTION #################################
while True:
    runGame()
    playAgain = player_wants_to_play_again()
    if playAgain == False:
        break
<|endoftext|>


<commit_before>import bluebox, fec
import config, parser
import threading
import argparse
from datetime import datetime

class bb_frontend(threading.Thread):

    DEFAULT_FREQUENCY = 437425000
    DEFAULT_MODINDEX = 1
    DEFAULT_BITRATE = 2400
    DEFAULT_POWER = 26
    DEFAULT_TRAINING = 200
    DEFAUL_SYNCWORD = "4f5a34" # OZ4
    LOGFILE = "log.txt"

    def __init__(self, conf, enable_tracking=False):
        self.conf = conf
        self.enable_tracking = enable_tracking
        self.bluebox = bluebox.Bluebox()
        self.parser = parser.Parser()

        if(self.enable_tracking):
            self.tracker = tracker.Tracker(qth, tle)

    def run(self):
        if self.enable_tracking:
            self.__run_pass__()
        else:
            self.__receive_mode__()
            # Update config if updated
            # An observer might be more useful
            #config = self.config.get_config()
            #self.set_config(config)

    def __run_pass__(self):
        while self.tracker.in_range():
            pass

    def __receive_mode__(self):
        while True:
            try:
                data, rssi, freq = self.bluebox.receive(1000)
                if data:
                    print("\n" + "#="*40 + "#\n")
                    print("Received packet {}".format(datetime.now().isoformat(' ')))
                    print("{}\n".format(data))

                    # Parse data
                    try:
                        beacon_str = self.parser.parse_data(data)
                    except Exception as e:
                        print e
                    else:
                        print beacon_str
                        # TODO: Report
            except Exception as e:
                print e

if __name__ == '__main__':
    args_parser = argparse.ArgumentParser(description='AAUSAT4 Beacon Parser')
    args_parser.add_argument('--lat', dest='lat', required=False, type=float, default=None,
                            help='Latitude of ground station (N), e.g. 55.6167')
    args_parser.add_argument('--lon', dest='lon', required=False, type=float, default=None,
                            help='Longitude of ground station (W), e.g. -12.6500')
    args_parser.add_argument('--alt', dest='alt', required=False, type=float, default=None,
                            help='Altitude of ground station (meters), e.g. 10')
    args_parser.add_argument('--disable-doppler', dest='enable_doppler',
                             action='store_false',
                             required=False,
                             help='Disables doppler tracking.')
    args_parser.add_argument('--enable-reporting', dest='enable_reporting',
                             action='store_true',
                             required=False,
                             help='Enables automatic reporting of received packets.')

    args = args_parser.parse_args()

    if (not args.enable_doppler) or (args.lat and args.lon and args.alt):
        # Start parser
        qth = None
        if args.enable_doppler:
            qth = (args.lat, args.lon, args.alt)
        config = config.Config()
        bb_frontend(None).run()

    else:
        args_parser.print_help()
        exit(1)
<commit_msg>initial tracking mode for bb_frontend<commit_after>import bluebox, fec
import config, parser, tracker
import threading
import argparse
import time
from datetime import datetime

class bb_frontend(threading.Thread):

    DEFAULT_FREQUENCY = 437425000
    DEFAULT_MODINDEX = 1
    DEFAULT_BITRATE = 2400
    DEFAULT_POWER = 26
    DEFAULT_TRAINING = 200
    DEFAUL_SYNCWORD = "4f5a34" # OZ4
    LOGFILE = "log.txt"

    def __init__(self, qth, conf, enable_tracking=True):
        self.conf = conf
        self.enable_tracking = enable_tracking
        self.bluebox = bluebox.Bluebox()
        self.parser = parser.Parser()

        tle = """AAUSAT3
1 39087U 13009B   16115.43831429  .00000233  00000-0  96510-4 0  9991
2 39087  98.5853 317.5656 0013674 101.2177 259.0548 14.35339547165447"""

        if(self.enable_tracking):
            self.tracker = tracker.Tracker(qth, tle)

    def run(self):
        if self.enable_tracking:
            self.__run_pass__()
        else:
            self.__receive_mode__()
            # Update config if updated
            # An observer might be more useful
            #config = self.config.get_config()
            #self.set_config(config)

    def __run_pass__(self):
        while True:
            while self.tracker.in_range():
                freq = bb_frontend.DEFAULT_FREQUENCY + self.tracker.get_doppler()
                print "Doppler freq:", freq
                self.bluebox.set_frequency(freq)
                data, rssi, freq = self.bluebox.receive(5000)
                if data:
                    # Parse data
                    beacon_str = self.parser.parse_data(data)
                    print beacon_str

            next_pass, duration, max_elvation = self.tracker.next_pass()
            print """Next pass: {0}
Duration: {1:.0f} minutes
Max elevation: {2:.2f} degrees""".format(datetime.fromtimestamp(next_pass), duration / 60, max_elvation)
            time.sleep(next_pass-time.time())

    def __receive_mode__(self):
        while True:
            try:
                data, rssi, freq = self.bluebox.receive(1000)
                if data:
                    print("\n" + "#="*40 + "#\n")
                    print("Received packet {}".format(datetime.now().isoformat(' ')))
                    print("{}\n".format(data))

                    # Parse data
                    try:
                        beacon_str = self.parser.parse_data(data)
                    except Exception as e:
                        print e
                    else:
                        print beacon_str
                        # TODO: Report
            except Exception as e:
                print e

if __name__ == '__main__':
    bb = bb_frontend((55.6167, -12.6500, 5), None)
    bb.run()
    # args_parser = argparse.ArgumentParser(description='AAUSAT4 Beacon Parser')
    # args_parser.add_argument('--lat', dest='lat', required=False, type=float, default=None,
    #                         help='Latitude of ground station (N), e.g. 55.6167')
    # args_parser.add_argument('--lon', dest='lon', required=False, type=float, default=None,
    #                         help='Longitude of ground station (W), e.g. -12.6500')
    # args_parser.add_argument('--alt', dest='alt', required=False, type=float, default=None,
    #                         help='Altitude of ground station (meters), e.g. 10')
    # args_parser.add_argument('--disable-doppler', dest='enable_doppler',
    #                          action='store_false',
    #                          required=False,
    #                          help='Disables doppler tracking.')
    # args_parser.add_argument('--enable-reporting', dest='enable_reporting',
    #                          action='store_true',
    #                          required=False,
    #                          help='Enables automatic reporting of received packets.')

    # args = args_parser.parse_args()

    # if (not args.enable_doppler) or (args.lat and args.lon and args.alt):
    #     # Start parser
    #     qth = None
    #     if args.enable_doppler:
    #         qth = (args.lat, args.lon, args.alt)
    #     config = config.Config()
    #     bb_frontend(None).run()

    # else:
    #     args_parser.print_help()
    #     exit(1)
<|endoftext|>