00ber commited on
Commit
f61d311
1 Parent(s): eb34b3c

added source code

Browse files
This view is limited to 50 files because it contains too many changes.   See raw diff
Files changed (50) hide show
  1. .DS_Store +0 -0
  2. README.md +1 -0
  3. training/.DS_Store +0 -0
  4. training/.dockerignore +1 -0
  5. training/.gitignore +1 -0
  6. training/data/weather-data.tar.gz +0 -3
  7. training/src/.DS_Store +0 -0
  8. training/src/.ipynb_checkpoints/MSML-602-Final-Project-checkpoint.ipynb +0 -0
  9. training/src/.ipynb_checkpoints/MSML-602-HW1-Q4-checkpoint.ipynb +283 -0
  10. training/src/.ipynb_checkpoints/MSML-602-HW1-checkpoint.ipynb +0 -0
  11. training/src/.ipynb_checkpoints/MSML602_Midterm_Karki-checkpoint.ipynb +831 -0
  12. training/{MSML-602-Final-Project-Final-Version.ipynb → src/MSML-602-Final-Project-Final-Version.ipynb} +0 -0
  13. training/{MSML-602-Final-Project.ipynb → src/MSML-602-Final-Project.ipynb} +0 -0
  14. training/{downloader.py → src/downloader.py} +0 -0
  15. web/.DS_Store +0 -0
  16. web/.dockerignore +2 -0
  17. web/.gitignore +1 -0
  18. web/Dockerfile.backend +11 -0
  19. web/Dockerfile.frontend +13 -0
  20. web/Makefile +19 -0
  21. web/README.md +1 -0
  22. web/backend/.DS_Store +0 -0
  23. web/backend/.dockerignore +1 -0
  24. web/backend/.gitignore +2 -0
  25. web/backend/README.md +1 -0
  26. web/backend/requirements.txt +7 -0
  27. web/backend/src/.DS_Store +0 -0
  28. web/backend/src/app.py +244 -0
  29. web/backend/src/model/keras_metadata.pb +8 -0
  30. web/backend/src/model/saved_model.pb +0 -0
  31. web/backend/src/model/scaler.pkl +0 -0
  32. web/backend/src/model/variables/variables.data-00000-of-00001 +0 -0
  33. web/backend/src/model/variables/variables.index +0 -0
  34. web/docker-compose.prod.yml +10 -0
  35. web/docker-compose.yml +34 -0
  36. web/frontend/.browserslistrc +16 -0
  37. web/frontend/.dockerignore +3 -0
  38. web/frontend/.editorconfig +16 -0
  39. web/frontend/.github/CODE_OF_CONDUCT.md +46 -0
  40. web/frontend/.github/COMMIT_CONVENTION.md +83 -0
  41. web/frontend/.github/CONTRIBUTING.md +178 -0
  42. web/frontend/.github/FUNDING.yml +4 -0
  43. web/frontend/.github/ISSUE_TEMPLATE/bug_report.md +20 -0
  44. web/frontend/.github/ISSUE_TEMPLATE/feature_request.md +18 -0
  45. web/frontend/.github/SUPPORT.md +9 -0
  46. web/frontend/.github/workflows/build-check.yml +39 -0
  47. web/frontend/.github/workflows/stale.yml +27 -0
  48. web/frontend/.gitignore +45 -0
  49. web/frontend/README.md +219 -0
  50. web/frontend/angular.json +118 -0
.DS_Store ADDED
Binary file (6.15 kB). View file
 
README.md ADDED
@@ -0,0 +1 @@
 
 
1
+ Weather forecasting using machine learning
training/.DS_Store ADDED
Binary file (6.15 kB). View file
 
training/.dockerignore ADDED
@@ -0,0 +1 @@
 
 
1
+ .git
training/.gitignore ADDED
@@ -0,0 +1 @@
 
 
1
+ .python-version
training/data/weather-data.tar.gz DELETED
@@ -1,3 +0,0 @@
1
- version https://git-lfs.github.com/spec/v1
2
- oid sha256:8b8096982477f4058aee79f5b4b41f8dacf9e5bcda5d97434ccbf2a573189e14
3
- size 38169226
 
 
 
 
training/src/.DS_Store ADDED
Binary file (6.15 kB). View file
 
training/src/.ipynb_checkpoints/MSML-602-Final-Project-checkpoint.ipynb ADDED
The diff for this file is too large to render. See raw diff
 
training/src/.ipynb_checkpoints/MSML-602-HW1-Q4-checkpoint.ipynb ADDED
@@ -0,0 +1,283 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "cells": [
3
+ {
4
+ "cell_type": "code",
5
+ "execution_count": 96,
6
+ "id": "d10fb797-f9d4-40c7-ba48-08e4ece334f9",
7
+ "metadata": {},
8
+ "outputs": [
9
+ {
10
+ "name": "stdout",
11
+ "output_type": "stream",
12
+ "text": [
13
+ "\n",
14
+ "Data for sum\n",
15
+ " x P(X) x * P(X)\n",
16
+ "0 10 0.125000 1.250000\n",
17
+ "1 11 0.125000 1.375000\n",
18
+ "2 9 0.115741 1.041667\n",
19
+ "3 12 0.115741 1.388889\n",
20
+ "4 8 0.097222 0.777778\n",
21
+ "5 13 0.097222 1.263889\n",
22
+ "6 7 0.069444 0.486111\n",
23
+ "7 14 0.069444 0.972222\n",
24
+ "8 6 0.046296 0.277778\n",
25
+ "9 15 0.046296 0.694444\n",
26
+ "10 5 0.027778 0.138889\n",
27
+ "11 16 0.027778 0.444444\n",
28
+ "12 4 0.013889 0.055556\n",
29
+ "13 17 0.013889 0.236111\n",
30
+ "14 3 0.004630 0.013889\n",
31
+ "15 18 0.004630 0.083333\n",
32
+ "\n",
33
+ "Expectation for sum: 10.5\n",
34
+ "\n",
35
+ "Data for product\n",
36
+ " x P(X) x * P(X)\n",
37
+ "0 12 0.069444 0.833333\n",
38
+ "1 24 0.069444 1.666667\n",
39
+ "2 30 0.055556 1.666667\n",
40
+ "3 60 0.055556 3.333333\n",
41
+ "4 36 0.055556 2.000000\n",
42
+ "5 18 0.041667 0.750000\n",
43
+ "6 72 0.041667 3.000000\n",
44
+ "7 6 0.041667 0.250000\n",
45
+ "8 48 0.041667 2.000000\n",
46
+ "9 20 0.041667 0.833333\n",
47
+ "10 8 0.032407 0.259259\n",
48
+ "11 90 0.027778 2.500000\n",
49
+ "12 40 0.027778 1.111111\n",
50
+ "13 16 0.027778 0.444444\n",
51
+ "14 10 0.027778 0.277778\n",
52
+ "15 4 0.027778 0.111111\n",
53
+ "16 15 0.027778 0.416667\n",
54
+ "17 120 0.027778 3.333333\n",
55
+ "18 32 0.013889 0.444444\n",
56
+ "19 25 0.013889 0.347222\n",
57
+ "20 108 0.013889 1.500000\n",
58
+ "21 100 0.013889 1.388889\n",
59
+ "22 96 0.013889 1.333333\n",
60
+ "23 3 0.013889 0.041667\n",
61
+ "24 80 0.013889 1.111111\n",
62
+ "25 75 0.013889 1.041667\n",
63
+ "26 150 0.013889 2.083333\n",
64
+ "27 144 0.013889 2.000000\n",
65
+ "28 5 0.013889 0.069444\n",
66
+ "29 180 0.013889 2.500000\n",
67
+ "30 50 0.013889 0.694444\n",
68
+ "31 9 0.013889 0.125000\n",
69
+ "32 45 0.013889 0.625000\n",
70
+ "33 2 0.013889 0.027778\n",
71
+ "34 54 0.013889 0.750000\n",
72
+ "35 1 0.004630 0.004630\n",
73
+ "36 125 0.004630 0.578704\n",
74
+ "37 64 0.004630 0.296296\n",
75
+ "38 27 0.004630 0.125000\n",
76
+ "39 216 0.004630 1.000000\n",
77
+ "Expectation for product 42.875\n"
78
+ ]
79
+ }
80
+ ],
81
+ "source": [
82
+ "import pandas as pd\n",
83
+ " \n",
84
+ "dice1 = [1, 2, 3, 4, 5, 6]\n",
85
+ "dice2 = [1, 2, 3, 4, 5, 6]\n",
86
+ "dice3 = [1, 2, 3, 4, 5, 6]\n",
87
+ "\n",
88
+ "\n",
89
+ "data = [[d1, d2, d3, d1 + d2 + d3, d1 * d2 * d3] for d1 in dice1 for d2 in dice2 for d3 in dice3]\n",
90
+ "\n",
91
+ "df = pd.DataFrame(data, columns=[\"dice1\", \"dice2\", \"dice3\", \"sum_of_dots\", \"product_of_dots\"])\n",
92
+ "total_count = len(dice1) * len(dice2) * len(dice3)\n",
93
+ "\n",
94
+ "# Expectation of sum of number of dots on the three rolls\n",
95
+ "sum_pmf = [(x[0], count_x / (total_count * 1.0)) for x, count_x in df.value_counts([\"sum_of_dots\"]).items()]\n",
96
+ "sum_pmf_df = pd.DataFrame(sum_pmf, columns=[\"x\", \"P(X)\"])\n",
97
+ "sum_pmf_df[\"x * P(X)\"] = sum_pmf_df[\"x\"] * sum_pmf_df[\"P(X)\"] \n",
98
+ "expectation_sum = sum_pmf_df[\"x * P(X)\"].sum()\n",
99
+ "\n",
100
+ "# Expectation of product of number of dots on the three rolls\n",
101
+ "product_pmf = [(x[0], count_x / (total_count * 1.0)) for x, count_x in df.value_counts([\"product_of_dots\"]).items()]\n",
102
+ "product_pmf_df = pd.DataFrame(product_pmf, columns=[\"x\", \"P(X)\"])\n",
103
+ "product_pmf_df[\"x * P(X)\"] = product_pmf_df[\"x\"] * product_pmf_df[\"P(X)\"] \n",
104
+ "expectation_product = product_pmf_df[\"x * P(X)\"].sum()\n",
105
+ "\n",
106
+ "print(\"\\nData for sum\")\n",
107
+ "print(sum_pmf_df)\n",
108
+ "print(\"\\nExpectation for sum: {}\".format(expectation_sum))\n",
109
+ "\n",
110
+ "print(\"\\nData for product\")\n",
111
+ "print(product_pmf_df)\n",
112
+ "print(\"Expectation for product {}\".format(expectation_product))"
113
+ ]
114
+ },
115
+ {
116
+ "cell_type": "code",
117
+ "execution_count": 78,
118
+ "id": "301ba7da-d523-48eb-8a6d-25e8d6fa5ffe",
119
+ "metadata": {},
120
+ "outputs": [
121
+ {
122
+ "data": {
123
+ "text/html": [
124
+ "<div>\n",
125
+ "<style scoped>\n",
126
+ " .dataframe tbody tr th:only-of-type {\n",
127
+ " vertical-align: middle;\n",
128
+ " }\n",
129
+ "\n",
130
+ " .dataframe tbody tr th {\n",
131
+ " vertical-align: top;\n",
132
+ " }\n",
133
+ "\n",
134
+ " .dataframe thead th {\n",
135
+ " text-align: right;\n",
136
+ " }\n",
137
+ "</style>\n",
138
+ "<table border=\"1\" class=\"dataframe\">\n",
139
+ " <thead>\n",
140
+ " <tr style=\"text-align: right;\">\n",
141
+ " <th></th>\n",
142
+ " <th>x</th>\n",
143
+ " <th>P(X)</th>\n",
144
+ " </tr>\n",
145
+ " </thead>\n",
146
+ " <tbody>\n",
147
+ " <tr>\n",
148
+ " <th>0</th>\n",
149
+ " <td>10</td>\n",
150
+ " <td>0.125000</td>\n",
151
+ " </tr>\n",
152
+ " <tr>\n",
153
+ " <th>1</th>\n",
154
+ " <td>11</td>\n",
155
+ " <td>0.125000</td>\n",
156
+ " </tr>\n",
157
+ " <tr>\n",
158
+ " <th>2</th>\n",
159
+ " <td>9</td>\n",
160
+ " <td>0.115741</td>\n",
161
+ " </tr>\n",
162
+ " <tr>\n",
163
+ " <th>3</th>\n",
164
+ " <td>12</td>\n",
165
+ " <td>0.115741</td>\n",
166
+ " </tr>\n",
167
+ " <tr>\n",
168
+ " <th>4</th>\n",
169
+ " <td>8</td>\n",
170
+ " <td>0.097222</td>\n",
171
+ " </tr>\n",
172
+ " </tbody>\n",
173
+ "</table>\n",
174
+ "</div>"
175
+ ],
176
+ "text/plain": [
177
+ " x P(X)\n",
178
+ "0 10 0.125000\n",
179
+ "1 11 0.125000\n",
180
+ "2 9 0.115741\n",
181
+ "3 12 0.115741\n",
182
+ "4 8 0.097222"
183
+ ]
184
+ },
185
+ "execution_count": 78,
186
+ "metadata": {},
187
+ "output_type": "execute_result"
188
+ }
189
+ ],
190
+ "source": []
191
+ },
192
+ {
193
+ "cell_type": "code",
194
+ "execution_count": 62,
195
+ "id": "42954464-bab8-44fc-9087-8c4f07bac679",
196
+ "metadata": {},
197
+ "outputs": [
198
+ {
199
+ "data": {
200
+ "text/plain": [
201
+ "<zip at 0x7f9ae912ac40>"
202
+ ]
203
+ },
204
+ "execution_count": 62,
205
+ "metadata": {},
206
+ "output_type": "execute_result"
207
+ }
208
+ ],
209
+ "source": []
210
+ },
211
+ {
212
+ "cell_type": "code",
213
+ "execution_count": 66,
214
+ "id": "4de2391b-e130-405b-bc26-b04584b2ed9c",
215
+ "metadata": {},
216
+ "outputs": [],
217
+ "source": []
218
+ },
219
+ {
220
+ "cell_type": "code",
221
+ "execution_count": 70,
222
+ "id": "56b9fd02-79ec-4c7d-9eca-17c04a7df44d",
223
+ "metadata": {},
224
+ "outputs": [],
225
+ "source": []
226
+ },
227
+ {
228
+ "cell_type": "code",
229
+ "execution_count": 71,
230
+ "id": "09e2316e-e242-48ab-9803-ef9e9212ea94",
231
+ "metadata": {},
232
+ "outputs": [],
233
+ "source": []
234
+ },
235
+ {
236
+ "cell_type": "code",
237
+ "execution_count": 72,
238
+ "id": "45a28a91-dc74-469b-8a1c-caa43ed0b907",
239
+ "metadata": {},
240
+ "outputs": [
241
+ {
242
+ "name": "stdout",
243
+ "output_type": "stream",
244
+ "text": [
245
+ "2268\n"
246
+ ]
247
+ }
248
+ ],
249
+ "source": [
250
+ "print(expectation)"
251
+ ]
252
+ },
253
+ {
254
+ "cell_type": "code",
255
+ "execution_count": null,
256
+ "id": "b4b63417-d541-44d1-98ad-2027865e1818",
257
+ "metadata": {},
258
+ "outputs": [],
259
+ "source": []
260
+ }
261
+ ],
262
+ "metadata": {
263
+ "kernelspec": {
264
+ "display_name": "Python 3 (ipykernel)",
265
+ "language": "python",
266
+ "name": "python3"
267
+ },
268
+ "language_info": {
269
+ "codemirror_mode": {
270
+ "name": "ipython",
271
+ "version": 3
272
+ },
273
+ "file_extension": ".py",
274
+ "mimetype": "text/x-python",
275
+ "name": "python",
276
+ "nbconvert_exporter": "python",
277
+ "pygments_lexer": "ipython3",
278
+ "version": "3.9.13"
279
+ }
280
+ },
281
+ "nbformat": 4,
282
+ "nbformat_minor": 5
283
+ }
training/src/.ipynb_checkpoints/MSML-602-HW1-checkpoint.ipynb ADDED
The diff for this file is too large to render. See raw diff
 
training/src/.ipynb_checkpoints/MSML602_Midterm_Karki-checkpoint.ipynb ADDED
@@ -0,0 +1,831 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "nbformat": 4,
3
+ "nbformat_minor": 0,
4
+ "metadata": {
5
+ "colab": {
6
+ "provenance": []
7
+ },
8
+ "kernelspec": {
9
+ "name": "python3",
10
+ "display_name": "Python 3"
11
+ },
12
+ "language_info": {
13
+ "name": "python"
14
+ }
15
+ },
16
+ "cells": [
17
+ {
18
+ "cell_type": "code",
19
+ "execution_count": 82,
20
+ "metadata": {
21
+ "cellView": "form",
22
+ "id": "AXI2uCSkxx7m"
23
+ },
24
+ "outputs": [],
25
+ "source": [
26
+ "#@title Setup\n",
27
+ "\n",
28
+ "%%capture\n",
29
+ "!pip install networkx pulp numpy pandas\n",
30
+ "\n",
31
+ "!rm -rf ./data/\n",
32
+ "!mkdir -p ./data/\n",
33
+ "!wget -c -O ./data/lastfm_asia.zip \"https://snap.stanford.edu/data/lastfm_asia.zip\"\n",
34
+ "!unzip -q ./data/lastfm_asia.zip -d ./data/"
35
+ ]
36
+ },
37
+ {
38
+ "cell_type": "code",
39
+ "source": [
40
+ "#@title Problem 3: Linear Programming\n",
41
+ "\n",
42
+ "\n",
43
+ "from pulp import *\n",
44
+ "from IPython.display import HTML, display\n",
45
+ "\n",
46
+ "def display_table(table):\n",
47
+ " display(HTML(\n",
48
+ " '<table><tr>{}</tr></table>'.format(\n",
49
+ " '</tr><tr>'.join(\n",
50
+ " '<td>{}</td>'.format('</td><td>'.join(str(_) for _ in row)) for row in table)\n",
51
+ " )\n",
52
+ " ))\n",
53
+ "\n",
54
+ "problem = LpProblem(\"MSML_602_Midterm_Q3\", LpMaximize)\n",
55
+ "\n",
56
+ "X = LpVariable(\"X\", cat=\"Integer\")\n",
57
+ "Y = LpVariable(\"Y\", cat=\"Integer\")\n",
58
+ "\n",
59
+ "problem += (5 * X) + (3 * Y), \"Objective\"\n",
60
+ "problem += X + (2 * Y) <= 14, \"Constraint 1\"\n",
61
+ "problem += (3* X) - Y >= 0, \"Constraint 2\"\n",
62
+ "problem += X - Y <= 2, \"Constraint 3\"\n",
63
+ "\n",
64
+ "problem.solve()\n",
65
+ "print(\"Solution:\\n\")\n",
66
+ "\n",
67
+ "data = [[\"Variable\", \"Value\"]] + [[v.name, v.varValue] for v in problem.variables()]\n",
68
+ "data += [[\"Max value for objective function: \", problem.objective.value()]]\n",
69
+ "display_table(data)"
70
+ ],
71
+ "metadata": {
72
+ "colab": {
73
+ "base_uri": "https://localhost:8080/",
74
+ "height": 140
75
+ },
76
+ "cellView": "form",
77
+ "id": "ALmlZnbcx-9e",
78
+ "outputId": "45e2c507-3265-4b22-e21a-2d6dbd72f05f"
79
+ },
80
+ "execution_count": 83,
81
+ "outputs": [
82
+ {
83
+ "output_type": "stream",
84
+ "name": "stdout",
85
+ "text": [
86
+ "Solution:\n",
87
+ "\n"
88
+ ]
89
+ },
90
+ {
91
+ "output_type": "display_data",
92
+ "data": {
93
+ "text/plain": [
94
+ "<IPython.core.display.HTML object>"
95
+ ],
96
+ "text/html": [
97
+ "<table><tr><td>Variable</td><td>Value</td></tr><tr><td>X</td><td>6.0</td></tr><tr><td>Y</td><td>4.0</td></tr><tr><td>Max value for objective function: </td><td>42.0</td></tr></table>"
98
+ ]
99
+ },
100
+ "metadata": {}
101
+ }
102
+ ]
103
+ },
104
+ {
105
+ "cell_type": "code",
106
+ "source": [
107
+ "#@title Problem 5: Graph Metrics\n",
108
+ "\n",
109
+ "import pandas as pd \n",
110
+ "import networkx as nx\n",
111
+ "import matplotlib.pyplot as plt\n",
112
+ "\n",
113
+ "df = pd.read_csv(\"/content/data/lasftm_asia/lastfm_asia_edges.csv\")\n",
114
+ "G = nx.from_pandas_edgelist(df, source=\"node_1\", target=\"node_2\")\n",
115
+ "shortest_path = nx.shortest_path_length(G, 0)\n",
116
+ "del shortest_path[0]\n",
117
+ "num = len(shortest_path)\n",
118
+ "total_length = sum([shortest_path[k] for k in shortest_path])\n",
119
+ "avg_shortest_path = total_length / num\n",
120
+ "print(f\"The average shortest path length from node 0 to all other nodes is: {avg_shortest_path}\")"
121
+ ],
122
+ "metadata": {
123
+ "colab": {
124
+ "base_uri": "https://localhost:8080/"
125
+ },
126
+ "cellView": "form",
127
+ "id": "87mMC-B1yJoq",
128
+ "outputId": "83ff28ec-7d51-4f6a-ced6-358538a58f83"
129
+ },
130
+ "execution_count": 84,
131
+ "outputs": [
132
+ {
133
+ "output_type": "stream",
134
+ "name": "stdout",
135
+ "text": [
136
+ "The average shortest path length from node 0 to all other nodes is: 5.651974288337925\n"
137
+ ]
138
+ }
139
+ ]
140
+ },
141
+ {
142
+ "cell_type": "markdown",
143
+ "source": [
144
+ "## Problem 6: Extracting Webpage Data"
145
+ ],
146
+ "metadata": {
147
+ "id": "mAiJRhb5iW5O"
148
+ }
149
+ },
150
+ {
151
+ "cell_type": "code",
152
+ "source": [
153
+ "#@title Scraping result\n",
154
+ "\n",
155
+ "import requests\n",
156
+ "from bs4 import BeautifulSoup\n",
157
+ "import pandas as pd \n",
158
+ "import numpy as np\n",
159
+ "\n",
160
+ "page = requests.get(\"https://www.worldometers.info/coronavirus/#countries\")\n",
161
+ "html = page.content\n",
162
+ "\n",
163
+ "soup = BeautifulSoup(html, 'html.parser')\n",
164
+ "table = soup.find(\"table\", {\"id\": \"main_table_countries_today\"})\n",
165
+ "\n",
166
+ "cols = [\n",
167
+ " '#', 'Country', 'TotalCases', 'NewCases', 'TotalDeaths', 'NewDeaths', 'TotalRecovered',\n",
168
+ " 'NewRecovered','ActiveCases','Serious,Critical','TotalCases/1M pop','Deaths/1M pop', \n",
169
+ " 'TotalTests', 'Tests/1M pop', 'Population', 'Continent', '1 Case every X ppl', '1 Death every X ppl',\n",
170
+ " '1 Test every X ppl', 'New Cases/1M pop', 'New Deaths/1M pop', 'Active Cases/1M pop'\n",
171
+ "]\n",
172
+ "\n",
173
+ "tbody = table.find(\"tbody\")\n",
174
+ "rows = tbody.find_all(\"tr\")\n",
175
+ "\n",
176
+ "data = []\n",
177
+ "for row in rows:\n",
178
+ " cells = row.find_all(\"td\")\n",
179
+ " values = [c.text for c in cells]\n",
180
+ " data.append(values)\n",
181
+ "\n",
182
+ "def sanitize_country_number(row):\n",
183
+ " val = row[\"#\"]\n",
184
+ " if not val.strip():\n",
185
+ " return np.NaN\n",
186
+ " else:\n",
187
+ " return val\n",
188
+ "\n",
189
+ "def fill_active_cases(row):\n",
190
+ " val = row[\"ActiveCases\"]\n",
191
+ " if not np.isnan(val):\n",
192
+ " return val\n",
193
+ " active_per_1_mil = row[\"Active Cases/1M pop\"]\n",
194
+ " if np.isnan(active_per_1_mil):\n",
195
+ " return np.nan\n",
196
+ " population = row[\"Population\"]\n",
197
+ " return (active_per_1_mil/1000000) * population\n",
198
+ "\n",
199
+ "def to_float(col):\n",
200
+ " def mapper(row):\n",
201
+ " if row[col] == \"N/A\":\n",
202
+ " return np.NaN\n",
203
+ " val = row[col]\n",
204
+ " val = val.replace(\",\", \"\").strip()\n",
205
+ " if not val:\n",
206
+ " return np.NaN\n",
207
+ " return float(val)\n",
208
+ " return mapper \n",
209
+ "\n",
210
+ "df = pd.DataFrame(data, columns=cols)\n",
211
+ "df.replace(r\"\\n\", \"\", regex=True, inplace=True)\n",
212
+ "\n",
213
+ "df.head()\n"
214
+ ],
215
+ "metadata": {
216
+ "colab": {
217
+ "base_uri": "https://localhost:8080/",
218
+ "height": 386
219
+ },
220
+ "cellView": "form",
221
+ "id": "Ay-ceRkkzcVg",
222
+ "outputId": "3b1e8535-f211-45ba-9b90-85c279e522ec"
223
+ },
224
+ "execution_count": 85,
225
+ "outputs": [
226
+ {
227
+ "output_type": "execute_result",
228
+ "data": {
229
+ "text/plain": [
230
+ " # Country TotalCases NewCases TotalDeaths NewDeaths \\\n",
231
+ "0 North America 118,308,960 +16,354 1,557,219 +76 \n",
232
+ "1 Asia 195,343,819 +168,618 1,491,630 +230 \n",
233
+ "2 Europe 235,496,414 +41,389 1,948,669 +165 \n",
234
+ "3 South America 64,557,158 +10,126 1,333,737 +79 \n",
235
+ "4 Oceania 12,691,699 +3,057 21,779 +9 \n",
236
+ "\n",
237
+ " TotalRecovered NewRecovered ActiveCases Serious,Critical ... TotalTests \\\n",
238
+ "0 113,762,872 +16,362 2,988,869 7,881 ... \n",
239
+ "1 188,186,652 +78,736 5,665,537 9,159 ... \n",
240
+ "2 229,427,346 +175,758 4,120,399 7,685 ... \n",
241
+ "3 62,884,992 +7,699 338,429 10,119 ... \n",
242
+ "4 12,512,305 157,615 97 ... \n",
243
+ "\n",
244
+ " Tests/1M pop Population Continent 1 Case every X ppl \\\n",
245
+ "0 North America \n",
246
+ "1 Asia \n",
247
+ "2 Europe \n",
248
+ "3 South America \n",
249
+ "4 Australia/Oceania \n",
250
+ "\n",
251
+ " 1 Death every X ppl 1 Test every X ppl New Cases/1M pop New Deaths/1M pop \\\n",
252
+ "0 \n",
253
+ "1 \n",
254
+ "2 \n",
255
+ "3 \n",
256
+ "4 \n",
257
+ "\n",
258
+ " Active Cases/1M pop \n",
259
+ "0 \n",
260
+ "1 \n",
261
+ "2 \n",
262
+ "3 \n",
263
+ "4 \n",
264
+ "\n",
265
+ "[5 rows x 22 columns]"
266
+ ],
267
+ "text/html": [
268
+ "\n",
269
+ " <div id=\"df-ba4843e7-ab30-4f7d-ab50-7ddf8afb1bbb\">\n",
270
+ " <div class=\"colab-df-container\">\n",
271
+ " <div>\n",
272
+ "<style scoped>\n",
273
+ " .dataframe tbody tr th:only-of-type {\n",
274
+ " vertical-align: middle;\n",
275
+ " }\n",
276
+ "\n",
277
+ " .dataframe tbody tr th {\n",
278
+ " vertical-align: top;\n",
279
+ " }\n",
280
+ "\n",
281
+ " .dataframe thead th {\n",
282
+ " text-align: right;\n",
283
+ " }\n",
284
+ "</style>\n",
285
+ "<table border=\"1\" class=\"dataframe\">\n",
286
+ " <thead>\n",
287
+ " <tr style=\"text-align: right;\">\n",
288
+ " <th></th>\n",
289
+ " <th>#</th>\n",
290
+ " <th>Country</th>\n",
291
+ " <th>TotalCases</th>\n",
292
+ " <th>NewCases</th>\n",
293
+ " <th>TotalDeaths</th>\n",
294
+ " <th>NewDeaths</th>\n",
295
+ " <th>TotalRecovered</th>\n",
296
+ " <th>NewRecovered</th>\n",
297
+ " <th>ActiveCases</th>\n",
298
+ " <th>Serious,Critical</th>\n",
299
+ " <th>...</th>\n",
300
+ " <th>TotalTests</th>\n",
301
+ " <th>Tests/1M pop</th>\n",
302
+ " <th>Population</th>\n",
303
+ " <th>Continent</th>\n",
304
+ " <th>1 Case every X ppl</th>\n",
305
+ " <th>1 Death every X ppl</th>\n",
306
+ " <th>1 Test every X ppl</th>\n",
307
+ " <th>New Cases/1M pop</th>\n",
308
+ " <th>New Deaths/1M pop</th>\n",
309
+ " <th>Active Cases/1M pop</th>\n",
310
+ " </tr>\n",
311
+ " </thead>\n",
312
+ " <tbody>\n",
313
+ " <tr>\n",
314
+ " <th>0</th>\n",
315
+ " <td></td>\n",
316
+ " <td>North America</td>\n",
317
+ " <td>118,308,960</td>\n",
318
+ " <td>+16,354</td>\n",
319
+ " <td>1,557,219</td>\n",
320
+ " <td>+76</td>\n",
321
+ " <td>113,762,872</td>\n",
322
+ " <td>+16,362</td>\n",
323
+ " <td>2,988,869</td>\n",
324
+ " <td>7,881</td>\n",
325
+ " <td>...</td>\n",
326
+ " <td></td>\n",
327
+ " <td></td>\n",
328
+ " <td></td>\n",
329
+ " <td>North America</td>\n",
330
+ " <td></td>\n",
331
+ " <td></td>\n",
332
+ " <td></td>\n",
333
+ " <td></td>\n",
334
+ " <td></td>\n",
335
+ " <td></td>\n",
336
+ " </tr>\n",
337
+ " <tr>\n",
338
+ " <th>1</th>\n",
339
+ " <td></td>\n",
340
+ " <td>Asia</td>\n",
341
+ " <td>195,343,819</td>\n",
342
+ " <td>+168,618</td>\n",
343
+ " <td>1,491,630</td>\n",
344
+ " <td>+230</td>\n",
345
+ " <td>188,186,652</td>\n",
346
+ " <td>+78,736</td>\n",
347
+ " <td>5,665,537</td>\n",
348
+ " <td>9,159</td>\n",
349
+ " <td>...</td>\n",
350
+ " <td></td>\n",
351
+ " <td></td>\n",
352
+ " <td></td>\n",
353
+ " <td>Asia</td>\n",
354
+ " <td></td>\n",
355
+ " <td></td>\n",
356
+ " <td></td>\n",
357
+ " <td></td>\n",
358
+ " <td></td>\n",
359
+ " <td></td>\n",
360
+ " </tr>\n",
361
+ " <tr>\n",
362
+ " <th>2</th>\n",
363
+ " <td></td>\n",
364
+ " <td>Europe</td>\n",
365
+ " <td>235,496,414</td>\n",
366
+ " <td>+41,389</td>\n",
367
+ " <td>1,948,669</td>\n",
368
+ " <td>+165</td>\n",
369
+ " <td>229,427,346</td>\n",
370
+ " <td>+175,758</td>\n",
371
+ " <td>4,120,399</td>\n",
372
+ " <td>7,685</td>\n",
373
+ " <td>...</td>\n",
374
+ " <td></td>\n",
375
+ " <td></td>\n",
376
+ " <td></td>\n",
377
+ " <td>Europe</td>\n",
378
+ " <td></td>\n",
379
+ " <td></td>\n",
380
+ " <td></td>\n",
381
+ " <td></td>\n",
382
+ " <td></td>\n",
383
+ " <td></td>\n",
384
+ " </tr>\n",
385
+ " <tr>\n",
386
+ " <th>3</th>\n",
387
+ " <td></td>\n",
388
+ " <td>South America</td>\n",
389
+ " <td>64,557,158</td>\n",
390
+ " <td>+10,126</td>\n",
391
+ " <td>1,333,737</td>\n",
392
+ " <td>+79</td>\n",
393
+ " <td>62,884,992</td>\n",
394
+ " <td>+7,699</td>\n",
395
+ " <td>338,429</td>\n",
396
+ " <td>10,119</td>\n",
397
+ " <td>...</td>\n",
398
+ " <td></td>\n",
399
+ " <td></td>\n",
400
+ " <td></td>\n",
401
+ " <td>South America</td>\n",
402
+ " <td></td>\n",
403
+ " <td></td>\n",
404
+ " <td></td>\n",
405
+ " <td></td>\n",
406
+ " <td></td>\n",
407
+ " <td></td>\n",
408
+ " </tr>\n",
409
+ " <tr>\n",
410
+ " <th>4</th>\n",
411
+ " <td></td>\n",
412
+ " <td>Oceania</td>\n",
413
+ " <td>12,691,699</td>\n",
414
+ " <td>+3,057</td>\n",
415
+ " <td>21,779</td>\n",
416
+ " <td>+9</td>\n",
417
+ " <td>12,512,305</td>\n",
418
+ " <td></td>\n",
419
+ " <td>157,615</td>\n",
420
+ " <td>97</td>\n",
421
+ " <td>...</td>\n",
422
+ " <td></td>\n",
423
+ " <td></td>\n",
424
+ " <td></td>\n",
425
+ " <td>Australia/Oceania</td>\n",
426
+ " <td></td>\n",
427
+ " <td></td>\n",
428
+ " <td></td>\n",
429
+ " <td></td>\n",
430
+ " <td></td>\n",
431
+ " <td></td>\n",
432
+ " </tr>\n",
433
+ " </tbody>\n",
434
+ "</table>\n",
435
+ "<p>5 rows × 22 columns</p>\n",
436
+ "</div>\n",
437
+ " <button class=\"colab-df-convert\" onclick=\"convertToInteractive('df-ba4843e7-ab30-4f7d-ab50-7ddf8afb1bbb')\"\n",
438
+ " title=\"Convert this dataframe to an interactive table.\"\n",
439
+ " style=\"display:none;\">\n",
440
+ " \n",
441
+ " <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\"viewBox=\"0 0 24 24\"\n",
442
+ " width=\"24px\">\n",
443
+ " <path d=\"M0 0h24v24H0V0z\" fill=\"none\"/>\n",
444
+ " <path d=\"M18.56 5.44l.94 2.06.94-2.06 2.06-.94-2.06-.94-.94-2.06-.94 2.06-2.06.94zm-11 1L8.5 8.5l.94-2.06 2.06-.94-2.06-.94L8.5 2.5l-.94 2.06-2.06.94zm10 10l.94 2.06.94-2.06 2.06-.94-2.06-.94-.94-2.06-.94 2.06-2.06.94z\"/><path d=\"M17.41 7.96l-1.37-1.37c-.4-.4-.92-.59-1.43-.59-.52 0-1.04.2-1.43.59L10.3 9.45l-7.72 7.72c-.78.78-.78 2.05 0 2.83L4 21.41c.39.39.9.59 1.41.59.51 0 1.02-.2 1.41-.59l7.78-7.78 2.81-2.81c.8-.78.8-2.07 0-2.86zM5.41 20L4 18.59l7.72-7.72 1.47 1.35L5.41 20z\"/>\n",
445
+ " </svg>\n",
446
+ " </button>\n",
447
+ " \n",
448
+ " <style>\n",
449
+ " .colab-df-container {\n",
450
+ " display:flex;\n",
451
+ " flex-wrap:wrap;\n",
452
+ " gap: 12px;\n",
453
+ " }\n",
454
+ "\n",
455
+ " .colab-df-convert {\n",
456
+ " background-color: #E8F0FE;\n",
457
+ " border: none;\n",
458
+ " border-radius: 50%;\n",
459
+ " cursor: pointer;\n",
460
+ " display: none;\n",
461
+ " fill: #1967D2;\n",
462
+ " height: 32px;\n",
463
+ " padding: 0 0 0 0;\n",
464
+ " width: 32px;\n",
465
+ " }\n",
466
+ "\n",
467
+ " .colab-df-convert:hover {\n",
468
+ " background-color: #E2EBFA;\n",
469
+ " box-shadow: 0px 1px 2px rgba(60, 64, 67, 0.3), 0px 1px 3px 1px rgba(60, 64, 67, 0.15);\n",
470
+ " fill: #174EA6;\n",
471
+ " }\n",
472
+ "\n",
473
+ " [theme=dark] .colab-df-convert {\n",
474
+ " background-color: #3B4455;\n",
475
+ " fill: #D2E3FC;\n",
476
+ " }\n",
477
+ "\n",
478
+ " [theme=dark] .colab-df-convert:hover {\n",
479
+ " background-color: #434B5C;\n",
480
+ " box-shadow: 0px 1px 3px 1px rgba(0, 0, 0, 0.15);\n",
481
+ " filter: drop-shadow(0px 1px 2px rgba(0, 0, 0, 0.3));\n",
482
+ " fill: #FFFFFF;\n",
483
+ " }\n",
484
+ " </style>\n",
485
+ "\n",
486
+ " <script>\n",
487
+ " const buttonEl =\n",
488
+ " document.querySelector('#df-ba4843e7-ab30-4f7d-ab50-7ddf8afb1bbb button.colab-df-convert');\n",
489
+ " buttonEl.style.display =\n",
490
+ " google.colab.kernel.accessAllowed ? 'block' : 'none';\n",
491
+ "\n",
492
+ " async function convertToInteractive(key) {\n",
493
+ " const element = document.querySelector('#df-ba4843e7-ab30-4f7d-ab50-7ddf8afb1bbb');\n",
494
+ " const dataTable =\n",
495
+ " await google.colab.kernel.invokeFunction('convertToInteractive',\n",
496
+ " [key], {});\n",
497
+ " if (!dataTable) return;\n",
498
+ "\n",
499
+ " const docLinkHtml = 'Like what you see? Visit the ' +\n",
500
+ " '<a target=\"_blank\" href=https://colab.research.google.com/notebooks/data_table.ipynb>data table notebook</a>'\n",
501
+ " + ' to learn more about interactive tables.';\n",
502
+ " element.innerHTML = '';\n",
503
+ " dataTable['output_type'] = 'display_data';\n",
504
+ " await google.colab.output.renderOutput(dataTable, element);\n",
505
+ " const docLink = document.createElement('div');\n",
506
+ " docLink.innerHTML = docLinkHtml;\n",
507
+ " element.appendChild(docLink);\n",
508
+ " }\n",
509
+ " </script>\n",
510
+ " </div>\n",
511
+ " </div>\n",
512
+ " "
513
+ ]
514
+ },
515
+ "metadata": {},
516
+ "execution_count": 85
517
+ }
518
+ ]
519
+ },
520
+ {
521
+ "cell_type": "code",
522
+ "source": [
523
+ "#@title Data sanitization / generation\n",
524
+ "\n",
525
+ "#@markdown Some of the countries (actually ships, in this case) did not have any population data, so I excluded those records from the dataset.\n",
526
+ "\n",
527
+ "#@markdown Some countries didn't have data for exact active cases, but had data for **active cases per 1 million population**. \n",
528
+ "#@markdown For these countries, I calculated their active cases by using the active cases per 1 million population data as follows: \n",
529
+ "\n",
530
+ "#@markdown ```Active Cases = (Active cases per 1 million population / 1,000,000) * Population```\n",
531
+ "\n",
532
+ "df[\"country_number\"] = df.apply(sanitize_country_number, axis=1)\n",
533
+ "\n",
534
+ "data_by_country = df[df[\"country_number\"].notna()].copy()\n",
535
+ "data_by_country[\"ActiveCases\"] = data_by_country.apply(to_float(\"ActiveCases\"), axis=1)\n",
536
+ "data_by_country[\"Active Cases/1M pop\"] = data_by_country.apply(to_float(\"Active Cases/1M pop\"), axis=1)\n",
537
+ "data_by_country[\"Population\"] = data_by_country.apply(to_float(\"Population\"), axis=1)\n",
538
+ "data_by_country[\"ActiveCases\"] = data_by_country.apply(fill_active_cases, axis=1)\n",
539
+ "data_by_country[data_by_country[\"ActiveCases\"] == \"N/A\"].head(20)\n",
540
+ "aggregated = data_by_country.groupby(\"Country\").agg({'ActiveCases':'mean', 'Population':'sum'}, as_index=False)\n",
541
+ "aggregated.reset_index(inplace=True)\n",
542
+ "dropped_countries = aggregated[aggregated[\"Population\"] == 0 ]\n",
543
+ "aggregated = aggregated[aggregated[\"Population\"] != 0 ]\n",
544
+ "aggregated[\"PercentageInfected\"] = aggregated.apply(lambda x: x[\"ActiveCases\"]/x[\"Population\"], axis=1)\n",
545
+ "aggregated.sort_values([\"PercentageInfected\"], ascending=False, inplace=True)\n",
546
+ "\n",
547
+ "print(\"These were the countries(ships) that didn't have population data:\\n\")\n",
548
+ "print(dropped_countries)\n"
549
+ ],
550
+ "metadata": {
551
+ "colab": {
552
+ "base_uri": "https://localhost:8080/"
553
+ },
554
+ "cellView": "form",
555
+ "id": "Roitzj22-VO5",
556
+ "outputId": "5dc61fa2-31c9-4fa4-828c-c9f88fb449e2"
557
+ },
558
+ "execution_count": 86,
559
+ "outputs": [
560
+ {
561
+ "output_type": "stream",
562
+ "name": "stdout",
563
+ "text": [
564
+ "These were the countries(ships) that didn't have population data:\n",
565
+ "\n",
566
+ " Country ActiveCases Population\n",
567
+ "56 Diamond Princess 0.0 0.0\n",
568
+ "120 MS Zaandam 0.0 0.0\n"
569
+ ]
570
+ }
571
+ ]
572
+ },
573
+ {
574
+ "cell_type": "code",
575
+ "source": [
576
+ "#@title Average active cases & the proportion of the total population affected\n",
577
+ "\n",
578
+ "from IPython.display import HTML, display\n",
579
+ "\n",
580
+ "def display_table(table):\n",
581
+ " display(HTML(\n",
582
+ " '<table><tr>{}</tr></table>'.format(\n",
583
+ " '</tr><tr>'.join(\n",
584
+ " '<td>{}</td>'.format('</td><td>'.join(str(_) for _ in row)) for row in table)\n",
585
+ " )\n",
586
+ " ))\n",
587
+ "\n",
588
+ "avg_active_cases = aggregated[\"ActiveCases\"].mean()\n",
589
+ "\n",
590
+ "aggr = aggregated.agg({\"ActiveCases\": \"sum\", \"Population\": \"sum\"}, as_index=False)\n",
591
+ "final_df = aggr.to_frame().T\n",
592
+ "final_df[\"PercentageInfected\"] = final_df.apply(lambda x: (x[\"ActiveCases\"]/x[\"Population\"]) * 100, axis=1)\n",
593
+ "percentage_infected = final_df[\"PercentageInfected\"].to_numpy()[0]\n",
594
+ "\n",
595
+ "display(HTML(\n",
596
+ " \"\"\"\n",
597
+ " <h3>Result:</h3>\n",
598
+ " <br>\n",
599
+ " <table border=\"1\">\n",
600
+ " <tr>\n",
601
+ " <th align=\"left\">Average active cases:</th>\n",
602
+ " <td>{0:.2f}</td>\n",
603
+ " </tr>\n",
604
+ " <tr>\n",
605
+ " <th align=\"left\">Proportion of total <br>population currently infected:</th>\n",
606
+ " <td>{1:.2f}%</td>\n",
607
+ " </tr>\n",
608
+ " </table>\n",
609
+ " <br>\n",
610
+ " \"\"\".format(avg_active_cases, percentage_infected))\n",
611
+ ")\n",
612
+ "\n",
613
+ "\n",
614
+ "print(\"\"\"\n",
615
+ "I was unsure whether the problem wanted the percentage of the population\n",
616
+ "affected for each country, so I have included the percentage for each country \n",
617
+ "as well, just in case:\n",
618
+ "\"\"\")\n",
619
+ "aggregated.head()"
620
+ ],
621
+ "metadata": {
622
+ "colab": {
623
+ "base_uri": "https://localhost:8080/",
624
+ "height": 439
625
+ },
626
+ "cellView": "form",
627
+ "id": "lRtwSfqSAPAY",
628
+ "outputId": "a7037d5d-fbd6-48b3-e47b-32090720dfd1"
629
+ },
630
+ "execution_count": 87,
631
+ "outputs": [
632
+ {
633
+ "output_type": "display_data",
634
+ "data": {
635
+ "text/plain": [
636
+ "<IPython.core.display.HTML object>"
637
+ ],
638
+ "text/html": [
639
+ "\n",
640
+ " <h3>Result:</h3>\n",
641
+ " <br>\n",
642
+ " <table border=\"1\">\n",
643
+ " <tr>\n",
644
+ " <th align=\"left\">Average active cases:</th>\n",
645
+ " <td>60038.20</td>\n",
646
+ " </tr>\n",
647
+ " <tr>\n",
648
+ " <th align=\"left\">Proportion of total <br>population currently infected:</th>\n",
649
+ " <td>0.17%</td>\n",
650
+ " </tr>\n",
651
+ " </table>\n",
652
+ " <br>\n",
653
+ " "
654
+ ]
655
+ },
656
+ "metadata": {}
657
+ },
658
+ {
659
+ "output_type": "stream",
660
+ "name": "stdout",
661
+ "text": [
662
+ "\n",
663
+ "I was unsure whether the problem wanted the percentage of the population\n",
664
+ "affected for each country, so I have included the percentage for each country \n",
665
+ "as well, just in case:\n",
666
+ "\n"
667
+ ]
668
+ },
669
+ {
670
+ "output_type": "execute_result",
671
+ "data": {
672
+ "text/plain": [
673
+ " Country ActiveCases Population PercentageInfected\n",
674
+ "129 Martinique 222576.901869 374087.0 0.594987\n",
675
+ "68 Faeroe Islands 26936.998989 49233.0 0.547133\n",
676
+ "195 St. Barth 4854.999825 9945.0 0.488185\n",
677
+ "84 Guadeloupe 193026.939904 399794.0 0.482816\n",
678
+ "93 Iceland 130899.111498 345393.0 0.378986"
679
+ ],
680
+ "text/html": [
681
+ "\n",
682
+ " <div id=\"df-5b3415ae-443b-4212-be42-19efc6bff309\">\n",
683
+ " <div class=\"colab-df-container\">\n",
684
+ " <div>\n",
685
+ "<style scoped>\n",
686
+ " .dataframe tbody tr th:only-of-type {\n",
687
+ " vertical-align: middle;\n",
688
+ " }\n",
689
+ "\n",
690
+ " .dataframe tbody tr th {\n",
691
+ " vertical-align: top;\n",
692
+ " }\n",
693
+ "\n",
694
+ " .dataframe thead th {\n",
695
+ " text-align: right;\n",
696
+ " }\n",
697
+ "</style>\n",
698
+ "<table border=\"1\" class=\"dataframe\">\n",
699
+ " <thead>\n",
700
+ " <tr style=\"text-align: right;\">\n",
701
+ " <th></th>\n",
702
+ " <th>Country</th>\n",
703
+ " <th>ActiveCases</th>\n",
704
+ " <th>Population</th>\n",
705
+ " <th>PercentageInfected</th>\n",
706
+ " </tr>\n",
707
+ " </thead>\n",
708
+ " <tbody>\n",
709
+ " <tr>\n",
710
+ " <th>129</th>\n",
711
+ " <td>Martinique</td>\n",
712
+ " <td>222576.901869</td>\n",
713
+ " <td>374087.0</td>\n",
714
+ " <td>0.594987</td>\n",
715
+ " </tr>\n",
716
+ " <tr>\n",
717
+ " <th>68</th>\n",
718
+ " <td>Faeroe Islands</td>\n",
719
+ " <td>26936.998989</td>\n",
720
+ " <td>49233.0</td>\n",
721
+ " <td>0.547133</td>\n",
722
+ " </tr>\n",
723
+ " <tr>\n",
724
+ " <th>195</th>\n",
725
+ " <td>St. Barth</td>\n",
726
+ " <td>4854.999825</td>\n",
727
+ " <td>9945.0</td>\n",
728
+ " <td>0.488185</td>\n",
729
+ " </tr>\n",
730
+ " <tr>\n",
731
+ " <th>84</th>\n",
732
+ " <td>Guadeloupe</td>\n",
733
+ " <td>193026.939904</td>\n",
734
+ " <td>399794.0</td>\n",
735
+ " <td>0.482816</td>\n",
736
+ " </tr>\n",
737
+ " <tr>\n",
738
+ " <th>93</th>\n",
739
+ " <td>Iceland</td>\n",
740
+ " <td>130899.111498</td>\n",
741
+ " <td>345393.0</td>\n",
742
+ " <td>0.378986</td>\n",
743
+ " </tr>\n",
744
+ " </tbody>\n",
745
+ "</table>\n",
746
+ "</div>\n",
747
+ " <button class=\"colab-df-convert\" onclick=\"convertToInteractive('df-5b3415ae-443b-4212-be42-19efc6bff309')\"\n",
748
+ " title=\"Convert this dataframe to an interactive table.\"\n",
749
+ " style=\"display:none;\">\n",
750
+ " \n",
751
+ " <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\"viewBox=\"0 0 24 24\"\n",
752
+ " width=\"24px\">\n",
753
+ " <path d=\"M0 0h24v24H0V0z\" fill=\"none\"/>\n",
754
+ " <path d=\"M18.56 5.44l.94 2.06.94-2.06 2.06-.94-2.06-.94-.94-2.06-.94 2.06-2.06.94zm-11 1L8.5 8.5l.94-2.06 2.06-.94-2.06-.94L8.5 2.5l-.94 2.06-2.06.94zm10 10l.94 2.06.94-2.06 2.06-.94-2.06-.94-.94-2.06-.94 2.06-2.06.94z\"/><path d=\"M17.41 7.96l-1.37-1.37c-.4-.4-.92-.59-1.43-.59-.52 0-1.04.2-1.43.59L10.3 9.45l-7.72 7.72c-.78.78-.78 2.05 0 2.83L4 21.41c.39.39.9.59 1.41.59.51 0 1.02-.2 1.41-.59l7.78-7.78 2.81-2.81c.8-.78.8-2.07 0-2.86zM5.41 20L4 18.59l7.72-7.72 1.47 1.35L5.41 20z\"/>\n",
755
+ " </svg>\n",
756
+ " </button>\n",
757
+ " \n",
758
+ " <style>\n",
759
+ " .colab-df-container {\n",
760
+ " display:flex;\n",
761
+ " flex-wrap:wrap;\n",
762
+ " gap: 12px;\n",
763
+ " }\n",
764
+ "\n",
765
+ " .colab-df-convert {\n",
766
+ " background-color: #E8F0FE;\n",
767
+ " border: none;\n",
768
+ " border-radius: 50%;\n",
769
+ " cursor: pointer;\n",
770
+ " display: none;\n",
771
+ " fill: #1967D2;\n",
772
+ " height: 32px;\n",
773
+ " padding: 0 0 0 0;\n",
774
+ " width: 32px;\n",
775
+ " }\n",
776
+ "\n",
777
+ " .colab-df-convert:hover {\n",
778
+ " background-color: #E2EBFA;\n",
779
+ " box-shadow: 0px 1px 2px rgba(60, 64, 67, 0.3), 0px 1px 3px 1px rgba(60, 64, 67, 0.15);\n",
780
+ " fill: #174EA6;\n",
781
+ " }\n",
782
+ "\n",
783
+ " [theme=dark] .colab-df-convert {\n",
784
+ " background-color: #3B4455;\n",
785
+ " fill: #D2E3FC;\n",
786
+ " }\n",
787
+ "\n",
788
+ " [theme=dark] .colab-df-convert:hover {\n",
789
+ " background-color: #434B5C;\n",
790
+ " box-shadow: 0px 1px 3px 1px rgba(0, 0, 0, 0.15);\n",
791
+ " filter: drop-shadow(0px 1px 2px rgba(0, 0, 0, 0.3));\n",
792
+ " fill: #FFFFFF;\n",
793
+ " }\n",
794
+ " </style>\n",
795
+ "\n",
796
+ " <script>\n",
797
+ " const buttonEl =\n",
798
+ " document.querySelector('#df-5b3415ae-443b-4212-be42-19efc6bff309 button.colab-df-convert');\n",
799
+ " buttonEl.style.display =\n",
800
+ " google.colab.kernel.accessAllowed ? 'block' : 'none';\n",
801
+ "\n",
802
+ " async function convertToInteractive(key) {\n",
803
+ " const element = document.querySelector('#df-5b3415ae-443b-4212-be42-19efc6bff309');\n",
804
+ " const dataTable =\n",
805
+ " await google.colab.kernel.invokeFunction('convertToInteractive',\n",
806
+ " [key], {});\n",
807
+ " if (!dataTable) return;\n",
808
+ "\n",
809
+ " const docLinkHtml = 'Like what you see? Visit the ' +\n",
810
+ " '<a target=\"_blank\" href=https://colab.research.google.com/notebooks/data_table.ipynb>data table notebook</a>'\n",
811
+ " + ' to learn more about interactive tables.';\n",
812
+ " element.innerHTML = '';\n",
813
+ " dataTable['output_type'] = 'display_data';\n",
814
+ " await google.colab.output.renderOutput(dataTable, element);\n",
815
+ " const docLink = document.createElement('div');\n",
816
+ " docLink.innerHTML = docLinkHtml;\n",
817
+ " element.appendChild(docLink);\n",
818
+ " }\n",
819
+ " </script>\n",
820
+ " </div>\n",
821
+ " </div>\n",
822
+ " "
823
+ ]
824
+ },
825
+ "metadata": {},
826
+ "execution_count": 87
827
+ }
828
+ ]
829
+ }
830
+ ]
831
+ }
training/{MSML-602-Final-Project-Final-Version.ipynb → src/MSML-602-Final-Project-Final-Version.ipynb} RENAMED
File without changes
training/{MSML-602-Final-Project.ipynb → src/MSML-602-Final-Project.ipynb} RENAMED
File without changes
training/{downloader.py → src/downloader.py} RENAMED
File without changes
web/.DS_Store ADDED
Binary file (6.15 kB). View file
 
web/.dockerignore ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ .git
2
+ node_modules
web/.gitignore ADDED
@@ -0,0 +1 @@
 
 
1
+ .python-version
web/Dockerfile.backend ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ FROM tensorflow/tensorflow:2.11.0
2
+
3
+ WORKDIR /app
4
+
5
+ COPY ./requirements.txt /app/requirements.txt
6
+
7
+ RUN pip install -r requirements.txt
8
+
9
+ COPY ./src /app
10
+
11
+ CMD ["python3", "-m", "flask", "run", "--host=0.0.0.0"]
web/Dockerfile.frontend ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ FROM node:18-alpine3.15
2
+
3
+ WORKDIR /app
4
+
5
+ COPY package.json ./
6
+
7
+ COPY package-lock.json ./
8
+
9
+ RUN npm update && npm install
10
+
11
+ COPY . .
12
+
13
+ CMD ["npm", "start"]
web/Makefile ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .PHONY: build-backend
2
+ build-backend: ## Build backend services
3
+ docker build -f Dockerfile.backend -t pred-backend ./backend
4
+
5
+ .PHONY: build-frontend
6
+ build-frontend: ## Build frontend services
7
+ docker build -f Dockerfile.frontend -t pred-frontend ./frontend
8
+
9
+ .PHONY: up-prod
10
+ up-prod: ## Build backend services
11
+ docker build -f Dockerfile.backend -t pred-backend ./backend
12
+ docker build -f Dockerfile.frontend -t pred-frontend ./frontend
13
+ docker-compose -f docker-compose.yml -f docker-compose.prod.yml up -d
14
+
15
+ .PHONY: up-dev
16
+ up-dev: ## Build backend services
17
+ docker build -f Dockerfile.backend -t pred-backend ./backend
18
+ docker build -f Dockerfile.frontend -t pred-frontend ./frontend
19
+ docker-compose up -d
web/README.md ADDED
@@ -0,0 +1 @@
 
 
1
+ MSML 602 Assignments/Projects
web/backend/.DS_Store ADDED
Binary file (6.15 kB). View file
 
web/backend/.dockerignore ADDED
@@ -0,0 +1 @@
 
 
1
+ .git
web/backend/.gitignore ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ .python-version
2
+ __pycache__
web/backend/README.md ADDED
@@ -0,0 +1 @@
 
 
1
+ MSML 602 Assignments/Projects
web/backend/requirements.txt ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ flask==2.2.2
2
+ flask-cors==3.0.10
3
+ pandas==1.5.0
4
+ numpy==1.23.3
5
+ scipy==1.9.1
6
+ scikit-learn==1.1.2
7
+ requests-cache==0.9.7
web/backend/src/.DS_Store ADDED
Binary file (6.15 kB). View file
 
web/backend/src/app.py ADDED
@@ -0,0 +1,244 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from flask import Flask, request
2
+ import tensorflow as tf
3
+ from datetime import datetime, timedelta
4
+ import logging
5
+ import requests
6
+ import requests_cache
7
+ import pandas as pd
8
+ import json
9
+ import numpy as np
10
+ import pickle
11
+ import math
12
+ import pytz
13
+
14
+ from flask_cors import CORS, cross_origin
15
+
16
+
17
+ session = requests_cache.CachedSession('requests-cache')
18
+
19
+ app = Flask(__name__)
20
+ cors = CORS(app)
21
+ app.config['CORS_HEADERS'] = 'Content-Type'
22
+
23
+ app.logger.setLevel(logging.INFO)
24
+ DATE_FORMAT = "%Y-%m-%d %H:%M:%S"
25
+ API_KEY = "e1f10a1e78da46f5b10a1e78da96f525"
26
+ BASE_URL = "https://api.weather.com/v1/location/KDCA:9:US/observations/historical.json?apiKey={api_key}&units=e&startDate={start_date}&endDate={end_date}"
27
+ model = tf.keras.models.load_model('/app/model', compile=False)
28
+
29
+ scaler = pickle.load(open('./model/scaler.pkl','rb'))
30
+ cols_to_scale = ["pressure", "wspd","heat_index","dewPt", "rh", "vis", "wc", "wdir_degree", "clds_ordinal",
31
+ "day_sin", "day_cos", "year_sin", "year_cos", "wdir_sin", "wdir_cos"]
32
+
33
+ def get_NaN_counts(df):
34
+ nan_counts = df.isna().sum()
35
+ return pd.concat([nan_counts, ((nan_counts/len(df))*100).round(2)],
36
+ axis=1,
37
+ keys=["NaN count", "Percentage"])
38
+
39
+ def clds_to_ordinal(row):
40
+ mapping = {
41
+ "SKC": 0,
42
+ "CLR": 0,
43
+ "FEW": 1,
44
+ "SCT": 2,
45
+ "BKN": 3,
46
+ "OVC": 4,
47
+ "VV": 5
48
+ }
49
+ clds = row["clds"]
50
+ if pd.isnull(clds):
51
+ return np.NaN
52
+ return mapping[clds]
53
+
54
+ def clean_wspd(row):
55
+ if row["wdir_cardinal"] == "CALM":
56
+ return 0
57
+ return row["wspd"]
58
+
59
+ def restrict_wspd(row):
60
+ if row["wspd"] < 0:
61
+ return 0
62
+ return row["wspd"]
63
+
64
+ def restrict_rh(row):
65
+ if row["rh"] < 0:
66
+ return 0
67
+ if row["rh"] > 100:
68
+ return 100
69
+ return row["rh"]
70
+
71
+ def clean_wdir(row):
72
+ if row["wdir_cardinal"] == "CALM":
73
+ return 0
74
+ return row["wdir"]
75
+
76
+ def wdir_cardinal_to_deg(row):
77
+ wdir = row["wdir"]
78
+ if not pd.isnull(wdir):
79
+ return wdir
80
+ cardinal_directions = {
81
+ 'N': 0,
82
+ 'NNE': 22.5,
83
+ 'NE': 45,
84
+ 'ENE': 67.5,
85
+ 'E': 90,
86
+ 'ESE': 112.5,
87
+ 'SE': 135,
88
+ 'SSE': 157.5,
89
+ 'S': 180,
90
+ 'SSW': 202.5,
91
+ 'SW': 225,
92
+ 'WSW': 247.5,
93
+ 'W': 270,
94
+ 'WNW': 292.5,
95
+ 'NW': 315,
96
+ 'NNW': 337.5,
97
+ 'CALM': 0,
98
+ 'VAR': -1
99
+ }
100
+ wdir_cardinal = row["wdir_cardinal"]
101
+
102
+ return cardinal_directions[wdir_cardinal] if wdir_cardinal in cardinal_directions else np.NaN
103
+
104
+ def prepare_dataframe(_df, start_timestamp, end_timestamp):
105
+ dates_df = pd.DataFrame()
106
+ dates_df["obs_timestamp"] = pd.date_range(start_timestamp, end_timestamp, freq="H")
107
+
108
+ _df = dates_df.merge(_df, how='left', on='obs_timestamp')
109
+ _df = _df.astype(
110
+ {
111
+ 'temp': 'float',
112
+ 'pressure': 'float',
113
+ 'wspd': 'float',
114
+ 'heat_index': 'float'
115
+ },
116
+ )
117
+
118
+ _df["wdir_cardinal"].fillna(method="bfill", inplace=True)
119
+ _df["wdir_degree"] = _df.apply(wdir_cardinal_to_deg, axis=1)
120
+ _df["clds_ordinal"] = _df.apply(clds_to_ordinal, axis=1)
121
+ _df["temp"].interpolate("polynomial", order=2, inplace=True)
122
+ _df["pressure"].interpolate("polynomial", order=2, inplace=True)
123
+ _df["heat_index"].interpolate("polynomial", order=2, inplace=True)
124
+ _df["wdir"].fillna(method="bfill", inplace=True)
125
+ _df["wdir"] = _df.apply(clean_wdir, axis=1)
126
+ _df["wspd"] = _df.apply(clean_wspd, axis=1)
127
+ _df["wspd"].interpolate("polynomial", order=2, inplace=True)
128
+ _df["wspd"] = _df.apply(restrict_wspd, axis=1)
129
+ _df["clds"].fillna(method="bfill", inplace=True)
130
+ _df["clds_ordinal"].interpolate("linear", inplace=True)
131
+ _df["dewPt"].interpolate("polynomial", order=2, inplace=True)
132
+ _df["rh"].interpolate("polynomial", order=2, inplace=True)
133
+ _df["rh"] = _df.apply(restrict_rh, axis=1)
134
+ _df["wc"].interpolate("polynomial", order=2, inplace=True)
135
+ _df["vis"].fillna(method="bfill", inplace=True)
136
+ _df.drop(["wdir", "wdir_cardinal", "clds"], axis=1, inplace=True)
137
+
138
+ _df = _df.dropna()
139
+
140
+ _df = _df.sort_values(by=['obs_timestamp'])
141
+ date_time = _df.pop('obs_timestamp')
142
+ timestamp_s = date_time.map(pd.Timestamp.timestamp)
143
+ day = 24*60*60
144
+ year = (365.2425)*day
145
+
146
+ _df['day_sin'] = np.sin(timestamp_s * (2 * np.pi / day))
147
+ _df['day_cos'] = np.cos(timestamp_s * (2 * np.pi / day))
148
+ _df['year_sin'] = np.sin(timestamp_s * (2 * np.pi / year))
149
+ _df['year_cos'] = np.cos(timestamp_s * (2 * np.pi / year))
150
+ _df['wdir_sin'] = np.sin(_df["wdir_degree"])
151
+ _df['wdir_cos'] = np.cos(_df["wdir_degree"])
152
+
153
+ return _df, date_time
154
+
155
+
156
+ def map_data_to_dataframe(data, target_date):
157
+ end_timestamp = target_date - timedelta(minutes=8)
158
+ start_timestamp = end_timestamp - timedelta(days=8) + timedelta(hours=1)
159
+
160
+ df = pd.read_json(json.dumps(data))
161
+ df["obs_timestamp"] = df.apply(lambda x: datetime.fromtimestamp(x["valid_time_gmt"]).strftime(DATE_FORMAT), axis=1)
162
+ df = df.astype({'obs_timestamp': 'datetime64[ns]'})
163
+ initial_cols = ["temp", "obs_timestamp", "pressure", "wspd", "heat_index", "dewPt", "rh", "vis", "wc", "wdir", "wdir_cardinal", "clds" ]
164
+ df = df[initial_cols]
165
+
166
+ df, _ = prepare_dataframe(df, start_timestamp.strftime(DATE_FORMAT), end_timestamp.strftime(DATE_FORMAT))
167
+ return df
168
+
169
+
170
+ def map_to_timestamp(predictions, target_date):
171
+ start = target_date + timedelta(hours=1)
172
+ end = start + timedelta(hours=23)
173
+ target_hours = [x.to_pydatetime().strftime(DATE_FORMAT) for x in pd.date_range(start, end, freq="H")]
174
+ return { h: predictions[idx] for idx, h in enumerate(target_hours)}
175
+
176
+ def predict(df):
177
+ predict_df = df[-168:]
178
+ predict_df_features = predict_df[cols_to_scale]
179
+ predict_df_features = scaler.transform(predict_df_features.values)
180
+ predict_df[cols_to_scale] = predict_df_features
181
+ predictions = model(predict_df.to_numpy().reshape(1, 168, 16))
182
+ return predictions
183
+
184
+ def predict_for_date(target_date):
185
+ date_format = "%Y%m%d"
186
+ start_date = target_date - timedelta(days=9)
187
+ res = session.get(BASE_URL.format(api_key=API_KEY, start_date=start_date.strftime(date_format), end_date=target_date.strftime(date_format)))
188
+ data = res.json()
189
+ df = map_data_to_dataframe(data["observations"], target_date)
190
+ predictions = predict(df)
191
+ flattened = list(map(lambda x: math.floor(x), predictions.numpy().flatten().tolist()))
192
+ return map_to_timestamp(flattened, target_date)
193
+
194
+ def get_actual_temperatures(target_date):
195
+ date_format = "%Y%m%d"
196
+ start_date = target_date - timedelta(days=1) #Because api uses utc
197
+ end_date = target_date + timedelta(days=1)
198
+ start_date_str = (start_date - timedelta(days=1)).strftime(date_format)
199
+ end_date_str = end_date.strftime(date_format)
200
+ today = datetime.today().astimezone(pytz.timezone("America/New_York")).date()
201
+ req_url = BASE_URL.format(api_key=API_KEY, start_date=start_date_str, end_date=end_date_str)
202
+ if target_date.date() < today:
203
+ res = session.get(req_url)
204
+ else:
205
+ res = requests.get(req_url)
206
+ start_timestamp = target_date + timedelta(minutes=52)
207
+ end_timestamp = end_date + timedelta(days=1) - timedelta(minutes=8)
208
+
209
+
210
+ data = res.json()
211
+ df = pd.read_json(json.dumps(data["observations"]))
212
+ df["obs_timestamp"] = df.apply(lambda x: datetime.fromtimestamp(x["valid_time_gmt"]).astimezone(pytz.timezone("America/New_York")).strftime(DATE_FORMAT), axis=1)
213
+ df = df.astype({'obs_timestamp': 'datetime64[ns]'})
214
+ initial_cols = ["temp", "obs_timestamp"]
215
+ df = df[initial_cols]
216
+ dates_df = pd.DataFrame()
217
+ dates_df["obs_timestamp"] = pd.date_range(start_timestamp, end_timestamp, freq="H")
218
+ df = dates_df.merge(df, how='left', on='obs_timestamp')
219
+
220
+ df["obs_timestamp"] = df.apply(lambda x: (x["obs_timestamp"] + timedelta(minutes=8)).strftime(DATE_FORMAT), axis=1)
221
+ dicts = df.to_dict("records")
222
+ reduced = { k["obs_timestamp"]: k["temp"] for k in dicts}
223
+ for k in reduced:
224
+ if np.isnan(reduced[k]):
225
+ reduced[k] = None
226
+ return reduced
227
+
228
+ @app.route("/predictions")
229
+ @cross_origin()
230
+ def get_predictions():
231
+ today = datetime.today().astimezone(pytz.timezone("America/New_York")).date()
232
+ target_date = datetime.strptime(request.args["target_date"], "%Y-%m-%d")
233
+ app.logger.info(today)
234
+ app.logger.info(target_date)
235
+ # target_dates = list(filter(lambda x: x < today, [x.to_pydatetime() for x in pd.date_range(start_date, end_date, freq="D").to_list()]))
236
+ predictions = predict_for_date(target_date)
237
+ actual_temp = get_actual_temperatures(target_date) if target_date.date() <= today else None
238
+
239
+ merged = { k: {"predicted": predictions[k], "actual": actual_temp[k] if actual_temp else None} for k in predictions}
240
+ response = app.response_class(response=json.dumps(merged),
241
+ status=200,
242
+ mimetype='application/json')
243
+ return response
244
+
web/backend/src/model/keras_metadata.pb ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+
2
+ �%root"_tf_keras_sequential*�%{"name": "sequential", "trainable": true, "expects_training_arg": true, "dtype": "float32", "batch_input_shape": null, "must_restore_from_config": false, "class_name": "Sequential", "config": {"name": "sequential", "layers": [{"class_name": "InputLayer", "config": {"batch_input_shape": {"class_name": "__tuple__", "items": [null, 168, 16]}, "dtype": "float32", "sparse": false, "ragged": false, "name": "lstm_input"}}, {"class_name": "LSTM", "config": {"name": "lstm", "trainable": true, "dtype": "float32", "return_sequences": false, "return_state": false, "go_backwards": false, "stateful": false, "unroll": false, "time_major": false, "units": 12, "activation": "tanh", "recurrent_activation": "sigmoid", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}, "shared_object_id": 1}, "recurrent_initializer": {"class_name": "Orthogonal", "config": {"gain": 1.0, "seed": null}, "shared_object_id": 2}, "bias_initializer": {"class_name": "Zeros", "config": {}, "shared_object_id": 3}, "unit_forget_bias": true, "kernel_regularizer": null, "recurrent_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "recurrent_constraint": null, "bias_constraint": null, "dropout": 0.0, "recurrent_dropout": 0.0, "implementation": 2}}, {"class_name": "Dense", "config": {"name": "dense", "trainable": true, "dtype": "float32", "units": 24, "activation": "linear", "use_bias": true, "kernel_initializer": {"class_name": "Zeros", "config": {}}, "bias_initializer": {"class_name": "Zeros", "config": {}}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}}, {"class_name": "Reshape", "config": {"name": "reshape", "trainable": true, "dtype": "float32", "target_shape": {"class_name": "__tuple__", "items": [24, 1]}}}]}, "shared_object_id": 10, "build_input_shape": {"class_name": "TensorShape", "items": [null, 168, 16]}, "is_graph_network": true, "full_save_spec": {"class_name": "__tuple__", "items": [[{"class_name": "TypeSpec", "type_spec": "tf.TensorSpec", "serialized": [{"class_name": "TensorShape", "items": [null, 168, 16]}, "float32", "lstm_input"]}], {}]}, "save_spec": {"class_name": "TypeSpec", "type_spec": "tf.TensorSpec", "serialized": [{"class_name": "TensorShape", "items": [null, 168, 16]}, "float32", "lstm_input"]}, "keras_version": "2.9.0", "backend": "tensorflow", "model_config": {"class_name": "Sequential", "config": {"name": "sequential", "layers": [{"class_name": "InputLayer", "config": {"batch_input_shape": {"class_name": "__tuple__", "items": [null, 168, 16]}, "dtype": "float32", "sparse": false, "ragged": false, "name": "lstm_input"}, "shared_object_id": 0}, {"class_name": "LSTM", "config": {"name": "lstm", "trainable": true, "dtype": "float32", "return_sequences": false, "return_state": false, "go_backwards": false, "stateful": false, "unroll": false, "time_major": false, "units": 12, "activation": "tanh", "recurrent_activation": "sigmoid", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}, "shared_object_id": 1}, "recurrent_initializer": {"class_name": "Orthogonal", "config": {"gain": 1.0, "seed": null}, "shared_object_id": 2}, "bias_initializer": {"class_name": "Zeros", "config": {}, "shared_object_id": 3}, "unit_forget_bias": true, "kernel_regularizer": null, "recurrent_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "recurrent_constraint": null, "bias_constraint": null, "dropout": 0.0, "recurrent_dropout": 0.0, "implementation": 2}, "shared_object_id": 5}, {"class_name": "Dense", "config": {"name": "dense", "trainable": true, "dtype": "float32", "units": 24, "activation": "linear", "use_bias": true, "kernel_initializer": {"class_name": "Zeros", "config": {}, "shared_object_id": 6}, "bias_initializer": {"class_name": "Zeros", "config": {}, "shared_object_id": 7}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}, "shared_object_id": 8}, {"class_name": "Reshape", "config": {"name": "reshape", "trainable": true, "dtype": "float32", "target_shape": {"class_name": "__tuple__", "items": [24, 1]}}, "shared_object_id": 9}]}}, "training_config": {"loss": {"class_name": "MeanSquaredError", "config": {"reduction": "auto", "name": "mean_squared_error"}, "shared_object_id": 11}, "metrics": null, "weighted_metrics": null, "loss_weights": null, "optimizer_config": {"class_name": "Adam", "config": {"name": "Adam", "learning_rate": 0.0010000000474974513, "decay": 0.0, "beta_1": 0.8999999761581421, "beta_2": 0.9990000128746033, "epsilon": 1e-07, "amsgrad": false}}}}2
3
+ � root.layer_with_weights-0"_tf_keras_rnn_layer*�
4
+ {"name": "lstm", "trainable": true, "expects_training_arg": true, "dtype": "float32", "batch_input_shape": null, "stateful": false, "must_restore_from_config": false, "class_name": "LSTM", "config": {"name": "lstm", "trainable": true, "dtype": "float32", "return_sequences": false, "return_state": false, "go_backwards": false, "stateful": false, "unroll": false, "time_major": false, "units": 12, "activation": "tanh", "recurrent_activation": "sigmoid", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}, "shared_object_id": 1}, "recurrent_initializer": {"class_name": "Orthogonal", "config": {"gain": 1.0, "seed": null}, "shared_object_id": 2}, "bias_initializer": {"class_name": "Zeros", "config": {}, "shared_object_id": 3}, "unit_forget_bias": true, "kernel_regularizer": null, "recurrent_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "recurrent_constraint": null, "bias_constraint": null, "dropout": 0.0, "recurrent_dropout": 0.0, "implementation": 2}, "shared_object_id": 5, "input_spec": [{"class_name": "InputSpec", "config": {"dtype": null, "shape": {"class_name": "__tuple__", "items": [null, null, 16]}, "ndim": 3, "max_ndim": null, "min_ndim": null, "axes": {}}, "shared_object_id": 12}], "build_input_shape": {"class_name": "TensorShape", "items": [null, 168, 16]}}2
5
+ �root.layer_with_weights-1"_tf_keras_layer*�{"name": "dense", "trainable": true, "expects_training_arg": false, "dtype": "float32", "batch_input_shape": null, "stateful": false, "must_restore_from_config": false, "class_name": "Dense", "config": {"name": "dense", "trainable": true, "dtype": "float32", "units": 24, "activation": "linear", "use_bias": true, "kernel_initializer": {"class_name": "Zeros", "config": {}, "shared_object_id": 6}, "bias_initializer": {"class_name": "Zeros", "config": {}, "shared_object_id": 7}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}, "shared_object_id": 8, "input_spec": {"class_name": "InputSpec", "config": {"dtype": null, "shape": null, "ndim": null, "max_ndim": null, "min_ndim": 2, "axes": {"-1": 12}}, "shared_object_id": 13}, "build_input_shape": {"class_name": "TensorShape", "items": [null, 12]}}2
6
+ � root.layer-2"_tf_keras_layer*�{"name": "reshape", "trainable": true, "expects_training_arg": false, "dtype": "float32", "batch_input_shape": null, "stateful": false, "must_restore_from_config": false, "class_name": "Reshape", "config": {"name": "reshape", "trainable": true, "dtype": "float32", "target_shape": {"class_name": "__tuple__", "items": [24, 1]}}, "shared_object_id": 9}2
7
+ �root.layer_with_weights-0.cell"_tf_keras_layer*�{"name": "lstm_cell", "trainable": true, "expects_training_arg": true, "dtype": "float32", "batch_input_shape": null, "stateful": false, "must_restore_from_config": false, "class_name": "LSTMCell", "config": {"name": "lstm_cell", "trainable": true, "dtype": "float32", "units": 12, "activation": "tanh", "recurrent_activation": "sigmoid", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}, "shared_object_id": 1}, "recurrent_initializer": {"class_name": "Orthogonal", "config": {"gain": 1.0, "seed": null}, "shared_object_id": 2}, "bias_initializer": {"class_name": "Zeros", "config": {}, "shared_object_id": 3}, "unit_forget_bias": true, "kernel_regularizer": null, "recurrent_regularizer": null, "bias_regularizer": null, "kernel_constraint": null, "recurrent_constraint": null, "bias_constraint": null, "dropout": 0.0, "recurrent_dropout": 0.0, "implementation": 2}, "shared_object_id": 4}2
8
+ �^root.keras_api.metrics.0"_tf_keras_metric*�{"class_name": "Mean", "name": "loss", "dtype": "float32", "config": {"name": "loss", "dtype": "float32"}, "shared_object_id": 14}2
web/backend/src/model/saved_model.pb ADDED
Binary file (749 kB). View file
 
web/backend/src/model/scaler.pkl ADDED
Binary file (809 Bytes). View file
 
web/backend/src/model/variables/variables.data-00000-of-00001 ADDED
Binary file (26.3 kB). View file
 
web/backend/src/model/variables/variables.index ADDED
Binary file (1.49 kB). View file
 
web/docker-compose.prod.yml ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ version: "3.5"
2
+ services:
3
+ pred-backend:
4
+ ports:
5
+ - "81:5000"
6
+
7
+ pred-frontend:
8
+ command: npm start
9
+ ports:
10
+ - "80:4200"
web/docker-compose.yml ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ version: "3.5"
2
+ services:
3
+ pred-backend:
4
+ image: pred-backend:latest
5
+ ports:
6
+ - "3001:5000"
7
+ volumes:
8
+ - ./backend/src:/app
9
+ networks:
10
+ - prediction-project
11
+ logging:
12
+ driver: "json-file"
13
+ options:
14
+ max-size: "10m"
15
+
16
+ pred-frontend:
17
+ image: pred-frontend:latest
18
+ command: npm run start-dev
19
+ ports:
20
+ - "4200:4200"
21
+ volumes:
22
+ - ./frontend/src:/app/src
23
+ networks:
24
+ - prediction-project
25
+ logging:
26
+ driver: "json-file"
27
+ options:
28
+ max-size: "10m"
29
+
30
+ volumes:
31
+ db-volume:
32
+
33
+ networks:
34
+ prediction-project:
web/frontend/.browserslistrc ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # This file is used by the build system to adjust CSS and JS output to support the specified browsers below.
2
+ # For additional information regarding the format and rule options, please see:
3
+ # https://github.com/browserslist/browserslist#queries
4
+
5
+ # For the full list of supported browsers by the Angular framework, please see:
6
+ # https://angular.io/guide/browser-support
7
+
8
+ # You can see what browsers were selected by your queries by running:
9
+ # npx browserslist
10
+
11
+ last 1 Chrome version
12
+ last 1 Firefox version
13
+ last 2 Edge major versions
14
+ last 2 Safari major versions
15
+ last 2 iOS major versions
16
+ Firefox ESR
web/frontend/.dockerignore ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ node_modules
2
+ .github
3
+ .angular
web/frontend/.editorconfig ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Editor configuration, see https://editorconfig.org
2
+ root = true
3
+
4
+ [*]
5
+ charset = utf-8
6
+ indent_style = space
7
+ indent_size = 2
8
+ insert_final_newline = true
9
+ trim_trailing_whitespace = true
10
+
11
+ [*.ts]
12
+ quote_type = single
13
+
14
+ [*.md]
15
+ max_line_length = off
16
+ trim_trailing_whitespace = false
web/frontend/.github/CODE_OF_CONDUCT.md ADDED
@@ -0,0 +1,46 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Contributor Covenant Code of Conduct
2
+
3
+ ## Our Pledge
4
+
5
+ In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.
6
+
7
+ ## Our Standards
8
+
9
+ Examples of behavior that contributes to creating a positive environment include:
10
+
11
+ * Using welcoming and inclusive language
12
+ * Being respectful of differing viewpoints and experiences
13
+ * Gracefully accepting constructive criticism
14
+ * Focusing on what is best for the community
15
+ * Showing empathy towards other community members
16
+
17
+ Examples of unacceptable behavior by participants include:
18
+
19
+ * The use of sexualized language or imagery and unwelcome sexual attention or advances
20
+ * Trolling, insulting/derogatory comments, and personal or political attacks
21
+ * Public or private harassment
22
+ * Publishing others' private information, such as a physical or electronic address, without explicit permission
23
+ * Other conduct which could reasonably be considered inappropriate in a professional setting
24
+
25
+ ## Our Responsibilities
26
+
27
+ Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.
28
+
29
+ Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
30
+
31
+ ## Scope
32
+
33
+ This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.
34
+
35
+ ## Enforcement
36
+
37
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at . The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
38
+
39
+ Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
40
+
41
+ ## Attribution
42
+
43
+ This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version]
44
+
45
+ [homepage]: http://contributor-covenant.org
46
+ [version]: http://contributor-covenant.org/version/1/4/
web/frontend/.github/COMMIT_CONVENTION.md ADDED
@@ -0,0 +1,83 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ## Git Commit Message Convention
2
+
3
+ > This is adapted from [Angular's commit convention](https://github.com/conventional-changelog/conventional-changelog/blob/master/packages/conventional-changelog-angular/convention.md).
4
+
5
+ #### Examples
6
+
7
+ Appears under "Features" header, `compiler` subheader:
8
+
9
+ ```
10
+ feat(compiler): add 'comments' option
11
+ ```
12
+
13
+ Appears under "Bug Fixes" header, `sidebar` subheader, with a link to issue #28:
14
+
15
+ ```
16
+ fix(sidebar): handle events on blur
17
+
18
+ close #28
19
+ ```
20
+
21
+ Appears under "Performance Improvements" header, and under "Breaking Changes" with the breaking change explanation:
22
+
23
+ ```
24
+ perf(core): improve vdom diffing by removing 'foo' option
25
+
26
+ BREAKING CHANGE: The 'foo' option has been removed.
27
+ ```
28
+
29
+ The following commit and commit `667ecc1` do not appear in the changelog if they are under the same release. If not, the revert commit appears under the "Reverts" header.
30
+
31
+ ```
32
+ revert: feat(compiler): add 'comments' option
33
+
34
+ This reverts commit 667ecc1654a317a13331b17617d973392f415f02.
35
+ ```
36
+
37
+ ### Full Message Format
38
+
39
+ A commit message consists of a **header**, **body** and **footer**. The header has a **type**, **scope** and **subject**:
40
+
41
+ ```
42
+ <type>(<scope>): <subject>
43
+ <BLANK LINE>
44
+ <body>
45
+ <BLANK LINE>
46
+ <footer>
47
+ ```
48
+
49
+ The **header** is mandatory and the **scope** of the header is optional.
50
+
51
+ ### Revert
52
+
53
+ If the commit reverts a previous commit, it should begin with `revert: `, followed by the header of the reverted commit. In the body it should say: `This reverts commit <hash>.`, where the hash is the SHA of the commit being reverted.
54
+
55
+ ### Type
56
+
57
+ If the prefix is `feat`, `fix` or `perf`, it will appear in the changelog. However if there is any [BREAKING CHANGE](#footer), the commit will always appear in the changelog.
58
+
59
+ Other prefixes are up to your discretion. Suggested prefixes are `docs`, `chore`, `style`, `refactor`, and `test` for non-changelog related tasks.
60
+
61
+ ### Scope
62
+
63
+ The scope could be anything specifying place of the commit change. For example `core`, `compiler`, `ssr`, `v-model`, `transition` etc...
64
+
65
+ ### Subject
66
+
67
+ The subject contains succinct description of the change:
68
+
69
+ * use the imperative, present tense: "change" not "changed" nor "changes"
70
+ * don't capitalize first letter
71
+ * no dot (.) at the end
72
+
73
+ ### Body
74
+
75
+ Just as in the **subject**, use the imperative, present tense: "change" not "changed" nor "changes".
76
+ The body should include the motivation for the change and contrast this with previous behavior.
77
+
78
+ ### Footer
79
+
80
+ The footer should contain any information about **Breaking Changes** and is also the place to
81
+ reference GitHub issues that this commit **Closes**.
82
+
83
+ **Breaking Changes** should start with the word `BREAKING CHANGE:` with a space or two newlines. The rest of the commit message is then used for this.
web/frontend/.github/CONTRIBUTING.md ADDED
@@ -0,0 +1,178 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Contributing to CoreUI
2
+
3
+ Looking to contribute something to CoreUI? **Here's how you can help.**
4
+
5
+ Please take a moment to review this document in order to make the contribution process easy and effective for everyone involved.
6
+
7
+ Following these guidelines helps to communicate that you respect the time of the developers managing and developing this open source project. In return, they should reciprocate that respect in addressing your issue or assessing
8
+ patches and features.
9
+
10
+ ## Using the issue tracker
11
+
12
+ The [issue tracker](https://github.com/coreui/coreui-free-angular-admin-template/issues) is
13
+ the preferred channel for [bug reports](#bug-reports), [features requests](#feature-requests)
14
+ and [submitting pull requests](#pull-requests), but please respect the following
15
+ restrictions:
16
+
17
+ * Please **do not** use the issue tracker for personal support requests.
18
+
19
+ * Please **do not** post comments consisting solely of "+1" or ":thumbsup:".
20
+ Use [GitHub's "reactions" feature](https://github.blog/2016-03-10-add-reactions-to-pull-requests-issues-and-comments/)
21
+ instead.
22
+
23
+ ## Bug reports
24
+
25
+ A bug is a _demonstrable problem_ that is caused by the code in the repository.
26
+ Good bug reports are extremely helpful, so thanks!
27
+
28
+ Guidelines for bug reports:
29
+
30
+ 0. **Validate and lint your code** &mdash; to ensure your problem isn't caused by a simple error in your own code.
31
+
32
+ 1. **Use the GitHub issue search** &mdash; check if the issue has already been reported.
33
+
34
+ 2. **Check if the issue has been fixed** &mdash; try to reproduce it using the latest `master` or development branch in the repository.
35
+
36
+ 3. **Isolate the problem** &mdash; ideally create a [reduced test case](https://css-tricks.com/reduced-test-cases/) and a live example. [This JS Bin](http://jsbin.com/lefey/1/edit?html,output) is a helpful template.
37
+
38
+
39
+ A good bug report shouldn't leave others needing to chase you up for more
40
+ information. Please try to be as detailed as possible in your report. What is
41
+ your environment? What steps will reproduce the issue? What browser(s) and OS
42
+ experience the problem? Do other browsers show the bug differently? What
43
+ would you expect to be the outcome? All these details will help people to fix
44
+ any potential bugs.
45
+
46
+ Example:
47
+
48
+ > Short and descriptive example bug report title
49
+ >
50
+ > A summary of the issue and the browser/OS environment in which it occurs. If
51
+ > suitable, include the steps required to reproduce the bug.
52
+ >
53
+ > 1. This is the first step
54
+ > 2. This is the second step
55
+ > 3. Further steps, etc.
56
+ >
57
+ > `<url>` - a link to the reduced test case
58
+ >
59
+ > Any other information you want to share that is relevant to the issue being
60
+ > reported. This might include the lines of code that you have identified as
61
+ > causing the bug, and potential solutions (and your opinions on their
62
+ > merits).
63
+
64
+ ## Feature requests
65
+
66
+ Feature requests are welcome. Before opening a feature request, please take a
67
+ moment to find out whether your idea fits with the scope and aims of the
68
+ project. It's up to *you* to make a strong case to convince the project's
69
+ developers of the merits of this feature. Please provide as much detail
70
+ and context as possible.
71
+
72
+
73
+ ## Pull requests
74
+
75
+ Good pull requests—patches, improvements, new features—are a fantastic
76
+ help. They should remain focused in scope and avoid containing unrelated
77
+ commits.
78
+
79
+ **Please ask first** before embarking on any significant pull request (e.g.
80
+ implementing features, refactoring code, porting to a different language),
81
+ otherwise you risk spending a lot of time working on something that the
82
+ project's developers might not want to merge into the project.
83
+
84
+ Adhering to the following process is the best way to get your work
85
+ included in the project:
86
+
87
+ 1. [Fork](https://help.github.com/fork-a-repo/) the project, clone your fork,
88
+ and configure the remotes:
89
+
90
+ ```bash
91
+ # Clone your fork of the repo into the current directory
92
+ git clone https://github.com/<your-username>/coreui-vue.git
93
+ # Navigate to the newly cloned directory
94
+ cd coreui
95
+ # Assign the original repo to a remote called "upstream"
96
+ git remote add upstream https://github.com/coreui/coreui-vue.git
97
+ ```
98
+
99
+ 2. If you cloned a while ago, get the latest changes from upstream:
100
+
101
+ ```bash
102
+ git checkout master
103
+ git pull upstream master
104
+ ```
105
+
106
+ 3. Create a new topic branch (off the main project development branch) to
107
+ contain your feature, change, or fix:
108
+
109
+ ```bash
110
+ git checkout -b <topic-branch-name>
111
+ ```
112
+
113
+ 4. Commit your changes in logical chunks. Please adhere to these [git commit
114
+ message guidelines](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html)
115
+ or your code is unlikely to be merged into the main project. Use Git's
116
+ [interactive rebase](https://help.github.com/articles/interactive-rebase)
117
+ feature to tidy up your commits before making them public.
118
+
119
+ 5. Locally merge (or rebase) the upstream development branch into your topic branch:
120
+
121
+ ```bash
122
+ git pull [--rebase] upstream master
123
+ ```
124
+
125
+ 6. Push your topic branch up to your fork:
126
+
127
+ ```bash
128
+ git push origin <topic-branch-name>
129
+ ```
130
+
131
+ 7. [Open a Pull Request](https://help.github.com/articles/using-pull-requests/)
132
+ with a clear title and description against the `master` branch.
133
+
134
+ **IMPORTANT**: By submitting a patch, you agree to allow the project owners to
135
+ license your work under the terms of the [MIT License](LICENSE).
136
+
137
+ ### Semantic Git commit messages
138
+
139
+ Inspired by Sparkbox's awesome article on
140
+ [semantic commit messages](http://seesparkbox.com/foundry/semantic_commit_messages).
141
+ Please use following commit message format.
142
+
143
+ * chore (updating npm tasks etc; no production code change) -> ```git test -m 'chore: commit-message-here'```
144
+ * docs (changes to documentation) -> ```git commit -m 'docs: commit-message-here'```
145
+ * feat (new feature) -> ```git commit -m 'feat: commit-message-here'```
146
+ * fix (bug fix) -> ```git commit -m 'fix: commit-message-here'```
147
+ * refactor (refactoring production code) -> ```git commit -m 'refactor: commit-message-here'```
148
+ * style (formatting, missing semi colons, etc; no code change) -> ```git commit -m 'style: commit-message-here'```
149
+ * test (adding missing tests, refactoring tests; no production code change) -> ```git test -m 'refactor: commit-message-here'```
150
+
151
+ ## Code guidelines
152
+
153
+ ### HTML
154
+
155
+ [Adhere to the Code Guide.](http://codeguide.co/#html)
156
+
157
+ - Use tags and elements appropriate for an HTML5 doctype (e.g., self-closing tags).
158
+ - Use CDNs and HTTPS for third-party JS when possible. We don't use protocol-relative URLs in this case because they break when viewing the page locally via `file://`.
159
+ - Use [WAI-ARIA](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA) attributes in documentation examples to promote accessibility.
160
+
161
+ ### CSS
162
+
163
+ [Adhere to the Code Guide.](http://codeguide.co/#css)
164
+
165
+ - When feasible, default color palettes should comply with [WCAG color contrast guidelines](http://www.w3.org/TR/WCAG20/#visual-audio-contrast).
166
+ - Except in rare cases, don't remove default `:focus` styles (via e.g. `outline: none;`) without providing alternative styles. See [this A11Y Project post](http://a11yproject.com/posts/never-remove-css-outlines) for more details.
167
+
168
+ ### JS
169
+
170
+ - No semicolons (in client-side JS)
171
+ - 2 spaces (no tabs)
172
+ - strict mode
173
+ - "Attractive"
174
+ - Don't use [jQuery event alias convenience methods](https://github.com/jquery/jquery/blob/master/src/event/alias.js) (such as `$().focus()`). Instead, use [`$().trigger(eventType, ...)`](http://api.jquery.com/trigger/) or [`$().on(eventType, ...)`](http://api.jquery.com/on/), depending on whether you're firing an event or listening for an event. (For example, `$().trigger('focus')` or `$().on('focus', function (event) { /* handle focus event */ })`) We do this to be compatible with custom builds of jQuery where the event aliases module has been excluded.
175
+
176
+ ## License
177
+
178
+ By contributing your code, you agree to license your contribution under the [MIT License](LICENSE).
web/frontend/.github/FUNDING.yml ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ # These are supported funding model platforms
2
+
3
+ custom: "https://coreui.io/pricing?support=angular"
4
+ open_collective: coreui
web/frontend/.github/ISSUE_TEMPLATE/bug_report.md ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ name: Bug report
3
+ about: Tell us about a bug you may have identified in CoreUI Free Angular Admin Template.
4
+ title: ''
5
+ labels: ''
6
+ assignees: ''
7
+
8
+ ---
9
+
10
+ Before opening:
11
+
12
+ - [Search for duplicate or closed issues](https://github.com/coreui/coreui-free-angular-admin-template/issues?utf8=%E2%9C%93&q=is%3Aissue)
13
+ - [Validate](https://html5.validator.nu/) any HTML to avoid common problems
14
+ - Read the [contributing guidelines](https://github.com/coreui/coreui-free-angular-admin-template/blob/v4-dev/.github/CONTRIBUTING.md)
15
+
16
+ Bug reports must include:
17
+
18
+ - Operating system and version (Windows, macOS, Android, iOS)
19
+ - Browser and version (Chrome, Firefox, Safari, Microsoft Edge, Opera, Android Browser)
20
+ - A [reduced test case](https://css-tricks.com/reduced-test-cases/) or suggested fix using [CodePen](https://codepen.io/) or [JS Bin](https://jsbin.com/)
web/frontend/.github/ISSUE_TEMPLATE/feature_request.md ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ name: Feature request
3
+ about: Suggest an idea for a new feature in CoreUI Free Angular Admin Template.
4
+ title: ''
5
+ labels: feature
6
+ assignees: ''
7
+
8
+ ---
9
+
10
+ Before opening:
11
+
12
+ - [Search for duplicate or closed issues](https://github.com/coreui/coreui-free-angular-admin-template/issues?utf8=%E2%9C%93&q=is%3Aissue)
13
+ - Read the [contributing guidelines](https://github.com/coreui/coreui-free-angular-admin-template/blob/main/.github/CONTRIBUTING.md)
14
+
15
+ Feature requests must include:
16
+
17
+ - As much detail as possible for what we should add and why it's important to Bootstrap
18
+ - Relevant links to prior art, screenshots, or live demos whenever possible
web/frontend/.github/SUPPORT.md ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ ### Bug reports
2
+
3
+ See the [contributing guidelines](CONTRIBUTING.md) for sharing bug reports.
4
+
5
+ ### How-to
6
+
7
+ For general troubleshooting or help getting started:
8
+
9
+ - Go to [Discussions](https://github.com/coreui/coreui-free-angular-admin-template/discussions).
web/frontend/.github/workflows/build-check.yml ADDED
@@ -0,0 +1,39 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ name: Build Check
2
+
3
+ on:
4
+ push:
5
+ branches-ignore:
6
+ - "dependabot/**"
7
+ pull_request:
8
+ branches:
9
+ - main
10
+ - v4
11
+ schedule:
12
+ - # build runs every weekday at 4:15AM UTC
13
+ - cron: '15 4 * * *'
14
+
15
+ env:
16
+ FORCE_COLOR: 2
17
+ NODE: 16
18
+
19
+ jobs:
20
+ build:
21
+ strategy:
22
+ matrix:
23
+ platform: [ubuntu-latest, windows-latest, macOS-latest]
24
+ node-version: [16.x, 18.x]
25
+ runs-on: ${{ matrix.platform }}
26
+ steps:
27
+ - name: Clone repository
28
+ uses: actions/checkout@v3
29
+
30
+ - name: Set up Node.js
31
+ uses: actions/setup-node@v3
32
+ with:
33
+ node-version: ${{ env.node-version }}
34
+
35
+ - name: Install npm dependencies
36
+ run: npm install
37
+
38
+ - name: Run build
39
+ run: npm run build
web/frontend/.github/workflows/stale.yml ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # This workflow warns and then closes issues and PRs that have had no activity for a specified amount of time.
2
+ #
3
+ # You can adjust the behavior by modifying this file.
4
+ # For more information, see:
5
+ # https://github.com/actions/stale
6
+ name: Mark stale issues and pull requests
7
+
8
+ on:
9
+ schedule:
10
+ - cron: '34 23 * * 0'
11
+
12
+ jobs:
13
+ stale:
14
+
15
+ runs-on: ubuntu-latest
16
+ permissions:
17
+ issues: write
18
+ pull-requests: write
19
+
20
+ steps:
21
+ - uses: actions/stale@v5
22
+ with:
23
+ repo-token: ${{ secrets.GITHUB_TOKEN }}
24
+ stale-issue-message: 'This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions'
25
+ stale-pr-message: 'This PR has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions'
26
+ stale-issue-label: 'no-issue-activity'
27
+ stale-pr-label: 'no-pr-activity'
web/frontend/.gitignore ADDED
@@ -0,0 +1,45 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # See http://help.github.com/ignore-files/ for more about ignoring files.
2
+
3
+ # Compiled output
4
+ /dist
5
+ /tmp
6
+ /out-tsc
7
+ /bazel-out
8
+
9
+ # Node
10
+ /node_modules
11
+ npm-debug.log
12
+ yarn-error.log
13
+
14
+ # profiling files
15
+ chrome-profiler-events*.json
16
+
17
+ # IDEs and editors
18
+ .idea/
19
+ .project
20
+ .classpath
21
+ .c9/
22
+ *.launch
23
+ .settings/
24
+ *.sublime-workspace
25
+
26
+ # Visual Studio Code
27
+ .vscode/*
28
+ !.vscode/settings.json
29
+ !.vscode/tasks.json
30
+ !.vscode/launch.json
31
+ !.vscode/extensions.json
32
+ .history/*
33
+
34
+ # Miscellaneous
35
+ /.angular/cache
36
+ .sass-cache/
37
+ /connect.lock
38
+ /coverage
39
+ /libpeerconnection.log
40
+ testem.log
41
+ /typings
42
+
43
+ # System files
44
+ .DS_Store
45
+ Thumbs.db
web/frontend/README.md ADDED
@@ -0,0 +1,219 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [![@coreui angular](https://img.shields.io/badge/@coreui%20-angular-lightgrey.svg?style=flat-square)](https://github.com/coreui/angular)
2
+ [![npm-coreui-angular-next][npm-coreui-angular-badge-next]][npm-coreui-angular]
3
+ [![NPM downloads][npm-coreui-angular-download]][npm-coreui-angular]
4
+ [![@coreui coreui](https://img.shields.io/badge/@coreui%20-coreui-lightgrey.svg?style=flat-square)](https://github.com/coreui/coreui)
5
+ [![npm package][npm-coreui-badge]][npm-coreui]
6
+ [![NPM downloads][npm-coreui-download]][npm-coreui]
7
+ ![angular](https://img.shields.io/badge/angular-^14.2.0-lightgrey.svg?style=flat-square&logo=angular)
8
+
9
+ [npm-coreui-angular]: https://www.npmjs.com/package/@coreui/angular
10
+ [npm-coreui-angular-badge]: https://img.shields.io/npm/v/@coreui/angular.png?style=flat-square
11
+ [npm-coreui-angular-badge-next]: https://img.shields.io/npm/v/@coreui/angular/next?style=flat-square&color=red
12
+ [npm-coreui-angular-download]: https://img.shields.io/npm/dm/@coreui/angular.svg?style=flat-square
13
+ [npm-coreui]: https://www.npmjs.com/package/@coreui/coreui
14
+ [npm-coreui-badge]: https://img.shields.io/npm/v/@coreui/coreui.png?style=flat-square
15
+ [npm-coreui-download]: https://img.shields.io/npm/dm/@coreui/coreui.svg?style=flat-square
16
+
17
+ # CoreUI 4 Angular 14 Free Admin Template
18
+
19
+ CoreUI is meant to be the UX game changer. Pure & transparent code is devoid of redundant components, so the app is light enough to offer ultimate user experience. This means mobile devices also, where the navigation is just as easy and intuitive as on a desktop or laptop. The CoreUI Layout API lets you customize your project for almost any device – be it Mobile, Web or WebApp – CoreUI covers them all!
20
+
21
+ [CoreUI Angular Admin Template](https://coreui.io/angular)
22
+ [Demo](https://coreui.io/angular/demo/4.0/free/)
23
+
24
+ ## Table of Contents
25
+
26
+ * [Versions](#versions)
27
+ * [CoreUI Pro](#coreui-pro)
28
+ * [Quick Start](#quick-start)
29
+ * [Installation](#installation)
30
+ * [Basic usage](#basic-usage)
31
+ * [What's included](#whats-included)
32
+ * [Documentation](#documentation)
33
+ * [Versioning](#versioning)
34
+ * [Creators](#creators)
35
+ * [Community](#community)
36
+ * [Copyright and License](#copyright-and-license)
37
+
38
+ ## Versions
39
+
40
+ * [CoreUI Free Bootstrap Admin Template](https://github.com/coreui/coreui-free-bootstrap-admin-template)
41
+ * [CoreUI Free Angular Admin Template](https://github.com/coreui/coreui-free-angular-admin-template)
42
+ * [CoreUI Free React.js Admin Template](https://github.com/coreui/coreui-free-react-admin-template)
43
+ * [CoreUI Free Vue.js Admin Template](https://github.com/coreui/coreui-free-vue-admin-template)
44
+
45
+ ## CoreUI Pro
46
+
47
+ **Only customers with [Enterpise Membership Plan](https://coreui.io/pro/#buy) have access to private github CoreUI Pro repository.**
48
+
49
+ * 💪 [CoreUI Pro Angular Admin Template](https://coreui.io/product/angular-dashboard-template/)
50
+ * 💪 [CoreUI Pro Bootstrap Admin Template](https://coreui.io/product/bootstrap-dashboard-template/)
51
+ * 💪 [CoreUI Pro React Admin Template](https://coreui.io/product/react-dashboard-template/)
52
+ * 💪 [CoreUI Pro Vue Admin Template](https://coreui.io/product/vue-dashboard-template/)
53
+
54
+ ## Quick Start
55
+
56
+ - [Download the latest release](https://github.com/coreui/coreui-free-angular-admin-template/)
57
+ - Clone the repo: `git clone https://github.com/coreui/coreui-free-angular-admin-template.git`
58
+
59
+ #### <i>Prerequisites</i>
60
+ Before you begin, make sure your development environment includes `Node.js®` and an `npm` package manager.
61
+
62
+ ###### Node.js
63
+ Angular 14 requires `Node.js` version `^14.15` or `^16.10`.
64
+
65
+ - To check your version, run `node -v` in a terminal/console window.
66
+ - To get `Node.js`, go to [nodejs.org](https://nodejs.org/).
67
+
68
+ ###### Angular CLI
69
+ Install the Angular CLI globally using a terminal/console window.
70
+ ```bash
71
+ npm install -g @angular/cli
72
+ ```
73
+
74
+ ### Installation
75
+
76
+ ``` bash
77
+ $ npm install
78
+ ```
79
+
80
+ ### Basic usage
81
+
82
+ ``` bash
83
+ # dev server with hot reload at http://localhost:4200
84
+ $ npm start
85
+ ```
86
+
87
+ Navigate to [http://localhost:4200](http://localhost:4200). The app will automatically reload if you change any of the source files.
88
+
89
+ #### Build
90
+
91
+ Run `build` to build the project. The build artifacts will be stored in the `dist/` directory.
92
+
93
+ ```bash
94
+ # build for production with minification
95
+ $ npm run build
96
+ ```
97
+ ## What's included
98
+
99
+ Within the download you'll find the following directories and files, logically grouping common assets and providing both compiled and minified variations. You'll see something like this:
100
+
101
+ ```
102
+ coreui-free-angular-admin-template
103
+ ├── src/ # project root
104
+ │ ├── app/ # main app directory
105
+ | │ ├── containers/ # layout containers
106
+ | | │ └── default-layout/ # layout containers
107
+ | | | └── _nav.js # sidebar navigation config
108
+ | │ ├── icons/ # icons set for the app
109
+ | │ └── views/ # application views
110
+ │ ├── assets/ # images, icons, etc.
111
+ �� ├── components/ # components for demo only
112
+ │ ├── scss/ # scss styles
113
+ │ └── index.html # html template
114
+
115
+ ├── angular.json
116
+ ├── README.md
117
+ └── package.json
118
+ ```
119
+
120
+ ## Documentation
121
+
122
+ The documentation for the CoreUI Admin Template is hosted at our website [CoreUI for Angular](https://coreui.io/angular/)
123
+
124
+ ---
125
+
126
+ This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 14.0.0.
127
+
128
+ ## Versioning
129
+
130
+ For transparency into our release cycle and in striving to maintain backward compatibility, CoreUI Free Admin Template is maintained under [the Semantic Versioning guidelines](http://semver.org/).
131
+
132
+ See [the Releases section of our project](https://github.com/coreui/coreui-free-angular-admin-template/releases) for changelogs for each release version.
133
+
134
+ ## Development server
135
+
136
+ Run `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The app will automatically reload if you change any of the source files.
137
+
138
+ ## Code scaffolding
139
+
140
+ Run `ng generate component component-name` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module`.
141
+
142
+ ## Build
143
+
144
+ Run `ng build` to build the project. The build artifacts will be stored in the `dist/` directory.
145
+
146
+ ## Running unit tests
147
+
148
+ Run `ng test` to execute the unit tests via [Karma](https://karma-runner.github.io).
149
+
150
+ ## Running end-to-end tests
151
+
152
+ Run `ng e2e` to execute the end-to-end tests via a platform of your choice. To use this command, you need to first add a package that implements end-to-end testing capabilities.
153
+
154
+ ## Further help
155
+
156
+ To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI Overview and Command Reference](https://angular.io/cli) page.
157
+
158
+ ## Creators
159
+
160
+ **Łukasz Holeczek**
161
+ * <https://twitter.com/lukaszholeczek>
162
+ * <https://github.com/mrholek>
163
+ * <https://github.com/coreui>
164
+
165
+ **CoreUI team**
166
+ * https://github.com/orgs/coreui/people
167
+
168
+ ## Community
169
+
170
+ Get updates on CoreUI's development and chat with the project maintainers and community members.
171
+
172
+ - Follow [@core_ui on Twitter](https://twitter.com/core_ui).
173
+ - Read and subscribe to [CoreUI Blog](https://coreui.io/blog/).
174
+
175
+ ## Support CoreUI Development
176
+
177
+ CoreUI is an MIT-licensed open source project and is completely free to use. However, the amount of effort needed to maintain and develop new features for the project is not sustainable without proper financial backing. You can support development by buying the [CoreUI PRO](https://coreui.io/pricing/) or by becoming a sponsor via [Open Collective](https://opencollective.com/coreui/).
178
+
179
+ <!--- StartOpenCollectiveBackers -->
180
+
181
+ ### Platinum Sponsors
182
+
183
+ Support this project by [becoming a Platinum Sponsor](https://opencollective.com/coreui/contribute/platinum-sponsor-40959/). A large company logo will be added here with a link to your website.
184
+
185
+ <a href="https://opencollective.com/coreui/contribute/platinum-sponsor-40959/checkout"><img src="https://opencollective.com/coreui/tiers/platinum-sponsor/0/avatar.svg?avatarHeight=100"></a>
186
+
187
+ ### Gold Sponsors
188
+
189
+ Support this project by [becoming a Gold Sponsor](https://opencollective.com/coreui/contribute/gold-sponsor-40960/). A big company logo will be added here with a link to your website.
190
+
191
+ <a href="https://opencollective.com/coreui/contribute/gold-sponsor-40960/checkout"><img src="https://opencollective.com/coreui/tiers/gold-sponsor/0/avatar.svg?avatarHeight=100"></a>
192
+
193
+ ### Silver Sponsors
194
+
195
+ Support this project by [becoming a Silver Sponsor](https://opencollective.com/coreui/contribute/silver-sponsor-40967/). A medium company logo will be added here with a link to your website.
196
+
197
+ <a href="https://opencollective.com/coreui/contribute/silver-sponsor-40967/checkout"><img src="https://opencollective.com/coreui/tiers/gold-sponsor/0/avatar.svg?avatarHeight=100"></a>
198
+
199
+ ### Bronze Sponsors
200
+
201
+ Support this project by [becoming a Bronze Sponsor](https://opencollective.com/coreui/contribute/bronze-sponsor-40966/). The company avatar will show up here with a link to your OpenCollective Profile.
202
+
203
+ <a href="https://opencollective.com/coreui/contribute/bronze-sponsor-40966/checkout"><img src="https://opencollective.com/coreui/tiers/bronze-sponsor/0/avatar.svg?avatarHeight=100"></a>
204
+
205
+ ### Backers
206
+
207
+ Thanks to all the backers and sponsors! Support this project by [becoming a backer](https://opencollective.com/coreui/contribute/backer-40965/).
208
+
209
+ <a href="https://opencollective.com/coreui/contribute/backer-40965/checkout" target="_blank" rel="noopener"><img src="https://opencollective.com/coreui/backers.svg?width=890"></a>
210
+
211
+ <!--- EndOpenCollectiveBackers -->
212
+
213
+ ## Copyright and License
214
+
215
+ copyright 2022 creativeLabs Łukasz Holeczek.
216
+
217
+
218
+ Code released under [the MIT license](https://github.com/coreui/coreui-free-react-admin-template/blob/master/LICENSE).
219
+ There is only one limitation you can't re-distribute the CoreUI as stock. You can’t do this if you modify the CoreUI. In past we faced some problems with persons who tried to sell CoreUI based templates.
web/frontend/angular.json ADDED
@@ -0,0 +1,118 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
3
+ "cli": {
4
+ "analytics": false
5
+ },
6
+ "version": 1,
7
+ "newProjectRoot": "projects",
8
+ "projects": {
9
+ "weather-forecaster": {
10
+ "projectType": "application",
11
+ "schematics": {
12
+ "@schematics/angular:component": {
13
+ "style": "scss"
14
+ },
15
+ "@schematics/angular:application": {
16
+ "strict": true
17
+ }
18
+ },
19
+ "root": "",
20
+ "sourceRoot": "src",
21
+ "prefix": "app",
22
+ "architect": {
23
+ "build": {
24
+ "builder": "@angular-devkit/build-angular:browser",
25
+ "options": {
26
+ "outputPath": "dist/weather-forecaster",
27
+ "index": "src/index.html",
28
+ "main": "src/main.ts",
29
+ "polyfills": "src/polyfills.ts",
30
+ "tsConfig": "tsconfig.app.json",
31
+ "inlineStyleLanguage": "scss",
32
+ "preserveSymlinks": true,
33
+ "assets": [
34
+ "src/favicon.ico",
35
+ "src/assets"
36
+ ],
37
+ "styles": [
38
+ "src/scss/styles.scss"
39
+ ],
40
+ "scripts": [],
41
+ "allowedCommonJsDependencies": [
42
+ "chart.js",
43
+ "@coreui/chartjs/dist/js/coreui-chartjs.js"
44
+ ]
45
+ },
46
+ "configurations": {
47
+ "production": {
48
+ "budgets": [
49
+ {
50
+ "type": "initial",
51
+ "maximumWarning": "1500kb",
52
+ "maximumError": "6mb"
53
+ },
54
+ {
55
+ "type": "anyComponentStyle",
56
+ "maximumWarning": "2kb",
57
+ "maximumError": "4kb"
58
+ }
59
+ ],
60
+ "fileReplacements": [
61
+ {
62
+ "replace": "src/environments/environment.ts",
63
+ "with": "src/environments/environment.prod.ts"
64
+ }
65
+ ],
66
+ "outputHashing": "all"
67
+ },
68
+ "development": {
69
+ "buildOptimizer": false,
70
+ "optimization": false,
71
+ "vendorChunk": true,
72
+ "extractLicenses": false,
73
+ "sourceMap": true,
74
+ "namedChunks": true
75
+ }
76
+ },
77
+ "defaultConfiguration": "production"
78
+ },
79
+ "serve": {
80
+ "builder": "@angular-devkit/build-angular:dev-server",
81
+ "configurations": {
82
+ "production": {
83
+ "browserTarget": "weather-forecaster:build:production"
84
+ },
85
+ "development": {
86
+ "browserTarget": "weather-forecaster:build:development"
87
+ }
88
+ },
89
+ "defaultConfiguration": "development"
90
+ },
91
+ "extract-i18n": {
92
+ "builder": "@angular-devkit/build-angular:extract-i18n",
93
+ "options": {
94
+ "browserTarget": "weather-forecaster:build"
95
+ }
96
+ },
97
+ "test": {
98
+ "builder": "@angular-devkit/build-angular:karma",
99
+ "options": {
100
+ "main": "src/test.ts",
101
+ "polyfills": "src/polyfills.ts",
102
+ "tsConfig": "tsconfig.spec.json",
103
+ "karmaConfig": "karma.conf.js",
104
+ "inlineStyleLanguage": "scss",
105
+ "assets": [
106
+ "src/favicon.ico",
107
+ "src/assets"
108
+ ],
109
+ "styles": [
110
+ "src/scss/styles.scss"
111
+ ],
112
+ "scripts": []
113
+ }
114
+ }
115
+ }
116
+ }
117
+ }
118
+ }