From e6263efc56e05e347bb1fbf948738858f8fc1c95 Mon Sep 17 00:00:00 2001 From: Edward Delaporte Date: Mon, 12 Feb 2024 15:53:37 -0600 Subject: [PATCH 01/16] Add link to https://wkhtmltopdf.org/ --- doc/markdown.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/markdown.md b/doc/markdown.md index 602b312..128895a 100644 --- a/doc/markdown.md +++ b/doc/markdown.md @@ -34,7 +34,7 @@ Then `Ctrl+Shift+P`, `Run Command` and select `markdown to HTML`. ### Setup -Install `wkhtml2pdf.exe` somewhere on my path. +Install [wkhtml2pdf.exe](https://wkhtmltopdf.org/) somewhere on my path. ### Use -- 2.47.3 From 1d60d6d001ad884ad979e81d643d40412b1515d9 Mon Sep 17 00:00:00 2001 From: Edward Delaporte Date: Wed, 14 Feb 2024 09:13:21 -0600 Subject: [PATCH 02/16] Add command to pull GitHub issue data for trend analysis --- psmodules/dash.psm1 | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/psmodules/dash.psm1 b/psmodules/dash.psm1 index bca0ea7..b2b1e09 100644 --- a/psmodules/dash.psm1 +++ b/psmodules/dash.psm1 @@ -119,5 +119,11 @@ function Show-MyTeamWork() { } } +function Write-AgileClosedData() { + $gh_cmd = 'gh issue list --state closed --json title,closedAt,milestone,url' + Write-AgileToFile -gh_command $gh_cmd +} + +Export-ModuleMember -Function Write-AgileClosedData Export-ModuleMember -Function Show-MyDashboard Export-ModuleMember -Function Show-MyTeamWork \ No newline at end of file -- 2.47.3 From bdb4b6305d4ee4fbe907cf200c2651169e6f9a40 Mon Sep 17 00:00:00 2001 From: Edward Delaporte Date: Wed, 14 Feb 2024 13:18:29 -0600 Subject: [PATCH 03/16] Recipe for cleaning data cells out of Jupyter notebooks --- files/gitattributes | 1 + util/jupyter_git_clean.py | 67 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 68 insertions(+) create mode 100644 files/gitattributes create mode 100644 util/jupyter_git_clean.py diff --git a/files/gitattributes b/files/gitattributes new file mode 100644 index 0000000..2d71c45 --- /dev/null +++ b/files/gitattributes @@ -0,0 +1 @@ +*.ipynb filter=~/dotfiles/util/jupyter_git_clean.py \ No newline at end of file diff --git a/util/jupyter_git_clean.py b/util/jupyter_git_clean.py new file mode 100644 index 0000000..301ea78 --- /dev/null +++ b/util/jupyter_git_clean.py @@ -0,0 +1,67 @@ +#!/usr/bin/env python + +""" +Clear outputs of IPython notebooks. + +By default, it prints the notebooks without outputs into stdout. +When the --in-place option is given, all files will be overwritten. + +From +https://github.com/ivanov/nbutils/blob/master/nbstrip.py + +""" + +import sys + +from IPython.nbformat import current as nbformat + + + + +def clear_outputs(nb): + """Clear output of notebook `nb` INPLACE.""" + for ws in nb.worksheets: + for cell in ws.cells: + cell.outputs = [] + + +def stripoutput(inputs, inplace=False): + """ + Strip output of notebooks. + + Parameters + ---------- + inputs : list of string + Path to the notebooks to be processed. + inplace : bool + If this is `True`, outputs in the input files will be deleted. + Default is `False`. + + """ + for inpath in inputs: + with file(inpath) as fp: + nb = nbformat.read(fp, 'ipynb') + clear_outputs(nb) + if inplace: + with file(inpath, 'w') as fp: + nbformat.write(nb, fp, 'ipynb') + else: + nbformat.write(nb, sys.stdout, 'ipynb') + + +def main(): + from argparse import ArgumentParser + parser = ArgumentParser(description=__doc__) + parser.add_argument('inputs', nargs='+', metavar='input', + help='Paths to notebook files.') + #XXX: TODO: handle alternative outputs here, such as to stdout or to file + parser.add_argument('-i', '--inplace', '--in-place', default=True, + action='store_true', + help='Overwrite existing notebook when given.') + + args = parser.parse_args() + stripoutput(**vars(args)) + + +if __name__ == '__main__': + main() -- 2.47.3 From 0459669ddc32d9069dece1d9cbe618f6dd2ee7df Mon Sep 17 00:00:00 2001 From: Edward Delaporte Date: Wed, 14 Feb 2024 14:53:02 -0600 Subject: [PATCH 04/16] Add jupyter hints --- doc/jupyter.md | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 doc/jupyter.md diff --git a/doc/jupyter.md b/doc/jupyter.md new file mode 100644 index 0000000..6bd31c7 --- /dev/null +++ b/doc/jupyter.md @@ -0,0 +1,22 @@ + +```pwsh + +# Install ipykernel at user level +pip install -U ipykernel + +# Tell git to clean data out before committing a notebook +cp ~/dotfiles/files/gitattributes ~/.gitattributes +``` + +Did not work + +```pwsh +# Create VirtualEnv +python -m venv ~/venvs/jupyter +./venvs/jupyter/Scripts/activate +pip install ipykernel + +# Tell jupyter about our virtualenv +cd ~/venvs/jupyter +python -m ipykernel install --user --name=jupyter +``` -- 2.47.3 From 7c1afefe42dcafe9caf31207b4e54a8032553a94 Mon Sep 17 00:00:00 2001 From: Edward Delaporte Date: Wed, 14 Feb 2024 14:54:30 -0600 Subject: [PATCH 05/16] WIP: GitHub issue chart --- data/issues.ipynb | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 data/issues.ipynb diff --git a/data/issues.ipynb b/data/issues.ipynb new file mode 100644 index 0000000..2156a71 --- /dev/null +++ b/data/issues.ipynb @@ -0,0 +1,38 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 21, + "metadata": {}, + "outputs": [], + "source": [ + "# Get ye data\n", + "import glob\n", + "import os\n", + "\n", + "data_files = glob.glob(os.path.expanduser('~\\\\Data\\\\*.json'))" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.12.1" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} -- 2.47.3 From cc29e4ce8e8d5784664ed9391bfd7cfa3b935c85 Mon Sep 17 00:00:00 2001 From: Edward Delaporte Date: Fri, 16 Feb 2024 07:34:16 -0600 Subject: [PATCH 06/16] Fixup --- doc/jupyter.md | 6 +++++- files/gitattributes | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/doc/jupyter.md b/doc/jupyter.md index 6bd31c7..154b635 100644 --- a/doc/jupyter.md +++ b/doc/jupyter.md @@ -4,8 +4,12 @@ # Install ipykernel at user level pip install -U ipykernel +# From https://stackoverflow.com/questions/18734739/using-ipython-jupyter-notebooks-under-version-control + # Tell git to clean data out before committing a notebook -cp ~/dotfiles/files/gitattributes ~/.gitattributes +git config --global core.attributesfile $HOME\dotfiles\files\gitattributes +git config --global filter.dropoutput_ipynb.clean ~\dotfiles\util\jupyter_git_clean.py +git config --global filter.dropoutput_ipynb.smudge cat ``` Did not work diff --git a/files/gitattributes b/files/gitattributes index 2d71c45..08ed568 100644 --- a/files/gitattributes +++ b/files/gitattributes @@ -1 +1 @@ -*.ipynb filter=~/dotfiles/util/jupyter_git_clean.py \ No newline at end of file +*.ipynb filter=$HOME/dotfiles/util/jupyter_git_clean.py \ No newline at end of file -- 2.47.3 From 913175fed4fa9fa4c69377cc28b3d476f462c078 Mon Sep 17 00:00:00 2001 From: Edward Delaporte Date: Fri, 16 Feb 2024 08:20:35 -0600 Subject: [PATCH 07/16] Open a data file --- data/issues.ipynb | 43 ++++++++++++++++++++++++++++++++++++++++--- data/requirements.txt | 4 ++++ 2 files changed, 44 insertions(+), 3 deletions(-) create mode 100644 data/requirements.txt diff --git a/data/issues.ipynb b/data/issues.ipynb index 2156a71..b731ad1 100644 --- a/data/issues.ipynb +++ b/data/issues.ipynb @@ -2,7 +2,7 @@ "cells": [ { "cell_type": "code", - "execution_count": 21, + "execution_count": 2, "metadata": {}, "outputs": [], "source": [ @@ -10,7 +10,44 @@ "import glob\n", "import os\n", "\n", - "data_files = glob.glob(os.path.expanduser('~\\\\Data\\\\*.json'))" + "data_files = glob.glob(os.path.expanduser('~\\\\Data\\\\*.json'))\n" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "3.12.2\n" + ] + } + ], + "source": [ + "import platform\n", + "print(platform.python_version())" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import pandas as pd\n", + "\n", + "data_sets = []\n", + "\n", + "file = data_files[0]\n", + "print(file)\n", + "\n", + "f = open(file, encoding='utf-16')\n", + "data = pd.read_json(f)\n", + "\n", + "print(data)\n" ] } ], @@ -30,7 +67,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.12.1" + "version": "3.12.2" } }, "nbformat": 4, diff --git a/data/requirements.txt b/data/requirements.txt new file mode 100644 index 0000000..1f7d68e --- /dev/null +++ b/data/requirements.txt @@ -0,0 +1,4 @@ +ipykernel +jupyter_core +pandas +pyarrow \ No newline at end of file -- 2.47.3 From 47680a09b0c98441226563f1ae277efd519475ff Mon Sep 17 00:00:00 2001 From: Edward Delaporte Date: Fri, 16 Feb 2024 08:24:12 -0600 Subject: [PATCH 08/16] WIP --- data/issues.ipynb | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/data/issues.ipynb b/data/issues.ipynb index b731ad1..3ffa40c 100644 --- a/data/issues.ipynb +++ b/data/issues.ipynb @@ -49,6 +49,18 @@ "\n", "print(data)\n" ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import maptploglib.pyplot as platform\n", + "# TODO: Get ye data into scatter plot\n", + "plt.scatter(x, y)\n", + "plt.show()" + ] } ], "metadata": { -- 2.47.3 From 0841af4e811a222bb5748a3fb41e1a4aa2287b59 Mon Sep 17 00:00:00 2001 From: Edward Delaporte Date: Fri, 16 Feb 2024 10:37:20 -0600 Subject: [PATCH 09/16] Add closed issues by month for one source --- data/issues.ipynb | 67 +++++++++++++++++++++++++++++++++++++------ data/requirements.txt | 1 + 2 files changed, 60 insertions(+), 8 deletions(-) diff --git a/data/issues.ipynb b/data/issues.ipynb index 3ffa40c..5b1a1b3 100644 --- a/data/issues.ipynb +++ b/data/issues.ipynb @@ -45,21 +45,72 @@ "print(file)\n", "\n", "f = open(file, encoding='utf-16')\n", - "data = pd.read_json(f)\n", - "\n", - "print(data)\n" + "df = pd.read_json(f)" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 23, + "metadata": {}, + "outputs": [], + "source": [ + "df['closed'] = pd.to_datetime(df['closedAt'], format='ISO8601')" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n" + ] + } + ], + "source": [ + "print(type(df.closed[0]))" + ] + }, + { + "cell_type": "code", + "execution_count": 29, "metadata": {}, "outputs": [], "source": [ - "import maptploglib.pyplot as platform\n", - "# TODO: Get ye data into scatter plot\n", - "plt.scatter(x, y)\n", - "plt.show()" + "for_plot = df.groupby(df.closed.dt.month)['url'].count()" + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 33, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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Nu3w/PPPP5/NmjUrGzZsWJf89z1ixIhs4cKFWZZl2d///vesqqoqu/POO9v333PPPdnw4cPLNV7J9OrVK3vyySd3uf+JJ57IevXq1YkTdY7/vuWXy+V22P77fFf873zQoEHZ0qVL2x+/8cYb2VlnnZUdc8wx2T//+c999opFl71587jjjosVK1bscv9bXc2oVKNGjYrly5fv8PzcuXPjwx/+cHzoQx8qw1SlN3z48Fi7dm3748WLF7f/bTYi4oUXXoiBAweWY7SyGDp0aFx11VWxbt26uPfee8s9TnLnnXdeTJ48OaZOnRoTJ06MSy+9NL7yla/EDTfcEDfeeGN84QtfiLPPPrvcYyZ34IEHRlNT0y73NzU1xYEHHthp83SWgw46KObPnx/r1q3bYXvuuefit7/9bblHLImWlpbo06dP++N8Ph933XVXDB8+PE455ZR46aWXyjjdrhX97aaV4qtf/epuL4OOHDky/vjHP3biRJ3j7LPPjttuuy3OP//8HfbNnTs32tra4oYbbijDZKV14YUXdrgMetRRR3XYv3Dhwjj11FM7e6ySGzZsWPTo0WOX+3O5XEyYMKETJ+ocjY2N0atXr1i8eHFMnTo1Zs6cGWPHjo1LL700XnvttTjrrLPi6quvLveYyX3+85+PyZMnx9e+9rU47bTT2r9VetOmTbFo0aK45ppr4qKLLirzlOkdd9xxsX79+hg2bNhO97/66qtd8i+Khx56aDzxxBNx2GGHtT/Xs2fP+PnPfx7nnHNOnHnmmWWcbte67D0WAF3RN77xjfjud78bGzdujFwuFxH/uZdqwIABMX369Lj00kvLPGF6CxYsiK1bt8anP/3pne5/5ZVX4u67744pU6Z08mSlddlll8WqVat2es/Mtm3b4qMf/Wj85je/2efusRAWABVo3bp17TcjDxgwIEaMGFHmiUht27Zt8dprr+1wo+7/7n/xxRd3eSWnXLrsPRYAXdmIESOivr4+6uvr26OiK3/w3+501XX37Nlzl1EREbFhw4ZobGzsxIneHlcsALqIv/zlL/Hud7+7y/3a5Vux7n1r3V325k2Arubuu+/e7f7nnnuukybpXNa9c/vqul2xAKgQ3fWD/6y7stbtHguACjFw4MC46667oq2tbafb448/Xu4RS8K6K2vdwgKgQnTXD/6z7p3bV9ftHguACtFdP/jPunduX123eywAgGS8FQIAJCMsAIBkhAUAkIywAACSERbADpqamiKXy8WqVau69QxA8YQFAJCMsAAAkhEW0I21tbXFN7/5zRg5cmTk8/kYOnRofP3rX9/psQ899FCceOKJkc/nY+DAgTFz5szYtm1b+/5f/OIXcfTRR0evXr2ib9++MX78+A4f7vPDH/4wjjjiiKipqYlRo0bF97///Q4//7HHHotjjz02ampq4vjjj4+VK1eWZtFASfnkTejGGhoaYv78+fGd73wn3vOe98SGDRti9erVOxz34osvxgc/+MH4zGc+EzfffHOsXr06pk6dGjU1NXHVVVfFhg0b4txzz41vfvObcfbZZ8fmzZvjkUceaf+44VtuuSWuvPLKmDt3bhx77LGxcuXKmDp1auy///4xZcqU2LJlS5x55pkxYcKE+NnPfhbr1q2LSy65pLP/cQApZEC31NramuXz+Wz+/Pk77Fu3bl0WEdnKlSuzLMuyyy+/PDv88MOztra29mOuv/767IADDsi2b9+erVixIouIrKmpaafneuc735ndeuutHZ67+uqrs/r6+izLsuzGG2/M+vbtm73++uvt++fNm9dhBqAyuGIB3dTf/va3KBQKcdppp72tY+vr6yOXy7U/N27cuNiyZUv84x//iLFjx8Zpp50WRx99dEycODFOP/30+NjHPhZ9+vSJrVu3xrPPPhuf+9znYurUqe2v37ZtW/Tu3bv9548ZMyZqamra99fX1ydcLdBZhAV0U7169Ur2s3r06BH3339/PProo/H73/8+vve978UVV1wRS5cujf322y8iIubPnx8nnXTSDq8DuhY3b0I3ddhhh0WvXr1i0aJFb3nsEUccEYsXL+7wFc1//vOfo7a2NgYPHhwR//kK53HjxkVjY2OsXLkyqqurY8GCBXHIIYfEoEGD4rnnnouRI0d22EaMGNH+85944ol444032n/+kiVLEq8Y6AyuWEA3VVNTE5dddllceumlUV1dHePGjYuXX345/vrXv+7w9sgXv/jFuO666+Kiiy6KL33pS7FmzZqYNWtWzJgxI6qqqmLp0qWxaNGiOP3006N///6xdOnSePnll+OII46IiIjGxsa4+OKLo3fv3vGBD3wgCoVCLF++PF555ZWYMWNGfOpTn4orrrgipk6dGg0NDdHU1BTf+ta3yvGPBdhb5b7JAyif7du3Z9dcc002bNiw7B3veEc2dOjQ7Nprr93h5s0sy7IHH3wwO+GEE7Lq6upswIAB2WWXXZa9+eabWZZl2dNPP51NnDgx69evX5bP57N3vetd2fe+970O57rllluyY445Jquurs769OmTnXzyydldd93Vvn/x4sXZ2LFjs+rq6uyYY47JfvnLX7p5EypQLsv+59omAMBecI8FAJCMsAAAkhEWAEAywgIASEZYAADJCAsAIBlhAQAkIywAgGSEBQCQjLAAAJIRFgBAMv8PBMTiOHhUsFgAAAAASUVORK5CYII=", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "for_plot.plot(kind='bar')" ] } ], diff --git a/data/requirements.txt b/data/requirements.txt index 1f7d68e..458cebd 100644 --- a/data/requirements.txt +++ b/data/requirements.txt @@ -1,4 +1,5 @@ ipykernel jupyter_core +matplotlib pandas pyarrow \ No newline at end of file -- 2.47.3 From d780c6fe060e29ccf560c2e20e641245cd1853cb Mon Sep 17 00:00:00 2001 From: Edward Delaporte Date: Fri, 16 Feb 2024 11:12:46 -0600 Subject: [PATCH 10/16] WIP chart of issues closed count by milestones and month --- data/issues.ipynb | 84 +++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 74 insertions(+), 10 deletions(-) diff --git a/data/issues.ipynb b/data/issues.ipynb index 5b1a1b3..d0a20fc 100644 --- a/data/issues.ipynb +++ b/data/issues.ipynb @@ -41,7 +41,7 @@ "\n", "data_sets = []\n", "\n", - "file = data_files[0]\n", + "file = data_files[2]\n", "print(file)\n", "\n", "f = open(file, encoding='utf-16')\n", @@ -50,33 +50,71 @@ }, { "cell_type": "code", - "execution_count": 23, + "execution_count": 26, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n" + ] + } + ], + "source": [ + "print(type(df.closed[0]))" + ] + }, + { + "cell_type": "code", + "execution_count": null, "metadata": {}, "outputs": [], "source": [ - "df['closed'] = pd.to_datetime(df['closedAt'], format='ISO8601')" + "import numpy as np\n", + "df['count'] = np.zeros(len(df))\n", + "\n" ] }, { "cell_type": "code", - "execution_count": 26, + "execution_count": 21, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "\n" + "[Strategic] Job Aids on bootstrapping CICD Pipelines\n" ] } ], "source": [ - "print(type(df.closed[0]))" + "print(df.milestone[22].get('title'))" + ] + }, + { + "cell_type": "code", + "execution_count": 58, + "metadata": {}, + "outputs": [], + "source": [ + "closed_months = pd.to_datetime(df['closedAt'], format='ISO8601')\n", + "df['closed_month'] = closed_months.dt.month" ] }, { "cell_type": "code", - "execution_count": 29, + "execution_count": 48, + "metadata": {}, + "outputs": [], + "source": [ + "df['mile'] = [d.get('title') if d else None for d in df.milestone]" + ] + }, + { + "cell_type": "code", + "execution_count": 39, "metadata": {}, "outputs": [], "source": [ @@ -85,7 +123,33 @@ }, { "cell_type": "code", - "execution_count": 33, + "execution_count": 59, + "metadata": {}, + "outputs": [], + "source": [ + "\n", + "grp_df = df.groupby(['mile', 'closed_month']).count().reset_index()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "print(grp_df)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Plot of closed issues by month for one project\n" + ] + }, + { + "cell_type": "code", + "execution_count": 7, "metadata": {}, "outputs": [ { @@ -94,13 +158,13 @@ "" ] }, - "execution_count": 33, + "execution_count": 7, "metadata": {}, "output_type": "execute_result" }, { "data": { - "image/png": "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Nu3w/PPPP5/NmjUrGzZsWJf89z1ixIhs4cKFWZZl2d///vesqqoqu/POO9v333PPPdnw4cPLNV7J9OrVK3vyySd3uf+JJ57IevXq1YkTdY7/vuWXy+V22P77fFf873zQoEHZ0qVL2x+/8cYb2VlnnZUdc8wx2T//+c999opFl71587jjjosVK1bscv9bXc2oVKNGjYrly5fv8PzcuXPjwx/+cHzoQx8qw1SlN3z48Fi7dm3748WLF7f/bTYi4oUXXoiBAweWY7SyGDp0aFx11VWxbt26uPfee8s9TnLnnXdeTJ48OaZOnRoTJ06MSy+9NL7yla/EDTfcEDfeeGN84QtfiLPPPrvcYyZ34IEHRlNT0y73NzU1xYEHHthp83SWgw46KObPnx/r1q3bYXvuuefit7/9bblHLImWlpbo06dP++N8Ph933XVXDB8+PE455ZR46aWXyjjdrhX97aaV4qtf/epuL4OOHDky/vjHP3biRJ3j7LPPjttuuy3OP//8HfbNnTs32tra4oYbbijDZKV14YUXdrgMetRRR3XYv3Dhwjj11FM7e6ySGzZsWPTo0WOX+3O5XEyYMKETJ+ocjY2N0atXr1i8eHFMnTo1Zs6cGWPHjo1LL700XnvttTjrrLPi6quvLveYyX3+85+PyZMnx9e+9rU47bTT2r9VetOmTbFo0aK45ppr4qKLLirzlOkdd9xxsX79+hg2bNhO97/66qtd8i+Khx56aDzxxBNx2GGHtT/Xs2fP+PnPfx7nnHNOnHnmmWWcbte67D0WAF3RN77xjfjud78bGzdujFwuFxH/uZdqwIABMX369Lj00kvLPGF6CxYsiK1bt8anP/3pne5/5ZVX4u67744pU6Z08mSlddlll8WqVat2es/Mtm3b4qMf/Wj85je/2efusRAWABVo3bp17TcjDxgwIEaMGFHmiUht27Zt8dprr+1wo+7/7n/xxRd3eSWnXLrsPRYAXdmIESOivr4+6uvr26OiK3/w3+501XX37Nlzl1EREbFhw4ZobGzsxIneHlcsALqIv/zlL/Hud7+7y/3a5Vux7n1r3V325k2Arubuu+/e7f7nnnuukybpXNa9c/vqul2xAKgQ3fWD/6y7stbtHguACjFw4MC46667oq2tbafb448/Xu4RS8K6K2vdwgKgQnTXD/6z7p3bV9ftHguACtFdP/jPunduX123eywAgGS8FQIAJCMsAIBkhAUAkIywAACSERbADpqamiKXy8WqVau69QxA8YQFAJCMsAAAkhEW0I21tbXFN7/5zRg5cmTk8/kYOnRofP3rX9/psQ899FCceOKJkc/nY+DAgTFz5szYtm1b+/5f/OIXcfTRR0evXr2ib9++MX78+A4f7vPDH/4wjjjiiKipqYlRo0bF97///Q4//7HHHotjjz02ampq4vjjj4+VK1eWZtFASfnkTejGGhoaYv78+fGd73wn3vOe98SGDRti9erVOxz34osvxgc/+MH4zGc+EzfffHOsXr06pk6dGjU1NXHVVVfFhg0b4txzz41vfvObcfbZZ8fmzZvjkUceaf+44VtuuSWuvPLKmDt3bhx77LGxcuXKmDp1auy///4xZcqU2LJlS5x55pkxYcKE+NnPfhbr1q2LSy65pLP/cQApZEC31NramuXz+Wz+/Pk77Fu3bl0WEdnKlSuzLMuyyy+/PDv88MOztra29mOuv/767IADDsi2b9+erVixIouIrKmpaafneuc735ndeuutHZ67+uqrs/r6+izLsuzGG2/M+vbtm73++uvt++fNm9dhBqAyuGIB3dTf/va3KBQKcdppp72tY+vr6yOXy7U/N27cuNiyZUv84x//iLFjx8Zpp50WRx99dEycODFOP/30+NjHPhZ9+vSJrVu3xrPPPhuf+9znYurUqe2v37ZtW/Tu3bv9548ZMyZqamra99fX1ydcLdBZhAV0U7169Ur2s3r06BH3339/PProo/H73/8+vve978UVV1wRS5cujf322y8iIubPnx8nnXTSDq8DuhY3b0I3ddhhh0WvXr1i0aJFb3nsEUccEYsXL+7wFc1//vOfo7a2NgYPHhwR//kK53HjxkVjY2OsXLkyqqurY8GCBXHIIYfEoEGD4rnnnouRI0d22EaMGNH+85944ol444032n/+kiVLEq8Y6AyuWEA3VVNTE5dddllceumlUV1dHePGjYuXX345/vrXv+7w9sgXv/jFuO666+Kiiy6KL33pS7FmzZqYNWtWzJgxI6qqqmLp0qWxaNGiOP3006N///6xdOnSePnll+OII46IiIjGxsa4+OKLo3fv3vGBD3wgCoVCLF++PF555ZWYMWNGfOpTn4orrrgipk6dGg0NDdHU1BTf+ta3yvGPBdhb5b7JAyif7du3Z9dcc002bNiw7B3veEc2dOjQ7Nprr93h5s0sy7IHH3wwO+GEE7Lq6upswIAB2WWXXZa9+eabWZZl2dNPP51NnDgx69evX5bP57N3vetd2fe+970O57rllluyY445Jquurs769OmTnXzyydldd93Vvn/x4sXZ2LFjs+rq6uyYY47JfvnLX7p5EypQLsv+59omAMBecI8FAJCMsAAAkhEWAEAywgIASEZYAADJCAsAIBlhAQAkIywAgGSEBQCQjLAAAJIRFgBAMv8PBMTiOHhUsFgAAAAASUVORK5CYII=", + "image/png": "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x3wAQBkpOixuvfXWmDFjRlx66aUxZsyY+Kd/+qc47LDD4l//9V/bYz4AoIx0K2bnt956K9avXx81NTWtt3Xp0iUmTZoUjz322H7v09TUFE1NTa3rDQ0NERHR2Nj4vo7Z0vSHYkZ8397v8Q9Fe80c0X5zm7ktM/+Rmdsqx387zNyWmf+omJnf3TeldPAdUxFefPHFFBHp0UcfbXP717/+9XTaaaft9z5z585NEWGxWCwWi+VDsNTX1x+0FYo6Y3EoampqYvbs2a3rLS0t8dprr0W/fv2iUChkO05jY2MMGTIk6uvro1evXtketz2ZuWOU48wR5Tm3mTuGmTuGmdtKKcWuXbti0KBBB92vqLD42Mc+Fl27do2XXnqpze0vvfRSDBgwYL/3qaioiIqKija3HXnkkcUctii9evUqmyfAu8zcMcpx5ojynNvMHcPMHcPMf9S7d+/33Keoizd79OgR48ePj5UrV7be1tLSEitXrozq6uriJwQAPlSK/lPI7NmzY/r06XHKKafEaaedFt/61rdiz549cemll7bHfABAGSk6LP7iL/4iXnnllbjhhhti586dMW7cuHjggQfi6KOPbo/53reKioqYO3fuPn926czM3DHKceaI8pzbzB3DzB3DzIemkN7zfSMAAO+P7woBALIRFgBANsICAMhGWAAA2QgLPhJcowzQMdr9I72hM6ioqIjNmzfH6NGjSz0KFG3Hjh2xaNGieOSRR2LHjh3RpUuXOOaYY+LCCy+MSy65JLp27VrqEaHVh/aMRX19fXz1q18t9RhtvPHGG/HII4/EM888s8+2N998M77//e+XYKqD+/Wvfx3/9m//Fs8++2xERDz77LNx+eWXx1e/+tX45S9/WeLp9jV79uz9Ls3NzbFw4cLW9c5mw4YNsW3bttb1O++8MyZMmBBDhgyJM844I5YsWVLC6fbviiuuiF/96lelHqNot912W0ybNq31Z3rnnXfGmDFjYtSoUXHdddfF3r17SzxhW+vWrYvRo0fHf/7nf8bbb78dW7dujfHjx8fhhx8eV199dZx55pmxa9euUo8Jf1TMt5uWk02bNqUuXbqUeoxWzz33XBo2bFgqFAqpS5cu6cwzz0zbt29v3b5z585ONW9KKS1fvjz16NEj9e3bN1VWVqbly5en/v37p0mTJqVPfepTqWvXrmnlypWlHrONQqGQxo0blyZOnNhmKRQK6dRTT00TJ05MZ599dqnH3MfYsWPTihUrUkopLV68OFVVVaUrr7wyLVq0KM2aNSsdccQR6bvf/W6Jp2zr3efyxz/+8bRw4cK0Y8eOUo/0nm688cbUs2fP9LnPfS4NGDAgLVy4MPXr1y/ddNNNaf78+al///7phhtuKPWYbUyYMCHNmzevdf3OO+9Mp59+ekoppddeey2NGzcuXXnllaUa74CamprS0qVL06xZs9KXvvSl9KUvfSnNmjUr/fCHP0xNTU2lHu+Q7Ny5M9XW1pZ6jP2qr69Pu3bt2uf2t956Kz388MMdOkvZhsVPfvKTgy7f/OY3O9Uv6gsvvDBdcMEF6ZVXXklbt25NF1xwQRoxYkT67W9/m1LqnGFRXV2drr/++pRSSj/4wQ9Snz590nXXXde6/dprr03nnntuqcbbrwULFqQRI0bsEzzdunVLTz/9dImmem9VVVWprq4upZTSySefnP75n/+5zfa77747jRkzphSjHVChUEgPPfRQuuqqq9LHPvax1L179/SZz3wm/exnP0vNzc2lHm+/jj322PTjH/84pfTOi4+uXbumu+66q3X7vffem0aOHFmq8farqqoqvfDCC63rzc3NqXv37mnnzp0ppZR+8YtfpEGDBpVqvP3aunVrOuaYY1JlZWU666yz0he/+MX0xS9+MZ111lmpsrIyjRw5Mm3durXUYxats71gTSml7du3p1NPPTV16dIlde3aNf3lX/5lm8Aoxe+Wsg2Ld18tFQqFAy6d6Qlw1FFHpSeffLJ1vaWlJf3VX/1VGjp0aHrhhRc6ZVj06tWr9X/+5ubm1K1bt7Rhw4bW7Vu2bElHH310qcY7oMcffzwdd9xx6W/+5m/SW2+9lVLq/GHRr1+/tG7dupTSO8+VTZs2tdn+/PPPp6qqqlKMdkCFQiG99NJLKaV3XhUtXbo0nXfeealr165p0KBB6brrrut0vzyqqqpaYz6llLp3756eeuqp1vW6urp02GGHlWK0Axo2bFh65JFHWte3b9+eCoVC+sMf/pBSSmnbtm2psrKyVOPt16RJk9LUqVNTQ0PDPtsaGhrS1KlT0+TJk0sw2cFt3rz5oMvSpUs73b/T06ZNS6effnp64okn0ooVK9L48ePTKaeckl577bWU0jthUSgUOnSmsg2LQYMGpfvuu++A2zdu3NipngA9e/ZMzzzzzD63z5w5Mw0ePDitXr26U82b0jth8fzzz7euH3HEEW1eOdXV1XW6f9DetWvXrjRt2rQ0duzYtGXLltS9e/dOHRZf+cpX0mWXXZZSSukLX/hC+tu//ds22+fPn59OPPHEUox2QH8aFn/qt7/9bZo7d24aNmxYp3tOjxgxIi1fvjyllNL//M//pC5duqQf/vCHrdvvv//+NHz48FKNt19XXXVVOuGEE9Ly5cvTL3/5y3T22WeniRMntm5/4IEH0rHHHlvCCfdVVVWVtmzZcsDtTz75ZKcL5ZQO/oL13ds723N60KBBae3ata3rb775ZpoyZUoaN25cevXVV0vyorVs3xUyfvz4WL9+fUydOnW/2wuFQqd6i+GoUaNaL8L6U7fddltERHzmM58pxVgHNXz48Ni6dWsce+yxERHx2GOPxdChQ1u3/+53v4uBAweWaryDOuKII+Lf//3fY8mSJTFp0qRobm4u9UgH9Y1vfCMmTJgQZ511VpxyyinxD//wD7Fq1aoYPXp0PPfcc7FmzZpYtmxZqcd8X4YOHRrz5s2LuXPnxkMPPVTqcdq4+OKLY9q0aTF16tRYuXJlXHPNNXH11VfHq6++GoVCIW6++eb4/Oc/X+ox27jppptix44dMWXKlGhubo7q6uq46667WrcXCoVYsGBBCSfc15FHHhl1dXVxwgkn7Hd7XV1dHHnkkR071PvQt2/fuOWWW+Kcc87Z7/ann346pkyZ0sFTHVxDQ0P06dOndb2ioiLuvffe+MIXvhBnn312m+dKh+nQjMlo9erVra889mf37t1p1apVHTjRwc2fPz+df/75B9x++eWXd/jpqveyaNGi9POf//yA22tqalpfZXdm9fX16b777ku7d+8u9SgH9frrr6c5c+akMWPGpMrKytSjR480bNiw9OUvfzk98cQTpR5vH8OHD0//+7//W+oxitLc3Jxuvvnm9OlPfzrNnz8/tbS0pB/84AdpyJAhqV+/fumSSy7ptM+TN954Y78X53VGf/d3f5f69OmTbr311rR58+a0c+fOtHPnzrR58+Z06623pr59+6a5c+eWesx9TJ48Od14440H3L5p06ZO9+/0iSeemH70ox/tc/vbb7+dLrzwwjR06NAOP2Ph200ByO4b3/hGfPvb346dO3dGoVCIiHc+qG7AgAExa9asuOaaa0o84b6WLVsWe/bsia985Sv73f7666/HT3/605g+fXoHT3Zgc+bMiU2bNsWDDz64z7a9e/fG5z73ufjZz34WLS0tHTaTsACg3Wzbti127twZEREDBgyIESNGlHiiD5e9e/fGH/7wh+jVq9cBt7/44osxbNiwDpvpQ/sBWQCU3ogRI6K6ujqqq6tbo6IzfoDh+9EZ5+7WrdsBoyLinU9tra2t7cCJnLEAoINt3rw5PvnJT3b6i6r/f+U4dylmLtt3hQDQOf30pz896Pbf/OY3HTRJccpx7s44szMWAGTVpUuX93zLf6FQ6HSv/Mtx7s44s2ssAMhq4MCBce+990ZLS8t+lw0bNpR6xP0qx7k748zCAoCs3v0AwwPpbB9g+K5ynLszzuwaCwCy+vrXvx579uw54PaRI0fGf/3Xf3XgRO9POc7dGWd2jQUAkI0/hQAA2QgLACAbYQEAZCMsAIBshAWwj7q6uigUCrFp06aP9AxA8YQFAJCNsAAAshEW8BHW0tISt9xyS4wcOTIqKipi6NChcfPNN+9334cffjhOO+20qKioiIEDB8a1114be/fubd3+ox/9KE488cSoqqqKfv36xaRJk9p8cM+//Mu/xOjRo6OysjJGjRoV//iP/9jm8R9//PE4+eSTo7KyMk455ZTYuHFj+/xHA+3KJ2/CR1hNTU0sXrw4vvnNb8YZZ5wRO3bsiGeffXaf/V588cX48z//87jkkkvi+9//fjz77LMxY8aMqKysjHnz5sWOHTvioosuiltuuSU++9nPxq5du+JXv/pV60cJ33333XHDDTfEbbfdFieffHJs3LgxZsyYEYcffnhMnz49du/eHZ/+9Kfj3HPPjbvuuiu2bdsWV111VUf/OIAcEvCR1NjYmCoqKtLixYv32bZt27YUEWnjxo0ppZSuu+66dPzxx6eWlpbWfW6//fZ0xBFHpObm5rR+/foUEamurm6/xzr22GPTPffc0+a2G2+8MVVXV6eUUrrjjjtSv3790htvvNG6fdGiRW1mAMqDMxbwEfXrX/86mpqa4pxzznlf+1ZXV0ehUGi9bcKECbF79+74/e9/HyeddFKcc845ceKJJ8Z5550XkydPjs9//vPRp0+f2LNnT7zwwgtx2WWXxYwZM1rvv3fv3ujdu3fr448dOzYqKytbt1dXV2f8rwU6irCAj6iqqqpsj9W1a9dYsWJFPProo/GLX/wivvOd78T1118fa9eujcMOOywiIhYvXhynn376PvcDPlxcvAkfUR//+MejqqoqVq5c+Z77jh49Oh577LE2X7/83//939GzZ88YPHhwRLzz9cwTJkyI2tra2LhxY/To0SOWLVsWRx99dAwaNCh+85vfxMiRI9ssI0aMaH38J598Mt58883Wx1+zZk3m/2KgIzhjAR9RlZWVMWfOnLjmmmuiR48eMWHChHjllVfi6aef3ufPI3/9138d3/rWt+KKK66Ir33ta/Hcc8/F3LlzY/bs2dGlS5dYu3ZtrFy5MiZPnhxHHXVUrF27Nl555ZUYPXp0RETU1tbGlVdeGb17944/+7M/i6ampli3bl28/vrrMXv27Pjyl78c119/fcyYMSNqamqirq4u/v7v/74UPxbggyr1RR5A6TQ3N6ebbropDRs2LHXv3j0NHTo0zZ8/f5+LN1NKadWqVenUU09NPXr0SAMGDEhz5sxJb7/9dkoppWeeeSadd955qX///qmioiIdd9xx6Tvf+U6bY919991p3LhxqUePHqlPnz7pzDPPTPfee2/r9sceeyyddNJJqUePHmncuHHpxz/+sYs3oQwVUvqTc5sAAB+AaywAgGyEBQCQjbAAALIRFgBANsICAMhGWAAA2QgLACAbYQEAZCMsAIBshAUAkI2wAACy+X9uAK2SLjLo9wAAAABJRU5ErkJggg==", "text/plain": [ "
" ] -- 2.47.3 From ac202236f525135adec8fa272fcf919ed0b871f8 Mon Sep 17 00:00:00 2001 From: Edward Delaporte Date: Fri, 16 Feb 2024 14:13:23 -0600 Subject: [PATCH 11/16] WIP - chart --- data/issues.ipynb | 84 ++++++++++++++++++++++++------------------- data/requirements.txt | 3 +- 2 files changed, 49 insertions(+), 38 deletions(-) diff --git a/data/issues.ipynb b/data/issues.ipynb index d0a20fc..735326e 100644 --- a/data/issues.ipynb +++ b/data/issues.ipynb @@ -13,6 +13,18 @@ "data_files = glob.glob(os.path.expanduser('~\\\\Data\\\\*.json'))\n" ] }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import os\n", + "\n", + "for file in data_files:\n", + "\tprint(f\"{file}\", os.path.getsize(file))\n" + ] + }, { "cell_type": "code", "execution_count": 5, @@ -41,7 +53,7 @@ "\n", "data_sets = []\n", "\n", - "file = data_files[2]\n", + "file = data_files[6]\n", "print(file)\n", "\n", "f = open(file, encoding='utf-16')\n", @@ -78,24 +90,16 @@ }, { "cell_type": "code", - "execution_count": 21, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[Strategic] Job Aids on bootstrapping CICD Pipelines\n" - ] - } - ], + "outputs": [], "source": [ "print(df.milestone[22].get('title'))" ] }, { "cell_type": "code", - "execution_count": 58, + "execution_count": 68, "metadata": {}, "outputs": [], "source": [ @@ -105,7 +109,7 @@ }, { "cell_type": "code", - "execution_count": 48, + "execution_count": 69, "metadata": {}, "outputs": [], "source": [ @@ -123,7 +127,7 @@ }, { "cell_type": "code", - "execution_count": 59, + "execution_count": 70, "metadata": {}, "outputs": [], "source": [ @@ -149,33 +153,39 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 7, - "metadata": {}, - "output_type": "execute_result" - }, - { - "data": { - "image/png": "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x3wAQBkpOixuvfXWmDFjRlx66aUxZsyY+Kd/+qc47LDD4l//9V/bYz4AoIx0K2bnt956K9avXx81NTWtt3Xp0iUmTZoUjz322H7v09TUFE1NTa3rDQ0NERHR2Nj4vo7Z0vSHYkZ8397v8Q9Fe80c0X5zm7ktM/+Rmdsqx387zNyWmf+omJnf3TeldPAdUxFefPHFFBHp0UcfbXP717/+9XTaaaft9z5z585NEWGxWCwWi+VDsNTX1x+0FYo6Y3EoampqYvbs2a3rLS0t8dprr0W/fv2iUChkO05jY2MMGTIk6uvro1evXtketz2ZuWOU48wR5Tm3mTuGmTuGmdtKKcWuXbti0KBBB92vqLD42Mc+Fl27do2XXnqpze0vvfRSDBgwYL/3qaioiIqKija3HXnkkcUctii9evUqmyfAu8zcMcpx5ojynNvMHcPMHcPMf9S7d+/33Keoizd79OgR48ePj5UrV7be1tLSEitXrozq6uriJwQAPlSK/lPI7NmzY/r06XHKKafEaaedFt/61rdiz549cemll7bHfABAGSk6LP7iL/4iXnnllbjhhhti586dMW7cuHjggQfi6KOPbo/53reKioqYO3fuPn926czM3DHKceaI8pzbzB3DzB3DzIemkN7zfSMAAO+P7woBALIRFgBANsICAMhGWAAA2QgLPhJcowzQMdr9I72hM6ioqIjNmzfH6NGjSz0KFG3Hjh2xaNGieOSRR2LHjh3RpUuXOOaYY+LCCy+MSy65JLp27VrqEaHVh/aMRX19fXz1q18t9RhtvPHGG/HII4/EM888s8+2N998M77//e+XYKqD+/Wvfx3/9m//Fs8++2xERDz77LNx+eWXx1e/+tX45S9/WeLp9jV79uz9Ls3NzbFw4cLW9c5mw4YNsW3bttb1O++8MyZMmBBDhgyJM844I5YsWVLC6fbviiuuiF/96lelHqNot912W0ybNq31Z3rnnXfGmDFjYtSoUXHdddfF3r17SzxhW+vWrYvRo0fHf/7nf8bbb78dW7dujfHjx8fhhx8eV199dZx55pmxa9euUo8Jf1TMt5uWk02bNqUuXbqUeoxWzz33XBo2bFgqFAqpS5cu6cwzz0zbt29v3b5z585ONW9KKS1fvjz16NEj9e3bN1VWVqbly5en/v37p0mTJqVPfepTqWvXrmnlypWlHrONQqGQxo0blyZOnNhmKRQK6dRTT00TJ05MZ599dqnH3MfYsWPTihUrUkopLV68OFVVVaUrr7wyLVq0KM2aNSsdccQR6bvf/W6Jp2zr3efyxz/+8bRw4cK0Y8eOUo/0nm688cbUs2fP9LnPfS4NGDAgLVy4MPXr1y/ddNNNaf78+al///7phhtuKPWYbUyYMCHNmzevdf3OO+9Mp59+ekoppddeey2NGzcuXXnllaUa74CamprS0qVL06xZs9KXvvSl9KUvfSnNmjUr/fCHP0xNTU2lHu+Q7Ny5M9XW1pZ6jP2qr69Pu3bt2uf2t956Kz388MMdOkvZhsVPfvKTgy7f/OY3O9Uv6gsvvDBdcMEF6ZVXXklbt25NF1xwQRoxYkT67W9/m1LqnGFRXV2drr/++pRSSj/4wQ9Snz590nXXXde6/dprr03nnntuqcbbrwULFqQRI0bsEzzdunVLTz/9dImmem9VVVWprq4upZTSySefnP75n/+5zfa77747jRkzphSjHVChUEgPPfRQuuqqq9LHPvax1L179/SZz3wm/exnP0vNzc2lHm+/jj322PTjH/84pfTOi4+uXbumu+66q3X7vffem0aOHFmq8farqqoqvfDCC63rzc3NqXv37mnnzp0ppZR+8YtfpEGDBpVqvP3aunVrOuaYY1JlZWU666yz0he/+MX0xS9+MZ111lmpsrIyjRw5Mm3durXUYxats71gTSml7du3p1NPPTV16dIlde3aNf3lX/5lm8Aoxe+Wsg2Ld18tFQqFAy6d6Qlw1FFHpSeffLJ1vaWlJf3VX/1VGjp0aHrhhRc6ZVj06tWr9X/+5ubm1K1bt7Rhw4bW7Vu2bElHH310qcY7oMcffzwdd9xx6W/+5m/SW2+9lVLq/GHRr1+/tG7dupTSO8+VTZs2tdn+/PPPp6qqqlKMdkCFQiG99NJLKaV3XhUtXbo0nXfeealr165p0KBB6brrrut0vzyqqqpaYz6llLp3756eeuqp1vW6urp02GGHlWK0Axo2bFh65JFHWte3b9+eCoVC+sMf/pBSSmnbtm2psrKyVOPt16RJk9LUqVNTQ0PDPtsaGhrS1KlT0+TJk0sw2cFt3rz5oMvSpUs73b/T06ZNS6effnp64okn0ooVK9L48ePTKaeckl577bWU0jthUSgUOnSmsg2LQYMGpfvuu++A2zdu3NipngA9e/ZMzzzzzD63z5w5Mw0ePDitXr26U82b0jth8fzzz7euH3HEEW1eOdXV1XW6f9DetWvXrjRt2rQ0duzYtGXLltS9e/dOHRZf+cpX0mWXXZZSSukLX/hC+tu//ds22+fPn59OPPHEUox2QH8aFn/qt7/9bZo7d24aNmxYp3tOjxgxIi1fvjyllNL//M//pC5duqQf/vCHrdvvv//+NHz48FKNt19XXXVVOuGEE9Ly5cvTL3/5y3T22WeniRMntm5/4IEH0rHHHlvCCfdVVVWVtmzZcsDtTz75ZKcL5ZQO/oL13ds723N60KBBae3ata3rb775ZpoyZUoaN25cevXVV0vyorVs3xUyfvz4WL9+fUydOnW/2wuFQqd6i+GoUaNaL8L6U7fddltERHzmM58pxVgHNXz48Ni6dWsce+yxERHx2GOPxdChQ1u3/+53v4uBAweWaryDOuKII+Lf//3fY8mSJTFp0qRobm4u9UgH9Y1vfCMmTJgQZ511VpxyyinxD//wD7Fq1aoYPXp0PPfcc7FmzZpYtmxZqcd8X4YOHRrz5s2LuXPnxkMPPVTqcdq4+OKLY9q0aTF16tRYuXJlXHPNNXH11VfHq6++GoVCIW6++eb4/Oc/X+ox27jppptix44dMWXKlGhubo7q6uq46667WrcXCoVYsGBBCSfc15FHHhl1dXVxwgkn7Hd7XV1dHHnkkR071PvQt2/fuOWWW+Kcc87Z7/ann346pkyZ0sFTHVxDQ0P06dOndb2ioiLuvffe+MIXvhBnn312m+dKh+nQjMlo9erVra889mf37t1p1apVHTjRwc2fPz+df/75B9x++eWXd/jpqveyaNGi9POf//yA22tqalpfZXdm9fX16b777ku7d+8u9SgH9frrr6c5c+akMWPGpMrKytSjR480bNiw9OUvfzk98cQTpR5vH8OHD0//+7//W+oxitLc3Jxuvvnm9OlPfzrNnz8/tbS0pB/84AdpyJAhqV+/fumSSy7ptM+TN954Y78X53VGf/d3f5f69OmTbr311rR58+a0c+fOtHPnzrR58+Z06623pr59+6a5c+eWesx9TJ48Od14440H3L5p06ZO9+/0iSeemH70ox/tc/vbb7+dLrzwwjR06NAOP2Ph200ByO4b3/hGfPvb346dO3dGoVCIiHc+qG7AgAExa9asuOaaa0o84b6WLVsWe/bsia985Sv73f7666/HT3/605g+fXoHT3Zgc+bMiU2bNsWDDz64z7a9e/fG5z73ufjZz34WLS0tHTaTsACg3Wzbti127twZEREDBgyIESNGlHiiD5e9e/fGH/7wh+jVq9cBt7/44osxbNiwDpvpQ/sBWQCU3ogRI6K6ujqqq6tbo6IzfoDh+9EZ5+7WrdsBoyLinU9tra2t7cCJnLEAoINt3rw5PvnJT3b6i6r/f+U4dylmLtt3hQDQOf30pz896Pbf/OY3HTRJccpx7s44szMWAGTVpUuX93zLf6FQ6HSv/Mtx7s44s2ssAMhq4MCBce+990ZLS8t+lw0bNpR6xP0qx7k748zCAoCs3v0AwwPpbB9g+K5ynLszzuwaCwCy+vrXvx579uw54PaRI0fGf/3Xf3XgRO9POc7dGWd2jQUAkI0/hQAA2QgLACAbYQEAZCMsAIBshAWwj7q6uigUCrFp06aP9AxA8YQFAJCNsAAAshEW8BHW0tISt9xyS4wcOTIqKipi6NChcfPNN+9334cffjhOO+20qKioiIEDB8a1114be/fubd3+ox/9KE488cSoqqqKfv36xaRJk9p8cM+//Mu/xOjRo6OysjJGjRoV//iP/9jm8R9//PE4+eSTo7KyMk455ZTYuHFj+/xHA+3KJ2/CR1hNTU0sXrw4vvnNb8YZZ5wRO3bsiGeffXaf/V588cX48z//87jkkkvi+9//fjz77LMxY8aMqKysjHnz5sWOHTvioosuiltuuSU++9nPxq5du+JXv/pV60cJ33333XHDDTfEbbfdFieffHJs3LgxZsyYEYcffnhMnz49du/eHZ/+9Kfj3HPPjbvuuiu2bdsWV111VUf/OIAcEvCR1NjYmCoqKtLixYv32bZt27YUEWnjxo0ppZSuu+66dPzxx6eWlpbWfW6//fZ0xBFHpObm5rR+/foUEamurm6/xzr22GPTPffc0+a2G2+8MVVXV6eUUrrjjjtSv3790htvvNG6fdGiRW1mAMqDMxbwEfXrX/86mpqa4pxzznlf+1ZXV0ehUGi9bcKECbF79+74/e9/HyeddFKcc845ceKJJ8Z5550XkydPjs9//vPRp0+f2LNnT7zwwgtx2WWXxYwZM1rvv3fv3ujdu3fr448dOzYqKytbt1dXV2f8rwU6irCAj6iqqqpsj9W1a9dYsWJFPProo/GLX/wivvOd78T1118fa9eujcMOOywiIhYvXhynn376PvcDPlxcvAkfUR//+MejqqoqVq5c+Z77jh49Oh577LE2X7/83//939GzZ88YPHhwRLzz9cwTJkyI2tra2LhxY/To0SOWLVsWRx99dAwaNCh+85vfxMiRI9ssI0aMaH38J598Mt58883Wx1+zZk3m/2KgIzhjAR9RlZWVMWfOnLjmmmuiR48eMWHChHjllVfi6aef3ufPI3/9138d3/rWt+KKK66Ir33ta/Hcc8/F3LlzY/bs2dGlS5dYu3ZtrFy5MiZPnhxHHXVUrF27Nl555ZUYPXp0RETU1tbGlVdeGb17944/+7M/i6ampli3bl28/vrrMXv27Pjyl78c119/fcyYMSNqamqirq4u/v7v/74UPxbggyr1RR5A6TQ3N6ebbropDRs2LHXv3j0NHTo0zZ8/f5+LN1NKadWqVenUU09NPXr0SAMGDEhz5sxJb7/9dkoppWeeeSadd955qX///qmioiIdd9xx6Tvf+U6bY919991p3LhxqUePHqlPnz7pzDPPTPfee2/r9sceeyyddNJJqUePHmncuHHpxz/+sYs3oQwVUvqTc5sAAB+AaywAgGyEBQCQjbAAALIRFgBANsICAMhGWAAA2QgLACAbYQEAZCMsAIBshAUAkI2wAACy+X9uAK2SLjLo9wAAAABJRU5ErkJggg==", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "for_plot.plot(kind='bar')" ] + }, + { + "cell_type": "code", + "execution_count": 75, + "metadata": {}, + "outputs": [], + "source": [ + "import seaborn as sns\n", + "import matplotlib.pyplot as plt\n", + "sns.set_theme()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "plt.figure(figsize=(10, 6))\n", + "sns.lineplot(x='closed_month', y='url', hue='mile', data=grp_df, marker='o', ci=None)\n", + "plt.xlabel('Closed Month')\n", + "plt.ylabel('ClosedAt')\n", + "plt.title('Stacked Line Chart: Milestone Effort by Issue Close Date')\n", + "plt.xticks(rotation=45)\n", + "plt.legend(title='Mile', loc='upper left')\n", + "plt.show()" + ] } ], "metadata": { diff --git a/data/requirements.txt b/data/requirements.txt index 458cebd..0fa37c4 100644 --- a/data/requirements.txt +++ b/data/requirements.txt @@ -2,4 +2,5 @@ ipykernel jupyter_core matplotlib pandas -pyarrow \ No newline at end of file +pyarrow +seaborn \ No newline at end of file -- 2.47.3 From 9cad6021b47e3b4d285c08a4f2e57cfd7b23cef0 Mon Sep 17 00:00:00 2001 From: Edward Delaporte Date: Fri, 16 Feb 2024 14:48:00 -0600 Subject: [PATCH 12/16] Cleanup unused code --- data/issues.ipynb | 96 +++++++++++++---------------------------------- 1 file changed, 26 insertions(+), 70 deletions(-) diff --git a/data/issues.ipynb b/data/issues.ipynb index 735326e..3340aaf 100644 --- a/data/issues.ipynb +++ b/data/issues.ipynb @@ -2,7 +2,25 @@ "cells": [ { "cell_type": "code", - "execution_count": 2, + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "3.12.2\n" + ] + } + ], + "source": [ + "import platform\n", + "print(platform.python_version())" + ] + }, + { + "cell_type": "code", + "execution_count": 92, "metadata": {}, "outputs": [], "source": [ @@ -25,24 +43,6 @@ "\tprint(f\"{file}\", os.path.getsize(file))\n" ] }, - { - "cell_type": "code", - "execution_count": 5, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "3.12.2\n" - ] - } - ], - "source": [ - "import platform\n", - "print(platform.python_version())" - ] - }, { "cell_type": "code", "execution_count": null, @@ -56,30 +56,13 @@ "file = data_files[6]\n", "print(file)\n", "\n", - "f = open(file, encoding='utf-16')\n", + "f = open(file, encoding='utf-8')\n", "df = pd.read_json(f)" ] }, { "cell_type": "code", - "execution_count": 26, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\n" - ] - } - ], - "source": [ - "print(type(df.closed[0]))" - ] - }, - { - "cell_type": "code", - "execution_count": null, + "execution_count": 94, "metadata": {}, "outputs": [], "source": [ @@ -90,16 +73,7 @@ }, { "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "print(df.milestone[22].get('title'))" - ] - }, - { - "cell_type": "code", - "execution_count": 68, + "execution_count": 95, "metadata": {}, "outputs": [], "source": [ @@ -109,7 +83,7 @@ }, { "cell_type": "code", - "execution_count": 69, + "execution_count": 97, "metadata": {}, "outputs": [], "source": [ @@ -118,16 +92,7 @@ }, { "cell_type": "code", - "execution_count": 39, - "metadata": {}, - "outputs": [], - "source": [ - "for_plot = df.groupby(df.closed.dt.month)['url'].count()" - ] - }, - { - "cell_type": "code", - "execution_count": 70, + "execution_count": 98, "metadata": {}, "outputs": [], "source": [ @@ -148,21 +113,12 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "#### Plot of closed issues by month for one project\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "for_plot.plot(kind='bar')" + "#### Plot of closed issues by month and milestone for one project\n" ] }, { "cell_type": "code", - "execution_count": 75, + "execution_count": 99, "metadata": {}, "outputs": [], "source": [ -- 2.47.3 From f2562a307496028edbcb6c337bc5fcd69ca2ffc2 Mon Sep 17 00:00:00 2001 From: Edward Delaporte Date: Fri, 16 Feb 2024 14:55:53 -0600 Subject: [PATCH 13/16] Cleanup unused columns --- data/issues.ipynb | 35 +++++++++++++++-------------------- 1 file changed, 15 insertions(+), 20 deletions(-) diff --git a/data/issues.ipynb b/data/issues.ipynb index 3340aaf..7608fd7 100644 --- a/data/issues.ipynb +++ b/data/issues.ipynb @@ -2,17 +2,9 @@ "cells": [ { "cell_type": "code", - "execution_count": 5, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "3.12.2\n" - ] - } - ], + "outputs": [], "source": [ "import platform\n", "print(platform.python_version())" @@ -20,7 +12,7 @@ }, { "cell_type": "code", - "execution_count": 92, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -53,7 +45,7 @@ "\n", "data_sets = []\n", "\n", - "file = data_files[6]\n", + "file = data_files[2]\n", "print(file)\n", "\n", "f = open(file, encoding='utf-8')\n", @@ -62,7 +54,7 @@ }, { "cell_type": "code", - "execution_count": 94, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -73,17 +65,18 @@ }, { "cell_type": "code", - "execution_count": 95, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ "closed_months = pd.to_datetime(df['closedAt'], format='ISO8601')\n", - "df['closed_month'] = closed_months.dt.month" + "df['closed_month'] = closed_months.dt.month\n", + "df.drop(columns=['closedAt'], inplace=True)" ] }, { "cell_type": "code", - "execution_count": 97, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -92,12 +85,13 @@ }, { "cell_type": "code", - "execution_count": 98, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ "\n", - "grp_df = df.groupby(['mile', 'closed_month']).count().reset_index()" + "grp_df = df.groupby(['mile', 'closed_month']).count().reset_index()\n", + "grp_df.drop(columns=['milestone', 'title', 'url'], inplace=True)" ] }, { @@ -106,6 +100,7 @@ "metadata": {}, "outputs": [], "source": [ + "\n", "print(grp_df)" ] }, @@ -118,7 +113,7 @@ }, { "cell_type": "code", - "execution_count": 99, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -134,7 +129,7 @@ "outputs": [], "source": [ "plt.figure(figsize=(10, 6))\n", - "sns.lineplot(x='closed_month', y='url', hue='mile', data=grp_df, marker='o', ci=None)\n", + "sns.barplot(x='closed_month', y='url', hue='mile', data=grp_df)\n", "plt.xlabel('Closed Month')\n", "plt.ylabel('ClosedAt')\n", "plt.title('Stacked Line Chart: Milestone Effort by Issue Close Date')\n", -- 2.47.3 From 39aa091f5951f7dde7ae65831749d9c5d03b8b51 Mon Sep 17 00:00:00 2001 From: Edward Delaporte Date: Fri, 16 Feb 2024 15:04:01 -0600 Subject: [PATCH 14/16] Add ability to exclude milestones to allow focus on bigger ones --- data/issues.ipynb | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/data/issues.ipynb b/data/issues.ipynb index 7608fd7..011beec 100644 --- a/data/issues.ipynb +++ b/data/issues.ipynb @@ -90,8 +90,8 @@ "outputs": [], "source": [ "\n", - "grp_df = df.groupby(['mile', 'closed_month']).count().reset_index()\n", - "grp_df.drop(columns=['milestone', 'title', 'url'], inplace=True)" + "dfg = df.groupby(['mile', 'closed_month']).count().reset_index()\n", + "dfg.drop(columns=['milestone', 'title', 'url'], inplace=True)\n" ] }, { @@ -101,7 +101,7 @@ "outputs": [], "source": [ "\n", - "print(grp_df)" + "print(dfg)" ] }, { @@ -111,6 +111,19 @@ "#### Plot of closed issues by month and milestone for one project\n" ] }, + { + "cell_type": "code", + "execution_count": 32, + "metadata": {}, + "outputs": [], + "source": [ + "exclude_from_chart = [\n", + "\t'Job Aid Ideas']\n", + "\n", + "for ex in exclude_from_chart:\n", + "\tdfg = dfg[dfg['mile'] != ex]\n" + ] + }, { "cell_type": "code", "execution_count": null, @@ -129,7 +142,7 @@ "outputs": [], "source": [ "plt.figure(figsize=(10, 6))\n", - "sns.barplot(x='closed_month', y='url', hue='mile', data=grp_df)\n", + "sns.barplot(x='closed_month', y='count', hue='mile', data=dfg)\n", "plt.xlabel('Closed Month')\n", "plt.ylabel('ClosedAt')\n", "plt.title('Stacked Line Chart: Milestone Effort by Issue Close Date')\n", -- 2.47.3 From 5e378f911e9d78734849e8bb51487e82de876245 Mon Sep 17 00:00:00 2001 From: Edward Delaporte Date: Fri, 16 Feb 2024 15:39:47 -0600 Subject: [PATCH 15/16] Add a pie chart --- data/issues.ipynb | 48 ++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 45 insertions(+), 3 deletions(-) diff --git a/data/issues.ipynb b/data/issues.ipynb index 011beec..6a68c2a 100644 --- a/data/issues.ipynb +++ b/data/issues.ipynb @@ -45,7 +45,7 @@ "\n", "data_sets = []\n", "\n", - "file = data_files[2]\n", + "file = data_files[6]\n", "print(file)\n", "\n", "f = open(file, encoding='utf-8')\n", @@ -63,6 +63,47 @@ "\n" ] }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "dfp = df\n", + "dfp['mile'] = [d.get('title') if d else None for d in dfp.milestone]\n", + "dfp.drop(columns=['closedAt','milestone', 'url'], inplace=True)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "\n", + "mile_counts = dfp.groupby('mile')['title'].nunique()\n", + "dfp['count'] = dfp['mile'].map(mile_counts)\n", + "# dfp.drop(columns=['title'], inplace=True)\n", + "dfp['mile'] = df['mile'].drop_duplicates()\n", + "dfp.dropna(inplace=True)\n", + "dfp = dfp[dfp['count'] > 5]\n", + "print(dfp)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "mile_counts = df.groupby('mile')['count'].sum()\n", + "mile_counts = mile_counts.loc[lambda x: x > 5]\n", + "plt.pie(mile_counts, labels=mile_counts.index, autopct='%1.1f%%')\n", + "plt.title(f\"Tasks by Milestone\")\n", + "plt.axis('equal')\n", + "plt.show()" + ] + }, { "cell_type": "code", "execution_count": null, @@ -113,7 +154,7 @@ }, { "cell_type": "code", - "execution_count": 32, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -142,7 +183,8 @@ "outputs": [], "source": [ "plt.figure(figsize=(10, 6))\n", - "sns.barplot(x='closed_month', y='count', hue='mile', data=dfg)\n", + "sns.pie(x='closed_month', y='count', hue='mile', data=dfg)\n", + "plt.pie(dfg, )\n", "plt.xlabel('Closed Month')\n", "plt.ylabel('ClosedAt')\n", "plt.title('Stacked Line Chart: Milestone Effort by Issue Close Date')\n", -- 2.47.3 From 72a71a545ddfbb9250308146efdda18f8ebcdfc1 Mon Sep 17 00:00:00 2001 From: Edward Delaporte Date: Fri, 16 Feb 2024 16:18:04 -0600 Subject: [PATCH 16/16] Add pie chart --- data/issues.ipynb | 34 ++++++++++++++++------------------ 1 file changed, 16 insertions(+), 18 deletions(-) diff --git a/data/issues.ipynb b/data/issues.ipynb index 6a68c2a..6c081fe 100644 --- a/data/issues.ipynb +++ b/data/issues.ipynb @@ -45,7 +45,8 @@ "\n", "data_sets = []\n", "\n", - "file = data_files[6]\n", + "# file = data_files[6] # CLI Tools\n", + "file = data_files[2] # Job Aids\n", "print(file)\n", "\n", "f = open(file, encoding='utf-8')\n", @@ -63,6 +64,13 @@ "\n" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Pie Chart" + ] + }, { "cell_type": "code", "execution_count": null, @@ -104,6 +112,13 @@ "plt.show()" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Plot of closed issues by month and milestone for one project\n" + ] + }, { "cell_type": "code", "execution_count": null, @@ -135,23 +150,6 @@ "dfg.drop(columns=['milestone', 'title', 'url'], inplace=True)\n" ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "\n", - "print(dfg)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### Plot of closed issues by month and milestone for one project\n" - ] - }, { "cell_type": "code", "execution_count": null, -- 2.47.3