diff --git a/appfigures.py b/appfigures.py index 38db1db..aa98f58 100755 --- a/appfigures.py +++ b/appfigures.py @@ -18,43 +18,44 @@ def openURL(urlFragment): def getData(pj): - # https://stackoverflow.com/questions/9627686/plotting-dates-on-the-x-axis-with-pythons-matplotlib#9627970 from datetime import datetime # Remove last couple days, since they're 0 return list( zip( *[ - (datetime.strptime(z["date"], "%Y-%m-%d"), z["downloads"], z["updates"]) + ( + datetime.strptime(z["date"], "%Y-%m-%d"), + z["downloads"], + z["updates"], + z["downloads"] - z["uninstalls"], + ) for z in sorted(pj.values(), key=lambda _: _["date"]) ][:-4] ) ) -def combineDailyToWeekly(pj, func): - chunkSize = 7 - return [func(pj[i : i + chunkSize]) for i in range(0, len(pj), chunkSize)] +def combineDaily(pj, func, numDays): + assert numDays in (1, 7) + return tuple([func(pj[i : i + numDays]) for i in range(0, len(pj), numDays)]) def getLastElem(arr): return arr[-1] -def getDownloadsWeekly(t): - return combineDailyToWeekly(t[0], getLastElem), combineDailyToWeekly(t[1], sum) +def getAxes(t, y_axis_choice, numDays): + assert len(t[0]) == len(t[y_axis_choice]) + assert y_axis_choice in (1, 2, 3) + assert numDays in (1, 7) + assert t[0] == combineDaily(t[0], getLastElem, 1) + assert t[y_axis_choice] == combineDaily(t[y_axis_choice], sum, 1) - -def getUpdatesWeekly(t): - return combineDailyToWeekly(t[0], getLastElem), combineDailyToWeekly(t[2], sum) - - -def getDownloadsDaily(t): - return t[0], t[1] - - -def getUpdatesDaily(t): - return t[0], t[2] + return ( + combineDaily(t[0], getLastElem, numDays), + combineDaily(t[y_axis_choice], sum, numDays), + ) def plotData(filename, ylabel, timespan, x, y): @@ -68,12 +69,13 @@ def plotData(filename, ylabel, timespan, x, y): assert len(x) == len(y) + # https://stackoverflow.com/questions/9627686/plotting-dates-on-the-x-axis-with-pythons-matplotlib#9627970 plt.clf() plt.gca().xaxis.set_major_formatter(mdates.DateFormatter("%Y-%m-%d")) plt.gca().xaxis.set_major_locator(mdates.AutoDateLocator()) plt.xlabel("Date") - assert ylabel in ("Downloads", "Updates") + assert ylabel in ("Downloads", "Updates", "Net New Installs") plt.ylabel(ylabel) assert timespan in ("Daily", "Weekly") @@ -96,23 +98,36 @@ def main(): from sys import argv outputPath = argv[1] + + # TOCTOU, but doesn't much matter. Just helpful to detect + # failures early if possible. assert checkOutputPath(outputPath) + getPath = lambda n: join(outputPath, n) data = getData(loads(openURL("sales/dates/-120/0").read())) - plotData( - getPath("downloads_daily.png"), "Downloads", "Daily", *getDownloadsDaily(data) - ) - plotData(getPath("updates_daily.png"), "Updates", "Daily", *getUpdatesDaily(data)) - plotData( - getPath("downloads_weekly.png"), - "Downloads", - "Weekly", - *getDownloadsWeekly(data) - ) - plotData( - getPath("updates_weekly.png"), "Updates", "Weekly", *getUpdatesWeekly(data) - ) + + # data has, in order: date, downloads, updates, and net new installs + for interval, numDays in (("Daily", 1), ("Weekly", 7)): + fi = interval.lower() + plotData( + getPath("downloads_%s.png" % fi), + "Downloads", + interval, + *getAxes(data, 1, numDays) + ) + plotData( + getPath("updates_%s.png" % fi), + "Updates", + interval, + *getAxes(data, 2, numDays) + ) + plotData( + getPath("netnewinstalls_%s.png" % fi), + "Net New Installs", + interval, + *getAxes(data, 3, numDays) + ) main() diff --git a/index.html b/index.html index b7f07fc..8d25723 100644 --- a/index.html +++ b/index.html @@ -4,5 +4,7 @@ + +