# Path: dcs/analyze.py
# def textAnalysis(series):
# 	"""Analyzes a :class:`pandas.Series` of type ``str``, returning a dictionary containing computed statistics
# 
# 	The returned dictionary has the following structure: {*metric*: *value*}. The calculated metrics are:
# 
# 	*	**word_count_min**: minimum number of words in each row
# 	*	**word_count_max**: maximum number of words in each row
# 	*	**word_count_average**: average number of words in each row
# 	*	**word_length_min**: length of shortest word
# 	*	**word_length_max**: length of longets word
# 	*	**word_total**: total number of words
# 	*	**word_mode**: most frequently occurring word
# 	*	**word_mode_frequency**: frequency of **word_mode**
# 	*	**word_frequencies**: a ``list<tuple<str, int>>`` object containing top 50 words (by frequency) and their counts
# 	*	**invalid**: number of invalid values
# 
# 	The returned dictionary will also contain the general statistical metrics returned by :func:`dcs.analyze.genericAnalysis`
# 
# 	Args:
# 		series (pandas.Series): series to analyze
# 
# 	Returns:
# 		dict: dictionary containing statistical metric–value pairs
# 	"""
# 
# 	analysis = {}
# 	minWordCount = float('inf')
# 	maxWordCount = 0
# 	totalWords = 0
# 	wordCounts = {}
# 	sumOfWordLengths = 0
# 	wordFrequencies = []
# 	frequencyCount = 0
# 
# 	averageWordsPerCell = 0
# 	minWordLength = float('inf')
# 	maxWordLength = 0
# 
# 	for row in series:
# 		if pd.notnull(row):
# 			words = str(row).split()
# 			numberOfWords = len(words)
# 			if numberOfWords < minWordCount:
# 				minWordCount = numberOfWords
# 			if numberOfWords > maxWordCount:
# 				maxWordCount = numberOfWords
# 			totalWords += numberOfWords
# 
# 			for word in words:
# 				wordLength = len(word)
# 				wordCounts[word] = wordCounts.get(word, 0) + 1
# 				sumOfWordLengths += wordLength
# 				if wordLength < minWordLength:
# 					minWordLength = wordLength
# 				elif wordLength > maxWordLength:
# 					maxWordLength = wordLength
# 
# 	averageWordLength = sumOfWordLengths / totalWords if totalWords > 0 else 0 
# 	averageWordCount = totalWords / series.count() if series.count() > 0 else 0
# 
# 	uniqueWords = 0
# 	maxCount = 0
# 	mostProminentWords = []
# 	for word, count in wordCounts.iteritems():
# 		uniqueWords += 1
# 		if count > maxCount:
# 			maxCount = count
# 			mostProminentWords = [word]
# 			maxCount = count
# 		elif count == maxCount:
# 			mostProminentWords.append(word)
# 	for w in sorted(wordCounts, key=wordCounts.get, reverse=True):
# 			if frequencyCount < 50:
# 				wordFrequencies.append((w, wordCounts[w]))
# 				frequencyCount += 1
# 			else:
# 				break
# 	#wordFrequencies = {k: wordCounts[k] for k in wordCounts.keys()[:50]}
# 
# 
# 	analysis = {}
# 	analysis["word_count_min"] = minWordCount
# 	analysis["word_count_max"] = maxWordCount
# 	analysis["word_count_average"] = averageWordCount
# 	analysis["word_length_min"] = minWordLength
# 	analysis["word_length_max"] = maxWordLength
# 	analysis["word_length_average"] = averageWordLength
# 	analysis["word_total"] = totalWords
# 	analysis["word_unique_count"] = uniqueWords
# 	analysis["word_mode"] = mostProminentWords
# 	analysis["word_mode_frequency"] = maxCount
# 	analysis["word_frequencies"] = wordFrequencies
# 	analysis["invalid"] = series.isnull().sum()
# 	analysis.update(genericAnalysis(series))
# 
# 	return analysis


import pandas as pd
import numpy as np
import matplotlib
import scipy.stats
import traceback
import base64
import dateutil.parser
from matplotlib.dates import num2date, date2num
from matplotlib import pyplot
from dcs.analyze import textAnalysis
from StringIO import StringIO # USE for production

			The values in the **axis** dictionary should be strings that are parseable using :func:`dateutil.parser.parse`

	The function returns a dictionary with the following key-value pairs:

	*	**image** : *StringIO.StringIO* – :class:`StringIO.StringIO` object containing Base64 encoded PNG image of generated plot
	*	**axis** : *dict* – dictionary containing axis/window settings for the generated plot with the structure
		``{'x': {'start': x-axis min, 'end': x-axis max}, 'y': {'start': y-axis min, 'end': y-axis max}}``

		The values in the **axis** dictionary are date strings formatted using the :meth:`ISO8601 date format <python:datetime.datetime.isoformat>`

	Args:
		df (pandas.DataFrame): data frame
		xIndex (int): index of column to plot on x-axis
		yIndices (list<int>, optional): indices of columns to plot on y-axis
		options (dict, optional): options dictionary

	Returns:
		dict: dictionary containing image and axis settings"""

	xColumn = df.columns[xIndex]
	yColumns = [df.columns[index] for index in yIndices]

	df = df.dropna(subset=[xColumn])
	df.sort_values(xColumn, inplace=True)

	pyplot.style.use('ggplot')
	fig = pyplot.figure(figsize=(10, 8))
	ax = fig.add_subplot(111)
	

# Path: dcs/analyze.py
# def textAnalysis(series):
# 	"""Analyzes a :class:`pandas.Series` of type ``str``, returning a dictionary containing computed statistics
# 
# 	The returned dictionary has the following structure: {*metric*: *value*}. The calculated metrics are:
# 
# 	*	**word_count_min**: minimum number of words in each row
# 	*	**word_count_max**: maximum number of words in each row
# 	*	**word_count_average**: average number of words in each row
# 	*	**word_length_min**: length of shortest word
# 	*	**word_length_max**: length of longets word
# 	*	**word_total**: total number of words
# 	*	**word_mode**: most frequently occurring word
# 	*	**word_mode_frequency**: frequency of **word_mode**
# 	*	**word_frequencies**: a ``list<tuple<str, int>>`` object containing top 50 words (by frequency) and their counts
# 	*	**invalid**: number of invalid values
# 
# 	The returned dictionary will also contain the general statistical metrics returned by :func:`dcs.analyze.genericAnalysis`
# 
# 	Args:
# 		series (pandas.Series): series to analyze
# 
# 	Returns:
# 		dict: dictionary containing statistical metric–value pairs
# 	"""
# 
# 	analysis = {}
# 	minWordCount = float('inf')
# 	maxWordCount = 0
# 	totalWords = 0
# 	wordCounts = {}
# 	sumOfWordLengths = 0
# 	wordFrequencies = []
# 	frequencyCount = 0
# 
# 	averageWordsPerCell = 0
# 	minWordLength = float('inf')
# 	maxWordLength = 0
# 
# 	for row in series:
# 		if pd.notnull(row):
# 			words = str(row).split()
# 			numberOfWords = len(words)
# 			if numberOfWords < minWordCount:
# 				minWordCount = numberOfWords
# 			if numberOfWords > maxWordCount:
# 				maxWordCount = numberOfWords
# 			totalWords += numberOfWords
# 
# 			for word in words:
# 				wordLength = len(word)
# 				wordCounts[word] = wordCounts.get(word, 0) + 1
# 				sumOfWordLengths += wordLength
# 				if wordLength < minWordLength:
# 					minWordLength = wordLength
# 				elif wordLength > maxWordLength:
# 					maxWordLength = wordLength
# 
# 	averageWordLength = sumOfWordLengths / totalWords if totalWords > 0 else 0 
# 	averageWordCount = totalWords / series.count() if series.count() > 0 else 0
# 
# 	uniqueWords = 0
# 	maxCount = 0
# 	mostProminentWords = []
# 	for word, count in wordCounts.iteritems():
# 		uniqueWords += 1
# 		if count > maxCount:
# 			maxCount = count
# 			mostProminentWords = [word]
# 			maxCount = count
# 		elif count == maxCount:
# 			mostProminentWords.append(word)
# 	for w in sorted(wordCounts, key=wordCounts.get, reverse=True):
# 			if frequencyCount < 50:
# 				wordFrequencies.append((w, wordCounts[w]))
# 				frequencyCount += 1
# 			else:
# 				break
# 	#wordFrequencies = {k: wordCounts[k] for k in wordCounts.keys()[:50]}
# 
# 
# 	analysis = {}
# 	analysis["word_count_min"] = minWordCount
# 	analysis["word_count_max"] = maxWordCount
# 	analysis["word_count_average"] = averageWordCount
# 	analysis["word_length_min"] = minWordLength
# 	analysis["word_length_max"] = maxWordLength
# 	analysis["word_length_average"] = averageWordLength
# 	analysis["word_total"] = totalWords
# 	analysis["word_unique_count"] = uniqueWords
# 	analysis["word_mode"] = mostProminentWords
# 	analysis["word_mode_frequency"] = maxCount
# 	analysis["word_frequencies"] = wordFrequencies
# 	analysis["invalid"] = series.isnull().sum()
# 	analysis.update(genericAnalysis(series))
# 
# 	return analysis


# Path: dcs/view.py
import pandas as pd
import numpy as np
import matplotlib
import scipy.stats
import traceback
import base64
import dateutil.parser
from matplotlib.dates import num2date, date2num
from matplotlib import pyplot
from dcs.analyze import textAnalysis
from StringIO import StringIO # USE for production


			The values in the **axis** dictionary should be strings that are parseable using :func:`dateutil.parser.parse`

	The function returns a dictionary with the following key-value pairs:

	*	**image** : *StringIO.StringIO* – :class:`StringIO.StringIO` object containing Base64 encoded PNG image of generated plot
	*	**axis** : *dict* – dictionary containing axis/window settings for the generated plot with the structure
		``{'x': {'start': x-axis min, 'end': x-axis max}, 'y': {'start': y-axis min, 'end': y-axis max}}``

		The values in the **axis** dictionary are date strings formatted using the :meth:`ISO8601 date format <python:datetime.datetime.isoformat>`

	Args:
		df (pandas.DataFrame): data frame
		xIndex (int): index of column to plot on x-axis
		yIndices (list<int>, optional): indices of columns to plot on y-axis
		options (dict, optional): options dictionary

	Returns:
		dict: dictionary containing image and axis settings"""

	xColumn = df.columns[xIndex]
	yColumns = [df.columns[index] for index in yIndices]

	df = df.dropna(subset=[xColumn])
	df.sort_values(xColumn, inplace=True)

	pyplot.style.use('ggplot')
	fig = pyplot.figure(figsize=(10, 8))
	ax = fig.add_subplot(111)
	

	if(type(options) is dict):