from bs4 import BeautifulSoup  # For processing XMLfrom BeautifulSoup
import pandas as pd
import matplotlib
import matplotlib.pyplot as plt
%matplotlib inline
import itertools
from math import floor
matplotlib.style.use('ggplot')
import numpy as np

"""
Explanation: Interpretive Tag Statistics for Katherine Mansfield's "The Garden Party"
First, let's get all the necessary programming libraries that will allow us to do these computations.
End of explanation
"""


doc = open('garden-party.xml').read()
soup = BeautifulSoup(doc, 'lxml')

"""
Explanation: Next, let's read the XML file of the short story.
End of explanation
"""


interps = soup.findAll('interp')

"""
Explanation: Read all the critical remarks.
End of explanation
"""


def getTags(interp): 
    descs = interp.findAll('desc')
    descList = []
    for desc in descs: 
        descList.append(desc.string)
    return descList

def getAllTags(interps):
    allTags = []
    for interp in interps: 
        tags = getTags(interp)
        for tag in tags: 
            allTags.append(tag)
    return allTags

"""
Explanation: These functions will extract the tags from the critical remarks.
End of explanation
"""


def dedupe(seq):
    seen = set()
    seen_add = seen.add
    return [x for x in seq if not (x in seen or seen_add(x))]
allTags = dedupe(getAllTags(interps))
print(str(allTags))
len(allTags)

"""
Explanation: Create a de-duplicated list of tags represented.
End of explanation
"""


tagDict = {}
for interp in interps: 
    number = int(interp.attrs['n'])
    tags = getTags(interp)
    tagDict[number] = tags

"""
Explanation: Create a table of all the tags, and where they occur according to lexia.
End of explanation
"""


def checkTags(tag):
    hasTags = []
    for n in tagDict: 
        if tag in tagDict[n]: 
            hasTags.append(1)
        else: 
            hasTags.append(0)
    return hasTags

"""
Explanation: Create a function for checking whether a tag is associated with a certain lexia.
End of explanation
"""


hasTagMatrix = {}
for tag in allTags: 
    hasTagMatrix[tag] = checkTags(tag)
df = pd.DataFrame(hasTagMatrix)

df.head()

"""
Explanation: Assemble a matrix of all tags, and whether they occur in certain lexia. Turn this into a data frame.
End of explanation
"""


s = df.sum(axis='rows').sort_values(ascending=False)
mostFrequentTags = s[s>3]

mft = mostFrequentTags.plot(kind='bar', alpha=0.5, figsize=(10,5))
mft.set_xlabel('tag')
mft.set_ylabel('number of occurrences')
fig = mft.get_figure()
fig.tight_layout()
fig.savefig('images/mtf.png') # save it to a file

"""
Explanation: While we're at it, let's find the most frequent tags.
End of explanation
"""


chunkSize=5
def chunkdf(df, chunkSize): 
    groups = df.groupby(lambda x: floor(x/chunkSize)).sum()
    return groups
groups = chunkdf(df, chunkSize)

"""
Explanation: Group lexia by 10s, so the data are more meaningful than ones and zeroes.
End of explanation
"""


party = [145, 150] # These are the lexia where the party occurs. Let's draw dotted lines there.
partyAdjusted = [x/chunkSize for x in party]
def plotTags(tags, thisdf=groups): 
    plot = thisdf[tags].plot(kind='area', alpha=0.5, figsize=(10,5))
    ymax = plot.get_ylim()[1]
    plot.axvspan(partyAdjusted[0], partyAdjusted[1], facecolor="0.65", alpha=0.5)
    plot.text(partyAdjusted[0]+0.2,ymax/2,'party',rotation=90)
    plot.set_xlabel('lexia number / ' + str(chunkSize))
    plot.set_ylabel('number of occurrences')
    fig = plot.get_figure()
    fig.tight_layout()
    fig.savefig('images/' + '-'.join(tags) + '.png') # save it to a file

fig = plotTags(['flora', 'sexuality'])

plotTags(['flora', 'butterflies'])

plotTags(['desire', 'eyes'])

plotTags(['flora', 'sexuality', 'death'])

plotTags(['darkness', 'light'])

plotTags(['black', 'death', 'oil'])

plotTags(['flora', 'green'])

plotTags(['green', 'light', 'black', 'darkness'])

plotTags(['hats', 'voices'])

plotTags(['sounds', 'colors', 'touch'])

plotTags(['class'])

"""
Explanation: Let's examine some of the tags. Where do references to flora occur in the story (as tagged)? Do these co-occur with references to sexuality?
End of explanation
"""


