# Python Project B
#   Multinomial Naive Bayes
# By
#   Valdar Rudman
#   R00081134

from nltk.corpus import stopwords
from nltk.tokenize import word_tokenize
import matplotlib.pyplot as plt
import numpy as np

# Read a file in and split on the white space
def readFile(source):
    return open(source).read().split()

# Read a file in and split on new line
def readTweetsFile(source):
    return open(source).read().lower().split("\n")

# Gets the probability of the word. This can be the probability
# of a word being positive or negative
def prob_of_word(percentDict, fullDict):
    words = {}

    for word in percentDict:
        words[word] = (percentDict[word] / fullDict[word])
    return words

# Takes a list of words in and returns list without stopwords
def removeStopWords(sentence):

    stopWords = set(stopwords.words('english'))
    words = word_tokenize(sentence)
    wordsFiltered = []

    for w in words:
        if w not in stopWords:
            wordsFiltered.append(w)

    return wordsFiltered

# Working out if tweets are positive or negative
def posNegTweets(tweets, wordsPos, wordsNeg):
    posTweets, negTweets, uknownTweets = 0, 0, 0
    for tweet in tweets:
        words = tweet.split()
        posWords, negWords, uknownWord, count = 0, 0, 0, 1
        for word in words:
            if word in wordsPos:
                posWords += wordsPos[word]
            if word in wordsNeg:
                negWords += wordsNeg[word]
            count += 1
        posWords = posWords / count
        negWords = negWords / count

        if posWords > negWords:
            posTweets += 1
        elif negWords > posWords:
            negTweets += 1
        else:
            uknownTweets += 1
    # Returns a list [percent of positive tweets in the batch, percent of negative tweets in the batch, percent of unkown tweets in the batch]
    return [((posTweets / len(tweets)) * 100), ((negTweets / len(tweets)) * 100), ((uknownTweets / len(tweets)) * 100)]

# Graph the before and after results of pre-processing for both negative and positive
def graph(PositiveBeforePP, positiveAfterPP, negativeBeforePP, negativeAfterPP):
    BarTitles = ('Pos Before Pre-Processing',
                 'Pos After Pre-Processing',
                 'Neg before Pre-Processing',
                 'Neg After Pre-Processing')
    plot = [PositiveBeforePP, positiveAfterPP,
            negativeBeforePP, negativeAfterPP]
    y_pos = np.arange(len(BarTitles))
    plt.bar(y_pos, plot, align='center', alpha=0.1)
    plt.xticks(y_pos, BarTitles)
    plt.ylabel("Percentage")
    plt.xlabel("Data")
    plt.title("Tweets Accuracy")
    plt.show()

def main():
    print("Reading in Training Files...")
    posList = readFile("train\\trainPos.txt")
    negList = readFile("train\\trainNeg.txt")

    posList = [item.lower() for item in posList]
    negList = [item.lower() for item in negList]

    print("Removing stopwords from training files...")
    # print(negList)
    posList = removeStopWords(' '.join(posList))
    negList = removeStopWords(' '.join(negList))

    # Getting unique words for positive and negative as well as getting a full set of them
    posSet = set(posList)
    negSet = set(negList)
    fullSet = posSet|negSet

    print("Creating dictionaries...")
    # Creating dictionaries to use to keep count of how many times a word show up
    posDict = dict.fromkeys(posSet, 0)
    negDict = dict.fromkeys(negSet, 0)
    fullDict = dict.fromkeys(fullSet, 0)

    for word in posList:
        posDict[word] = posDict[word] + 1
        fullDict[word] = fullDict[word] + 1

    for word in negList:
        negDict[word] = negDict[word] + 1
        fullDict[word] = fullDict[word] + 1

    # print("Negative: ", negDict)
    # print("Full: ", fullDict)

    print("Calculate words pos/neg value...")
    wordsPos = prob_of_word(posDict, fullDict)
    wordsNeg = prob_of_word(negDict, fullDict)

    print("Reading in Pos Tweets and removing stopwords...")
    posTweets = readTweetsFile("test\\testPos.txt")
    posTweetsCleanedUp = []
    for tweet in posTweets:
        tweet.lower()
        posTweetsCleanedUp.append(' '.join(removeStopWords(tweet)))

    print("Reading in Neg Tweets and removing stopwords...")
    negTweets = readTweetsFile("test\\testNeg.txt")
    negTweetsCleanedUp = []
    for tweet in negTweets:
        tweet.lower()
        negTweetsCleanedUp.append(' '.join(removeStopWords(tweet)))

    print("Calculating Pre results...")
    posPreResults = posNegTweets(posTweets, wordsPos, wordsNeg)
    negPreResults = posNegTweets(negTweets, wordsPos, wordsNeg)
    print("Pre Results\nPositive: ", posPreResults, "\nNegative: ", negPreResults)

    print("Calculating Post results...")
    posPostResults = posNegTweets(posTweetsCleanedUp, wordsPos, wordsNeg)
    negPostResults = posNegTweets(negTweetsCleanedUp, wordsPos, wordsNeg)
    print("Post Results\nPositive: ", posPostResults, "\nNegative: ", negPostResults)

    graph(posPreResults[0], posPostResults[0], negPreResults[1], negPostResults[1])

if __name__ == '__main__':
    main()


import abc

from neutron import quota
from neutron.api import extensions
from neutron.api.v2 import attributes as attr
from neutron.api.v2 import resource_helper
from neutron.common import exceptions as qexception
from neutron.plugins.common import constants

UOS_SERVICE_PROVIDER = 'uos:service_provider'
UOS_NAME = 'uos:name'
UOS_REGISTERNO = 'uos:registerno'
UOS_PORT_DEVICE_NAME = 'uos:port_device_name'
UOS_PORT_DEVICE_OWNER = 'uos:port_device_owner'
UOS_PORT_DEVICE_ID = 'uos:port_device_id'
UOS_RATE_LIMIT = 'rate_limit'
RESOURCE_ATTRIBUTE_MAP = {
    'floatingipsets': {
        'id': {'allow_post': False, 'allow_put': False,
               'validate': {'type:uuid': None},
               'is_visible': True,
               'primary_key': True},
        'floatingipset_address': {'allow_post': False, 'allow_put': False,
                                'convert_to': attr._validate_dict_or_none,
                                'is_visible': True, 'required_by_policy': True,
                                'enforce_policy': True, 'default': list()},
        'floatingipset_subnet_id': {'allow_post': True, 'allow_put': False,
                               'convert_to': attr.convert_to_list,
                               'validate': {'type:uuid_list': None},
                               'is_visible': True,
                               'default': None},
        'floatingipset_network_id': {'allow_post': True, 'allow_put': False,
                                'validate': {'type:uuid': None},
                                'is_visible': True},
        'router_id': {'allow_post': False, 'allow_put': False,
                      'validate': {'type:uuid_or_none': None},
                      'is_visible': True, 'default': None},
        'port_id': {'allow_post': True, 'allow_put': True,
                    'validate': {'type:uuid_or_none': None},
                    'is_visible': True, 'default': None,
                    'required_by_policy': True},
        'fixed_ip_address': {'allow_post': True, 'allow_put': True,
                             'validate': {'type:ip_address_or_none': None},
                             'is_visible': True, 'default': None},
        'tenant_id': {'allow_post': True, 'allow_put': False,
                      'required_by_policy': True,
                      'validate': {'type:string': None},
                      'is_visible': True},
        'status': {'allow_post': False, 'allow_put': False,
                   'is_visible': True},
        UOS_NAME: {'allow_post': True, 'allow_put': False,
                   'validate': {'type:string': None},
                   'is_visible': True, 'default': ''},
        UOS_REGISTERNO: {'allow_post': True, 'allow_put': False,
                         'validate': {'type:string': None},
                         'is_visible': True, 'default': ''},
        UOS_SERVICE_PROVIDER: {'allow_post': True, 'allow_put': False,
                         'convert_to': attr.convert_to_list,
                         'is_visible': True, 'default': ''},
        UOS_PORT_DEVICE_NAME: {'allow_post': False, 'allow_put': False,
                               'validate': {'type:string': None},
                               'is_visible': True, 'default': ''},
        UOS_PORT_DEVICE_OWNER: {'allow_post': False, 'allow_put': False,
                                'validate': {'type:string': None},
                                'is_visible': True, 'default': ''},
        UOS_PORT_DEVICE_ID: {'allow_post': False, 'allow_put': False,
                             'validate': {'type:string': None},
                             'is_visible': True, 'default': ''},
        UOS_RATE_LIMIT: {'allow_post': True, 'allow_put': False,
                     'convert_to': attr.convert_to_int,
                     'validate': {'type:fip_rate_limit': None},
                     'is_visible': True, 'default': 1024}

    }
}

class ServiceProviderNotExist(qexception.BadRequest):
    message = _("the service provider %(service_provider)s is not exists")

class InputServieProviderNull(qexception.BadRequest):
    message = _("the service provider could not be found")

class FloatingipsLenTooLong(qexception.BadRequest):
    message = _("In the floatingipset, the num of floatingip must be only one")

class FloatingIPSetNotFound(qexception.NotFound):
    message = _("Floating IP Set %(floatingipset_id)s could not be found")

class Uosfloatingipset(extensions.ExtensionDescriptor):

    @classmethod
    def get_name(cls):
        return "UnitedStack Floatingipset"

    @classmethod
    def get_alias(cls):
        return "uos_floatingipsets"

    @classmethod
    def get_description(cls):
        return ("Return related resources")

    @classmethod
    def get_namespace(cls):
        return "http://docs.openstack.org/ext/neutron/uos/api/v1.0"

    @classmethod
    def get_updated(cls):
        return "2013-12-25T10:00:00-00:00"

    @classmethod
    def get_resources(cls):
        """Returns uos floatingipset Resources."""
        return []

    @classmethod
    def get_resources(cls):
        """Returns floatingipset Resources."""
        plural_mappings = resource_helper.build_plural_mappings(
            {}, RESOURCE_ATTRIBUTE_MAP)
        attr.PLURALS.update(plural_mappings)
        #quota.QUOTAS.register_resource_by_name('floatingset')
        return resource_helper.build_resource_info(plural_mappings,
                                                   RESOURCE_ATTRIBUTE_MAP,
                                                   constants.L3_ROUTER_NAT,
                                                   register_quota=True)

    def update_attributes_map(self, attributes):
        super(Uosfloatingipset, self).update_attributes_map(
            attributes, extension_attrs_map=RESOURCE_ATTRIBUTE_MAP)

    def get_extended_resources(self, version):
        if version == "2.0":
            return RESOURCE_ATTRIBUTE_MAP
        else:
            return {}

class FloatingipsetBase(object):

    @abc.abstractmethod
    def create_floatingipset(self, context, floatingipset):
        pass

    @abc.abstractmethod
    def update_floatingipset(self, context, id, floatingipset):
        pass

    @abc.abstractmethod
    def get_floatingipset(self, context, id, fields=None):
        pass

    @abc.abstractmethod
    def delete_floatingipset(self, context, id):
        pass

    @abc.abstractmethod
    def get_floatingipsets(self, context, filters=None, fields=None,
                        sorts=None, limit=None, marker=None,
                        page_reverse=False):
        pass

    def get_floatingipsets_count(self, context, filters=None):
        pass