Esvanth commited on
Commit
3c2c304
Β·
1 Parent(s): f9a3b7b

Load task data from data/*.csv instead of regenerating in-code

Browse files

Each task script now reads its inputs directly from the CSVs in data/:
customers.csv (Task 2), sales_history.csv (Task 5), and
network_nodes/edges.csv (Tasks 3/4). The inline generators are kept
as the source-of-truth used by data/export_data.py to rebuild the
CSVs. Results are unchanged (byte-identical for Tasks 2 and 3/4,
~1e-14 float round-trip noise for Task 5, invisible in any metric).

README's Dataset section updated to reflect that CSVs are now the
program's runtime data source.

README.md CHANGED
@@ -2,7 +2,7 @@
2
 
3
  An interactive AI-powered logistics simulation
4
 
5
- πŸš€ **Live Demo:** [Launch on Streamlit](https://ecocart-ai-app-live.streamlit.app)
6
 
7
  ---
8
 
@@ -43,13 +43,14 @@ Trains two ML models on 730 days of synthetic sales data:
43
  - **Linear Regression** β€” fast and interpretable
44
  - **Random Forest** β€” captures non-linear seasonal patterns
45
 
46
- Trains on 730 days of data and evaluates both models on 140 unseen test days using MAE, RMSE, RΒ², and MAPE.
47
 
48
  ### Task 6 β€” Business Case *(Voluntary β€” AI Student)*
49
  Quantifies the financial and environmental impact of the AI system with fully interactive sliders:
50
  - **ROI calculator** β€” adjusts fleet size, fuel cost, wage rates and shows live annual savings
51
  - **3-year ROI projection** β€” cumulative benefit vs cost with breakeven line
52
- - **COβ‚‚ impact** β€” estimated tonnes of COβ‚‚ saved per year
 
53
 
54
  ---
55
 
@@ -68,8 +69,6 @@ Quantifies the financial and environmental impact of the AI system with fully in
68
  ## Run Locally
69
 
70
  ```bash
71
- git clone https://github.com/Esvanth/Ecocart-AI.git
72
- cd Ecocart-AI
73
  pip install -r requirements.txt
74
  streamlit run app.py
75
  ```
@@ -79,21 +78,47 @@ streamlit run app.py
79
  ## Project Structure
80
 
81
  ```
82
- Ecocart-AI/
83
  β”œβ”€β”€ app.py # Main Streamlit app (all 6 tasks)
84
  β”œβ”€β”€ task2_segmentation.py # Standalone Task 2 script
85
  β”œβ”€β”€ task3_4_routing.py # Standalone Tasks 3 & 4 script
86
  β”œβ”€β”€ task5_forecasting.py # Standalone Task 5 script
 
 
 
 
 
 
87
  β”œβ”€β”€ requirements.txt # Python dependencies
88
  └── README.md
89
  ```
90
 
91
  ---
92
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
93
  ## Author
94
 
95
- **Esvanth Mohankumar**
96
  Student ID: 24311073
97
  Programme: MSc Artificial Intelligence
98
- Institution: National College of Ireland
99
- Module: Foundations of AI
 
2
 
3
  An interactive AI-powered logistics simulation
4
 
5
+ **Live Demo:** [Launch on Streamlit](https://ecocart-ai-app-live.streamlit.app)
6
 
7
  ---
8
 
 
43
  - **Linear Regression** β€” fast and interpretable
44
  - **Random Forest** β€” captures non-linear seasonal patterns
45
 
46
+ Features a **what-if predictor** β€” enter any day, month, and promotion flag to get an instant sales prediction.
47
 
48
  ### Task 6 β€” Business Case *(Voluntary β€” AI Student)*
49
  Quantifies the financial and environmental impact of the AI system with fully interactive sliders:
50
  - **ROI calculator** β€” adjusts fleet size, fuel cost, wage rates and shows live annual savings
51
  - **3-year ROI projection** β€” cumulative benefit vs cost with breakeven line
52
+ - **COβ‚‚ impact** β€” tonnes saved per year, tree and car equivalents
53
+ - **Implementation roadmap** β€” 5-phase Gantt chart across 8 months
54
 
55
  ---
56
 
 
69
  ## Run Locally
70
 
71
  ```bash
 
 
72
  pip install -r requirements.txt
73
  streamlit run app.py
74
  ```
 
78
  ## Project Structure
79
 
80
  ```
81
+ FAI SIMULATION/
82
  β”œβ”€β”€ app.py # Main Streamlit app (all 6 tasks)
83
  β”œβ”€β”€ task2_segmentation.py # Standalone Task 2 script
84
  β”œβ”€β”€ task3_4_routing.py # Standalone Tasks 3 & 4 script
85
  β”œβ”€β”€ task5_forecasting.py # Standalone Task 5 script
86
+ β”œβ”€β”€ data/ # Synthetic datasets (loaded by every task)
87
+ β”‚ β”œβ”€β”€ customers.csv # Task 2 β€” 400 customer records
88
+ β”‚ β”œβ”€β”€ sales_history.csv # Task 5 β€” 730 days of daily sales
89
+ β”‚ β”œβ”€β”€ network_nodes.csv # Tasks 3/4 β€” 20-node delivery network
90
+ β”‚ β”œβ”€β”€ network_edges.csv # Tasks 3/4 β€” edge weights + COβ‚‚ cost
91
+ β”‚ └── export_data.py # Regenerates the CSVs from a fixed seed
92
  β”œβ”€β”€ requirements.txt # Python dependencies
93
  └── README.md
94
  ```
95
 
96
  ---
97
 
98
+ ## Dataset
99
+
100
+ All data is **synthetic and reproducible**. The CSVs in `data/` are the
101
+ program's data source β€” every task script (`task2_segmentation.py`,
102
+ `task3_4_routing.py`, `task5_forecasting.py`) loads its inputs directly
103
+ from these files at runtime:
104
+
105
+ | File | Rows | Description |
106
+ |------|------|-------------|
107
+ | `customers.csv` | 400 | 300 urban + 100 rural customers (deliberately biased) |
108
+ | `sales_history.csv` | 730 | Daily sales with weekly + yearly seasonality + promos |
109
+ | `network_nodes.csv` | 20 | Delivery hubs (x, y, urban/rural) |
110
+ | `network_edges.csv` | 34 | Roads with distance (km) and COβ‚‚ cost (kg) |
111
+
112
+ The CSVs themselves are generated from an inline source-of-truth with a
113
+ fixed random seed (`np.random.default_rng(42)`). To rebuild them:
114
+ `python data/export_data.py`
115
+
116
+ ---
117
+
118
  ## Author
119
 
120
+ Esvanth Mohankumar
121
  Student ID: 24311073
122
  Programme: MSc Artificial Intelligence
123
+ College: National College of Ireland
124
+ Module: Foundations of AI
data/customers.csv ADDED
@@ -0,0 +1,401 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ freq,spend,recency,region
2
+ 6.6,189.0,5.0,urban
3
+ 3.9,59.0,6.0,urban
4
+ 7.5,155.0,1.0,urban
5
+ 7.9,107.0,24.0,urban
6
+ 2.1,118.0,12.0,urban
7
+ 3.4,78.0,27.0,urban
8
+ 6.3,107.0,24.0,urban
9
+ 5.4,172.0,1.0,urban
10
+ 6.0,143.0,18.0,urban
11
+ 4.3,189.0,1.0,urban
12
+ 7.8,167.0,1.0,urban
13
+ 7.6,138.0,11.0,urban
14
+ 6.1,190.0,6.0,urban
15
+ 8.3,138.0,16.0,urban
16
+ 6.9,153.0,33.0,urban
17
+ 4.3,108.0,6.0,urban
18
+ 6.7,123.0,9.0,urban
19
+ 4.1,92.0,1.0,urban
20
+ 7.8,160.0,2.0,urban
21
+ 5.9,73.0,11.0,urban
22
+ 5.6,151.0,1.0,urban
23
+ 4.6,112.0,10.0,urban
24
+ 8.4,167.0,10.0,urban
25
+ 5.7,150.0,1.0,urban
26
+ 5.1,193.0,26.0,urban
27
+ 5.3,149.0,15.0,urban
28
+ 7.1,57.0,24.0,urban
29
+ 6.7,117.0,2.0,urban
30
+ 6.8,73.0,14.0,urban
31
+ 6.9,99.0,4.0,urban
32
+ 10.3,180.0,30.0,urban
33
+ 5.2,146.0,7.0,urban
34
+ 5.0,92.0,10.0,urban
35
+ 4.4,79.0,3.0,urban
36
+ 7.2,121.0,6.0,urban
37
+ 8.3,71.0,14.0,urban
38
+ 5.8,93.0,11.0,urban
39
+ 4.3,132.0,1.0,urban
40
+ 4.4,166.0,1.0,urban
41
+ 7.3,144.0,6.0,urban
42
+ 7.5,28.0,15.0,urban
43
+ 7.1,132.0,9.0,urban
44
+ 4.7,123.0,2.0,urban
45
+ 6.5,137.0,16.0,urban
46
+ 6.2,185.0,34.0,urban
47
+ 6.4,37.0,4.0,urban
48
+ 7.7,96.0,7.0,urban
49
+ 6.4,144.0,6.0,urban
50
+ 7.4,57.0,3.0,urban
51
+ 6.1,179.0,4.0,urban
52
+ 6.6,135.0,4.0,urban
53
+ 7.3,154.0,2.0,urban
54
+ 3.1,97.0,1.0,urban
55
+ 5.4,153.0,3.0,urban
56
+ 5.1,163.0,22.0,urban
57
+ 4.7,129.0,4.0,urban
58
+ 5.4,129.0,3.0,urban
59
+ 9.0,131.0,16.0,urban
60
+ 4.3,85.0,5.0,urban
61
+ 7.9,114.0,14.0,urban
62
+ 2.6,114.0,12.0,urban
63
+ 5.3,135.0,12.0,urban
64
+ 6.3,160.0,4.0,urban
65
+ 7.2,78.0,9.0,urban
66
+ 7.4,115.0,29.0,urban
67
+ 7.6,179.0,14.0,urban
68
+ 5.3,90.0,12.0,urban
69
+ 5.1,87.0,6.0,urban
70
+ 7.7,128.0,12.0,urban
71
+ 5.6,154.0,7.0,urban
72
+ 3.4,120.0,2.0,urban
73
+ 3.7,173.0,4.0,urban
74
+ 4.2,154.0,2.0,urban
75
+ 7.0,154.0,11.0,urban
76
+ 6.3,142.0,1.0,urban
77
+ 7.4,213.0,1.0,urban
78
+ 5.1,112.0,2.0,urban
79
+ 6.3,40.0,5.0,urban
80
+ 7.3,184.0,2.0,urban
81
+ 5.4,102.0,13.0,urban
82
+ 6.9,124.0,8.0,urban
83
+ 4.7,172.0,51.0,urban
84
+ 5.3,56.0,34.0,urban
85
+ 5.2,70.0,7.0,urban
86
+ 3.6,56.0,6.0,urban
87
+ 7.0,88.0,1.0,urban
88
+ 5.1,138.0,16.0,urban
89
+ 6.0,141.0,35.0,urban
90
+ 7.0,131.0,7.0,urban
91
+ 6.9,63.0,16.0,urban
92
+ 7.3,28.0,1.0,urban
93
+ 5.8,122.0,74.0,urban
94
+ 5.2,101.0,1.0,urban
95
+ 5.8,138.0,15.0,urban
96
+ 2.6,148.0,1.0,urban
97
+ 3.1,126.0,3.0,urban
98
+ 3.4,150.0,4.0,urban
99
+ 4.0,129.0,11.0,urban
100
+ 6.8,141.0,1.0,urban
101
+ 4.2,92.0,4.0,urban
102
+ 5.2,113.0,2.0,urban
103
+ 8.6,128.0,1.0,urban
104
+ 5.3,153.0,17.0,urban
105
+ 7.5,104.0,5.0,urban
106
+ 4.1,141.0,1.0,urban
107
+ 5.6,109.0,6.0,urban
108
+ 4.1,115.0,2.0,urban
109
+ 5.3,153.0,1.0,urban
110
+ 7.7,40.0,1.0,urban
111
+ 2.5,68.0,12.0,urban
112
+ 6.9,61.0,1.0,urban
113
+ 6.5,27.0,5.0,urban
114
+ 4.8,93.0,7.0,urban
115
+ 3.1,150.0,3.0,urban
116
+ 6.1,109.0,8.0,urban
117
+ 4.9,128.0,18.0,urban
118
+ 6.5,164.0,6.0,urban
119
+ 6.0,173.0,6.0,urban
120
+ 9.2,117.0,2.0,urban
121
+ 5.5,174.0,6.0,urban
122
+ 4.0,124.0,23.0,urban
123
+ 6.4,87.0,6.0,urban
124
+ 6.4,96.0,7.0,urban
125
+ 8.7,61.0,29.0,urban
126
+ 7.7,84.0,4.0,urban
127
+ 6.7,106.0,1.0,urban
128
+ 8.9,152.0,21.0,urban
129
+ 3.6,189.0,7.0,urban
130
+ 4.7,65.0,1.0,urban
131
+ 4.1,136.0,1.0,urban
132
+ 5.2,78.0,7.0,urban
133
+ 3.2,139.0,16.0,urban
134
+ 7.3,115.0,1.0,urban
135
+ 5.6,47.0,1.0,urban
136
+ 3.1,157.0,1.0,urban
137
+ 4.0,96.0,2.0,urban
138
+ 6.6,99.0,10.0,urban
139
+ 7.7,77.0,1.0,urban
140
+ 10.0,94.0,19.0,urban
141
+ 11.8,137.0,25.0,urban
142
+ 6.8,112.0,50.0,urban
143
+ 4.0,133.0,1.0,urban
144
+ 1.7,134.0,2.0,urban
145
+ 6.5,173.0,7.0,urban
146
+ 4.4,106.0,1.0,urban
147
+ 5.2,61.0,41.0,urban
148
+ 4.8,163.0,34.0,urban
149
+ 5.7,107.0,7.0,urban
150
+ 8.1,165.0,20.0,urban
151
+ 6.3,135.0,21.0,urban
152
+ 5.7,115.0,8.0,urban
153
+ 3.9,134.0,5.0,urban
154
+ 2.7,198.0,20.0,urban
155
+ 5.0,203.0,6.0,urban
156
+ 5.9,123.0,25.0,urban
157
+ 9.5,126.0,10.0,urban
158
+ 6.3,163.0,7.0,urban
159
+ 8.0,86.0,5.0,urban
160
+ 5.0,133.0,3.0,urban
161
+ 3.6,119.0,2.0,urban
162
+ 4.1,133.0,1.0,urban
163
+ 4.5,87.0,3.0,urban
164
+ 10.3,56.0,1.0,urban
165
+ 4.4,37.0,3.0,urban
166
+ 7.7,75.0,33.0,urban
167
+ 4.2,102.0,25.0,urban
168
+ 7.9,108.0,24.0,urban
169
+ 6.8,197.0,4.0,urban
170
+ 5.7,164.0,30.0,urban
171
+ 5.9,82.0,11.0,urban
172
+ 4.7,134.0,1.0,urban
173
+ 6.9,104.0,3.0,urban
174
+ 5.1,109.0,11.0,urban
175
+ 3.5,127.0,2.0,urban
176
+ 3.4,145.0,1.0,urban
177
+ 6.3,106.0,14.0,urban
178
+ 9.2,163.0,1.0,urban
179
+ 6.3,74.0,1.0,urban
180
+ 5.8,120.0,20.0,urban
181
+ 6.6,224.0,3.0,urban
182
+ 8.6,129.0,27.0,urban
183
+ 6.4,177.0,15.0,urban
184
+ 5.2,124.0,11.0,urban
185
+ 8.2,143.0,4.0,urban
186
+ 6.9,118.0,2.0,urban
187
+ 9.1,113.0,1.0,urban
188
+ 6.4,89.0,14.0,urban
189
+ 3.6,137.0,1.0,urban
190
+ 3.3,86.0,2.0,urban
191
+ 9.3,147.0,8.0,urban
192
+ 9.4,163.0,1.0,urban
193
+ 5.6,135.0,11.0,urban
194
+ 5.2,109.0,1.0,urban
195
+ 8.9,138.0,2.0,urban
196
+ 3.8,108.0,1.0,urban
197
+ 4.2,157.0,23.0,urban
198
+ 7.3,47.0,36.0,urban
199
+ 5.2,107.0,13.0,urban
200
+ 6.0,40.0,12.0,urban
201
+ 5.7,60.0,3.0,urban
202
+ 6.7,175.0,11.0,urban
203
+ 8.8,156.0,12.0,urban
204
+ 6.2,91.0,14.0,urban
205
+ 7.3,60.0,16.0,urban
206
+ 1.9,10.0,17.0,urban
207
+ 5.9,98.0,1.0,urban
208
+ 4.3,217.0,12.0,urban
209
+ 3.6,137.0,10.0,urban
210
+ 4.2,98.0,21.0,urban
211
+ 5.3,139.0,1.0,urban
212
+ 7.8,58.0,11.0,urban
213
+ 3.3,108.0,6.0,urban
214
+ 6.1,124.0,7.0,urban
215
+ 5.0,117.0,2.0,urban
216
+ 5.3,152.0,14.0,urban
217
+ 8.0,134.0,7.0,urban
218
+ 7.1,147.0,1.0,urban
219
+ 8.7,92.0,75.0,urban
220
+ 5.7,156.0,9.0,urban
221
+ 4.6,185.0,5.0,urban
222
+ 5.6,81.0,33.0,urban
223
+ 6.5,84.0,19.0,urban
224
+ 6.4,173.0,15.0,urban
225
+ 3.8,112.0,1.0,urban
226
+ 6.2,176.0,11.0,urban
227
+ 6.5,102.0,22.0,urban
228
+ 11.0,178.0,7.0,urban
229
+ 9.8,125.0,15.0,urban
230
+ 4.3,130.0,3.0,urban
231
+ 5.4,183.0,1.0,urban
232
+ 3.1,106.0,22.0,urban
233
+ 4.8,82.0,5.0,urban
234
+ 6.6,102.0,7.0,urban
235
+ 8.4,138.0,4.0,urban
236
+ 4.5,57.0,7.0,urban
237
+ 4.7,145.0,3.0,urban
238
+ 1.7,98.0,1.0,urban
239
+ 5.7,166.0,20.0,urban
240
+ 3.9,24.0,2.0,urban
241
+ 4.9,89.0,4.0,urban
242
+ 4.2,53.0,19.0,urban
243
+ 5.8,87.0,11.0,urban
244
+ 2.5,130.0,9.0,urban
245
+ 3.1,113.0,22.0,urban
246
+ 10.3,110.0,2.0,urban
247
+ 3.4,114.0,7.0,urban
248
+ 3.8,128.0,6.0,urban
249
+ 9.7,80.0,35.0,urban
250
+ 11.8,148.0,17.0,urban
251
+ 3.7,147.0,2.0,urban
252
+ 5.3,135.0,2.0,urban
253
+ 6.7,142.0,5.0,urban
254
+ 9.5,132.0,2.0,urban
255
+ 4.0,201.0,5.0,urban
256
+ 5.5,117.0,1.0,urban
257
+ 7.6,108.0,9.0,urban
258
+ 6.9,90.0,2.0,urban
259
+ 5.2,79.0,2.0,urban
260
+ 5.7,70.0,40.0,urban
261
+ 3.3,84.0,17.0,urban
262
+ 5.5,117.0,21.0,urban
263
+ 5.5,133.0,1.0,urban
264
+ 6.5,122.0,3.0,urban
265
+ 4.9,89.0,5.0,urban
266
+ 6.9,156.0,17.0,urban
267
+ 8.0,150.0,9.0,urban
268
+ 6.3,114.0,1.0,urban
269
+ 6.7,94.0,3.0,urban
270
+ 6.1,142.0,17.0,urban
271
+ 6.0,128.0,57.0,urban
272
+ 4.6,62.0,4.0,urban
273
+ 6.6,117.0,6.0,urban
274
+ 5.8,130.0,9.0,urban
275
+ 10.2,84.0,6.0,urban
276
+ 9.1,128.0,17.0,urban
277
+ 6.8,62.0,22.0,urban
278
+ 4.5,173.0,2.0,urban
279
+ 3.8,170.0,8.0,urban
280
+ 8.4,110.0,1.0,urban
281
+ 6.5,135.0,2.0,urban
282
+ 7.0,24.0,6.0,urban
283
+ 2.5,74.0,4.0,urban
284
+ 7.9,108.0,1.0,urban
285
+ 6.9,77.0,7.0,urban
286
+ 3.8,149.0,13.0,urban
287
+ 5.1,200.0,13.0,urban
288
+ 6.5,73.0,4.0,urban
289
+ 6.1,87.0,8.0,urban
290
+ 5.4,129.0,2.0,urban
291
+ 5.8,184.0,3.0,urban
292
+ 5.5,71.0,4.0,urban
293
+ 6.3,130.0,28.0,urban
294
+ 8.9,193.0,5.0,urban
295
+ 0.9,54.0,9.0,urban
296
+ 5.5,69.0,8.0,urban
297
+ 6.4,103.0,14.0,urban
298
+ 6.6,99.0,29.0,urban
299
+ 5.3,153.0,4.0,urban
300
+ 2.5,130.0,13.0,urban
301
+ 6.7,49.0,4.0,urban
302
+ 2.7,85.0,20.0,rural
303
+ 1.1,54.0,18.0,rural
304
+ 3.1,88.0,17.0,rural
305
+ 1.4,76.0,15.0,rural
306
+ 1.9,28.0,21.0,rural
307
+ 3.6,108.0,44.0,rural
308
+ 3.8,50.0,5.0,rural
309
+ 2.1,15.0,32.0,rural
310
+ 4.5,34.0,1.0,rural
311
+ 4.7,34.0,46.0,rural
312
+ 5.2,67.0,2.0,rural
313
+ 3.8,57.0,2.0,rural
314
+ 5.0,55.0,9.0,rural
315
+ 0.5,84.0,2.0,rural
316
+ 2.5,75.0,1.0,rural
317
+ 1.7,74.0,1.0,rural
318
+ 3.2,77.0,5.0,rural
319
+ 2.1,83.0,26.0,rural
320
+ 2.8,10.0,2.0,rural
321
+ 5.8,54.0,14.0,rural
322
+ 2.7,10.0,26.0,rural
323
+ 3.6,66.0,3.0,rural
324
+ 2.7,65.0,5.0,rural
325
+ 3.1,96.0,76.0,rural
326
+ 3.0,101.0,18.0,rural
327
+ 3.7,71.0,11.0,rural
328
+ 4.7,50.0,28.0,rural
329
+ 5.5,80.0,2.0,rural
330
+ 3.5,49.0,23.0,rural
331
+ 3.9,65.0,21.0,rural
332
+ 1.3,95.0,7.0,rural
333
+ 2.9,48.0,5.0,rural
334
+ 4.4,89.0,12.0,rural
335
+ 4.3,85.0,22.0,rural
336
+ 3.3,36.0,24.0,rural
337
+ 4.3,94.0,34.0,rural
338
+ 3.7,86.0,3.0,rural
339
+ 4.8,68.0,4.0,rural
340
+ 3.4,42.0,20.0,rural
341
+ 2.5,39.0,3.0,rural
342
+ 3.5,49.0,1.0,rural
343
+ 0.5,81.0,4.0,rural
344
+ 3.6,36.0,5.0,rural
345
+ 0.5,78.0,5.0,rural
346
+ 0.5,28.0,17.0,rural
347
+ 3.7,59.0,15.0,rural
348
+ 3.7,68.0,9.0,rural
349
+ 1.3,138.0,19.0,rural
350
+ 1.9,24.0,10.0,rural
351
+ 5.1,109.0,16.0,rural
352
+ 2.3,69.0,47.0,rural
353
+ 6.4,77.0,21.0,rural
354
+ 3.0,69.0,5.0,rural
355
+ 3.6,78.0,3.0,rural
356
+ 5.4,60.0,43.0,rural
357
+ 3.2,109.0,16.0,rural
358
+ 1.5,51.0,27.0,rural
359
+ 2.8,99.0,13.0,rural
360
+ 2.9,46.0,13.0,rural
361
+ 1.0,63.0,90.0,rural
362
+ 2.6,33.0,37.0,rural
363
+ 1.9,79.0,1.0,rural
364
+ 4.4,108.0,3.0,rural
365
+ 3.1,63.0,7.0,rural
366
+ 2.6,59.0,6.0,rural
367
+ 2.8,32.0,3.0,rural
368
+ 3.3,58.0,17.0,rural
369
+ 3.9,17.0,8.0,rural
370
+ 1.5,38.0,33.0,rural
371
+ 1.4,72.0,7.0,rural
372
+ 4.7,105.0,11.0,rural
373
+ 2.4,149.0,8.0,rural
374
+ 0.9,47.0,16.0,rural
375
+ 3.7,108.0,4.0,rural
376
+ 3.7,72.0,27.0,rural
377
+ 0.7,60.0,51.0,rural
378
+ 3.3,78.0,1.0,rural
379
+ 4.1,67.0,1.0,rural
380
+ 3.6,68.0,8.0,rural
381
+ 3.9,53.0,12.0,rural
382
+ 0.9,23.0,19.0,rural
383
+ 3.5,19.0,8.0,rural
384
+ 2.5,85.0,9.0,rural
385
+ 2.3,57.0,14.0,rural
386
+ 4.3,47.0,8.0,rural
387
+ 5.2,65.0,51.0,rural
388
+ 5.7,89.0,1.0,rural
389
+ 5.0,70.0,2.0,rural
390
+ 2.8,45.0,11.0,rural
391
+ 3.5,102.0,5.0,rural
392
+ 4.2,112.0,26.0,rural
393
+ 3.2,80.0,6.0,rural
394
+ 3.2,94.0,3.0,rural
395
+ 4.2,102.0,3.0,rural
396
+ 2.9,99.0,15.0,rural
397
+ 1.9,83.0,3.0,rural
398
+ 2.4,83.0,8.0,rural
399
+ 4.0,81.0,17.0,rural
400
+ 3.0,32.0,19.0,rural
401
+ 3.5,86.0,7.0,rural
data/export_data.py ADDED
@@ -0,0 +1,63 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Export the synthetic datasets used by all tasks to CSV.
3
+ Run from project root: python data/export_data.py
4
+
5
+ Writes:
6
+ data/customers.csv - Task 2 (400 customers, biased urban/rural mix)
7
+ data/sales_history.csv - Task 5 (730 days of synthetic daily sales)
8
+ data/network_nodes.csv - Tasks 3/4 (20-node delivery network)
9
+ data/network_edges.csv - Tasks 3/4 (weighted edges + CO2 cost)
10
+
11
+ All generators use a fixed seed (42), so re-running this produces identical files.
12
+ """
13
+
14
+ import os, sys
15
+ import pandas as pd
16
+
17
+ # Allow `python data/export_data.py` from project root
18
+ sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
19
+
20
+ from task2_segmentation import generate_biased_data
21
+ from task5_forecasting import generate_sales
22
+ from task3_4_routing import _build_inline_network
23
+
24
+ OUT = os.path.dirname(os.path.abspath(__file__))
25
+
26
+
27
+ def export_customers():
28
+ df = generate_biased_data()
29
+ path = os.path.join(OUT, "customers.csv")
30
+ df.to_csv(path, index=False)
31
+ print(f" customers.csv ({len(df)} rows)")
32
+
33
+
34
+ def export_sales():
35
+ df = generate_sales()
36
+ path = os.path.join(OUT, "sales_history.csv")
37
+ df.to_csv(path, index=False)
38
+ print(f" sales_history.csv ({len(df)} rows)")
39
+
40
+
41
+ def export_network():
42
+ nodes_dict, edges_list, co2_list = _build_inline_network()
43
+ nodes = pd.DataFrame(
44
+ [(n, x, y, region) for n, (x, y, region) in nodes_dict.items()],
45
+ columns=["node", "x", "y", "region"],
46
+ )
47
+ nodes.to_csv(os.path.join(OUT, "network_nodes.csv"), index=False)
48
+ print(f" network_nodes.csv ({len(nodes)} rows)")
49
+
50
+ edges = pd.DataFrame(
51
+ [(a, b, km, co2) for (a, b, km), (_, _, co2) in zip(edges_list, co2_list)],
52
+ columns=["from", "to", "distance_km", "co2_kg"],
53
+ )
54
+ edges.to_csv(os.path.join(OUT, "network_edges.csv"), index=False)
55
+ print(f" network_edges.csv ({len(edges)} rows)")
56
+
57
+
58
+ if __name__ == "__main__":
59
+ print("Exporting synthetic datasets to data/:")
60
+ export_customers()
61
+ export_sales()
62
+ export_network()
63
+ print("Done.")
data/network_edges.csv ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from,to,distance_km,co2_kg
2
+ U1,U2,1.29,0.361
3
+ U2,U3,1.29,0.361
4
+ U1,U4,1.82,0.51
5
+ U2,U4,1.29,0.361
6
+ U2,U5,1.82,0.51
7
+ U3,U6,1.29,0.361
8
+ U4,U5,1.29,0.361
9
+ U5,U6,1.63,0.456
10
+ U4,U7,1.29,0.361
11
+ U5,U8,1.29,0.361
12
+ U6,U10,1.82,0.51
13
+ U7,U8,1.29,0.361
14
+ U8,U9,1.15,0.322
15
+ U9,U10,1.29,0.361
16
+ U5,U9,1.29,0.361
17
+ R1,R2,2.57,0.257
18
+ R2,R3,2.37,0.237
19
+ R1,R4,3.64,0.364
20
+ R2,R4,2.57,0.257
21
+ R3,R6,2.57,0.257
22
+ R4,R5,2.37,0.237
23
+ R5,R6,2.57,0.257
24
+ R4,R7,2.37,0.237
25
+ R5,R10,1.63,0.163
26
+ R7,R10,1.82,0.182
27
+ R7,R8,3.1,0.31
28
+ R8,R9,2.57,0.257
29
+ R6,R9,2.88,0.288
30
+ R8,R10,2.07,0.207
31
+ R5,R8,2.88,0.288
32
+ U3,R1,3.45,0.621
33
+ U10,R4,3.5,0.63
34
+ U6,R1,3.1,0.558
35
+ U9,R7,4.64,0.835
data/network_nodes.csv ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ node,x,y,region
2
+ U1,1.0,1.0,urban
3
+ U2,2.0,1.5,urban
4
+ U3,3.0,1.0,urban
5
+ U4,1.5,2.5,urban
6
+ U5,2.5,3.0,urban
7
+ U6,3.5,2.0,urban
8
+ U7,1.0,3.5,urban
9
+ U8,2.0,4.0,urban
10
+ U9,3.0,4.0,urban
11
+ U10,4.0,3.5,urban
12
+ R1,6.0,1.0,rural
13
+ R2,8.0,2.0,rural
14
+ R3,10.0,1.5,rural
15
+ R4,7.0,4.0,rural
16
+ R5,9.0,4.5,rural
17
+ R6,11.0,3.5,rural
18
+ R7,6.5,6.0,rural
19
+ R8,9.0,7.0,rural
20
+ R9,11.0,6.0,rural
21
+ R10,8.0,5.5,rural
data/sales_history.csv ADDED
@@ -0,0 +1,731 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ date,sales,dow,month,day_of_year,is_promo
2
+ 2023-01-01,102.43773663803545,6,1,1,0
3
+ 2023-01-02,111.96444845801017,0,1,2,0
4
+ 2023-01-03,163.10501235197285,1,1,3,1
5
+ 2023-01-04,120.58639789799882,2,1,4,0
6
+ 2023-01-05,76.49672208492315,3,1,5,0
7
+ 2023-01-06,68.89795809005373,4,1,6,0
8
+ 2023-01-07,85.90100406153492,5,1,7,0
9
+ 2023-01-08,102.62838105722544,6,1,8,0
10
+ 2023-01-09,125.30252868619702,0,1,9,0
11
+ 2023-01-10,124.17119921052821,1,1,10,0
12
+ 2023-01-11,125.23400304410067,2,1,11,0
13
+ 2023-01-12,167.43172372281362,3,1,12,1
14
+ 2023-01-13,84.9592277706889,4,1,13,0
15
+ 2023-01-14,98.99900311421017,5,1,14,0
16
+ 2023-01-15,113.98698537825435,6,1,15,0
17
+ 2023-01-16,123.63557916328229,0,1,16,0
18
+ 2023-01-17,139.00153037856978,1,1,17,0
19
+ 2023-01-18,115.5653299865313,2,1,18,0
20
+ 2023-01-19,109.27735791877082,3,1,19,0
21
+ 2023-01-20,89.02818137525897,4,1,20,0
22
+ 2023-01-21,93.47623001370168,5,1,21,0
23
+ 2023-01-22,109.74960853182331,6,1,22,0
24
+ 2023-01-23,145.21509948671985,0,1,23,0
25
+ 2023-01-24,139.71349819773945,1,1,24,0
26
+ 2023-01-25,124.67999046887304,2,1,25,0
27
+ 2023-01-26,104.27358222264792,3,1,26,0
28
+ 2023-01-27,98.49629938189844,4,1,27,0
29
+ 2023-01-28,102.65693912282829,5,1,28,0
30
+ 2023-01-29,123.24387172888191,6,1,29,0
31
+ 2023-01-30,143.5917086903953,0,1,30,0
32
+ 2023-01-31,162.7574006179084,1,1,31,0
33
+ 2023-02-01,129.49261110094622,2,2,32,0
34
+ 2023-02-02,107.59158898411077,3,2,33,0
35
+ 2023-02-03,92.28682723100339,4,2,34,0
36
+ 2023-02-04,109.17946084560805,5,2,35,0
37
+ 2023-02-05,133.44984859341182,6,2,36,0
38
+ 2023-02-06,209.26699662332157,0,2,37,1
39
+ 2023-02-07,143.29101346727592,1,2,38,0
40
+ 2023-02-08,130.49031855701412,2,2,39,0
41
+ 2023-02-09,121.18951876229339,3,2,40,0
42
+ 2023-02-10,108.99012760068905,4,2,41,0
43
+ 2023-02-11,143.55599543883952,5,2,42,1
44
+ 2023-02-12,123.24130707138154,6,2,43,0
45
+ 2023-02-13,150.5308223995523,0,2,44,0
46
+ 2023-02-14,154.98879496661814,1,2,45,0
47
+ 2023-02-15,142.82493533383698,2,2,46,0
48
+ 2023-02-16,126.89060163691758,3,2,47,0
49
+ 2023-02-17,108.71132811748836,4,2,48,0
50
+ 2023-02-18,117.70220236143382,5,2,49,0
51
+ 2023-02-19,132.86951606377332,6,2,50,0
52
+ 2023-02-20,154.69097459036308,0,2,51,0
53
+ 2023-02-21,162.7500966866114,1,2,52,0
54
+ 2023-02-22,133.0016809619245,2,2,53,0
55
+ 2023-02-23,120.88336306147377,3,2,54,0
56
+ 2023-02-24,106.61826448809913,4,2,55,0
57
+ 2023-02-25,110.55475251264694,5,2,56,0
58
+ 2023-02-26,133.45792412228306,6,2,57,0
59
+ 2023-02-27,167.60214260620816,0,2,58,0
60
+ 2023-02-28,153.97128510437878,1,2,59,0
61
+ 2023-03-01,155.53600397577193,2,3,60,0
62
+ 2023-03-02,113.04050668016694,3,3,61,0
63
+ 2023-03-03,110.6959761447521,4,3,62,0
64
+ 2023-03-04,119.89190566490898,5,3,63,0
65
+ 2023-03-05,143.2024790486087,6,3,64,0
66
+ 2023-03-06,164.1148535584255,0,3,65,0
67
+ 2023-03-07,224.7611819373666,1,3,66,1
68
+ 2023-03-08,147.63784541205692,2,3,67,0
69
+ 2023-03-09,125.3692117081579,3,3,68,0
70
+ 2023-03-10,122.72946075417701,4,3,69,0
71
+ 2023-03-11,119.47544568241416,5,3,70,0
72
+ 2023-03-12,130.64799856621357,6,3,71,0
73
+ 2023-03-13,151.62373166734866,0,3,72,0
74
+ 2023-03-14,158.44143501361842,1,3,73,0
75
+ 2023-03-15,156.51664008217543,2,3,74,0
76
+ 2023-03-16,132.24170547430185,3,3,75,0
77
+ 2023-03-17,123.34587638288865,4,3,76,0
78
+ 2023-03-18,119.46578927380114,5,3,77,0
79
+ 2023-03-19,143.92087440267412,6,3,78,0
80
+ 2023-03-20,167.4145284203362,0,3,79,0
81
+ 2023-03-21,164.96235914700995,1,3,80,0
82
+ 2023-03-22,157.7535541892627,2,3,81,0
83
+ 2023-03-23,127.28645166361177,3,3,82,0
84
+ 2023-03-24,116.31634911869331,4,3,83,0
85
+ 2023-03-25,121.14760958980682,5,3,84,0
86
+ 2023-03-26,188.45914938533775,6,3,85,1
87
+ 2023-03-27,167.46028318374354,0,3,86,0
88
+ 2023-03-28,164.75473892881095,1,3,87,0
89
+ 2023-03-29,192.72292434454096,2,3,88,1
90
+ 2023-03-30,137.33629663953127,3,3,89,0
91
+ 2023-03-31,123.6190520532813,4,3,90,0
92
+ 2023-04-01,189.2753667233119,5,4,91,1
93
+ 2023-04-02,143.76174571337197,6,4,92,0
94
+ 2023-04-03,160.75606691153698,0,4,93,0
95
+ 2023-04-04,168.36730334478875,1,4,94,0
96
+ 2023-04-05,142.00360662967614,2,4,95,0
97
+ 2023-04-06,158.75243262149024,3,4,96,1
98
+ 2023-04-07,109.71156136678601,4,4,97,0
99
+ 2023-04-08,117.13045076151515,5,4,98,0
100
+ 2023-04-09,147.828467784484,6,4,99,0
101
+ 2023-04-10,193.5160274818295,0,4,100,1
102
+ 2023-04-11,165.89500098152413,1,4,101,0
103
+ 2023-04-12,225.2720613170759,2,4,102,1
104
+ 2023-04-13,130.719856832769,3,4,103,0
105
+ 2023-04-14,125.86147440901077,4,4,104,0
106
+ 2023-04-15,117.22569352351513,5,4,105,0
107
+ 2023-04-16,142.4912274022215,6,4,106,0
108
+ 2023-04-17,155.9631219433786,0,4,107,0
109
+ 2023-04-18,165.5497551399071,1,4,108,0
110
+ 2023-04-19,161.31827125709006,2,4,109,0
111
+ 2023-04-20,118.93158300174034,3,4,110,0
112
+ 2023-04-21,122.53665454430815,4,4,111,0
113
+ 2023-04-22,125.61654349257435,5,4,112,0
114
+ 2023-04-23,138.3220542062428,6,4,113,0
115
+ 2023-04-24,150.85628146811212,0,4,114,0
116
+ 2023-04-25,167.6218627539803,1,4,115,0
117
+ 2023-04-26,149.0644968478042,2,4,116,0
118
+ 2023-04-27,133.23850141666742,3,4,117,0
119
+ 2023-04-28,117.78585145262932,4,4,118,0
120
+ 2023-04-29,178.8611619145501,5,4,119,1
121
+ 2023-04-30,139.55744788539525,6,4,120,0
122
+ 2023-05-01,184.45325607988624,0,5,121,1
123
+ 2023-05-02,166.72565563256896,1,5,122,0
124
+ 2023-05-03,153.23275207170963,2,5,123,0
125
+ 2023-05-04,140.34929391397787,3,5,124,0
126
+ 2023-05-05,122.31765445689359,4,5,125,0
127
+ 2023-05-06,122.99620058824065,5,5,126,0
128
+ 2023-05-07,151.06059107871278,6,5,127,0
129
+ 2023-05-08,149.0472046849546,0,5,128,0
130
+ 2023-05-09,157.9143833953854,1,5,129,0
131
+ 2023-05-10,141.73180049799964,2,5,130,0
132
+ 2023-05-11,123.9604222999636,3,5,131,0
133
+ 2023-05-12,132.52906594253048,4,5,132,1
134
+ 2023-05-13,122.69096502443612,5,5,133,0
135
+ 2023-05-14,134.97889152449022,6,5,134,0
136
+ 2023-05-15,144.12821713962325,0,5,135,0
137
+ 2023-05-16,152.18086731834484,1,5,136,0
138
+ 2023-05-17,148.86228080457877,2,5,137,0
139
+ 2023-05-18,130.93126346950314,3,5,138,0
140
+ 2023-05-19,126.23189840446784,4,5,139,0
141
+ 2023-05-20,137.94604904543834,5,5,140,0
142
+ 2023-05-21,137.0378300347492,6,5,141,0
143
+ 2023-05-22,144.88573638980907,0,5,142,0
144
+ 2023-05-23,140.09901608815767,1,5,143,0
145
+ 2023-05-24,145.28929776052297,2,5,144,0
146
+ 2023-05-25,114.46076175811166,3,5,145,0
147
+ 2023-05-26,103.61890664301389,4,5,146,0
148
+ 2023-05-27,106.36884863751942,5,5,147,0
149
+ 2023-05-28,129.17456362484194,6,5,148,0
150
+ 2023-05-29,157.8571994044089,0,5,149,0
151
+ 2023-05-30,154.88920388573445,1,5,150,0
152
+ 2023-05-31,138.3072167081072,2,5,151,0
153
+ 2023-06-01,109.06017214008861,3,6,152,0
154
+ 2023-06-02,89.87901117565062,4,6,153,0
155
+ 2023-06-03,103.66465795006003,5,6,154,0
156
+ 2023-06-04,126.11611990040821,6,6,155,0
157
+ 2023-06-05,159.6754941106782,0,6,156,0
158
+ 2023-06-06,150.8361453503485,1,6,157,0
159
+ 2023-06-07,143.55902316490588,2,6,158,0
160
+ 2023-06-08,109.43278008637249,3,6,159,0
161
+ 2023-06-09,89.84086313037687,4,6,160,0
162
+ 2023-06-10,95.84159744859879,5,6,161,0
163
+ 2023-06-11,116.71674071290437,6,6,162,0
164
+ 2023-06-12,158.4980374280111,0,6,163,0
165
+ 2023-06-13,197.4520930870754,1,6,164,1
166
+ 2023-06-14,138.27928874526293,2,6,165,0
167
+ 2023-06-15,102.04800186830475,3,6,166,0
168
+ 2023-06-16,102.58861330641695,4,6,167,0
169
+ 2023-06-17,102.43044037626646,5,6,168,0
170
+ 2023-06-18,117.02778403797257,6,6,169,0
171
+ 2023-06-19,136.88191366184157,0,6,170,0
172
+ 2023-06-20,136.17573285870228,1,6,171,0
173
+ 2023-06-21,130.83258668153863,2,6,172,0
174
+ 2023-06-22,101.30370210835743,3,6,173,0
175
+ 2023-06-23,80.98423660285718,4,6,174,0
176
+ 2023-06-24,84.76268022053699,5,6,175,0
177
+ 2023-06-25,115.28063043987952,6,6,176,0
178
+ 2023-06-26,145.4448773978515,0,6,177,0
179
+ 2023-06-27,138.28460070582096,1,6,178,0
180
+ 2023-06-28,121.89344603839824,2,6,179,0
181
+ 2023-06-29,102.7980467335131,3,6,180,0
182
+ 2023-06-30,96.79570544929027,4,6,181,0
183
+ 2023-07-01,92.29201055829522,5,7,182,0
184
+ 2023-07-02,106.15686202887713,6,7,183,0
185
+ 2023-07-03,137.20181686663236,0,7,184,0
186
+ 2023-07-04,135.97051170315322,1,7,185,0
187
+ 2023-07-05,130.66225209372598,2,7,186,0
188
+ 2023-07-06,140.24621563834341,3,7,187,1
189
+ 2023-07-07,72.08559077235186,4,7,188,0
190
+ 2023-07-08,75.12746935164586,5,7,189,0
191
+ 2023-07-09,118.1910631729826,6,7,190,0
192
+ 2023-07-10,137.685185729864,0,7,191,0
193
+ 2023-07-11,126.65507622148981,1,7,192,0
194
+ 2023-07-12,110.86931439131052,2,7,193,0
195
+ 2023-07-13,103.30379743097649,3,7,194,0
196
+ 2023-07-14,68.60352114736358,4,7,195,0
197
+ 2023-07-15,74.50556016906036,5,7,196,0
198
+ 2023-07-16,175.12036889299347,6,7,197,1
199
+ 2023-07-17,116.35805885958641,0,7,198,0
200
+ 2023-07-18,123.6856031616647,1,7,199,0
201
+ 2023-07-19,108.28032328177422,2,7,200,0
202
+ 2023-07-20,89.98499014151307,3,7,201,0
203
+ 2023-07-21,84.41237544853115,4,7,202,0
204
+ 2023-07-22,78.10255290453212,5,7,203,0
205
+ 2023-07-23,101.47701783938554,6,7,204,0
206
+ 2023-07-24,98.87586102426175,0,7,205,0
207
+ 2023-07-25,119.12513198094614,1,7,206,0
208
+ 2023-07-26,98.65764024933782,2,7,207,0
209
+ 2023-07-27,73.37816368604783,3,7,208,0
210
+ 2023-07-28,62.00156966124213,4,7,209,0
211
+ 2023-07-29,70.61047403867317,5,7,210,0
212
+ 2023-07-30,99.59095259850992,6,7,211,0
213
+ 2023-07-31,100.63826501282968,0,7,212,0
214
+ 2023-08-01,115.76734146095338,1,8,213,0
215
+ 2023-08-02,97.57406547343963,2,8,214,0
216
+ 2023-08-03,140.72380450022644,3,8,215,1
217
+ 2023-08-04,73.16966287141392,4,8,216,0
218
+ 2023-08-05,73.74951889270451,5,8,217,0
219
+ 2023-08-06,99.16561436313452,6,8,218,0
220
+ 2023-08-07,106.25885091152821,0,8,219,0
221
+ 2023-08-08,106.24424681948105,1,8,220,0
222
+ 2023-08-09,95.99126041389822,2,8,221,0
223
+ 2023-08-10,77.5314968536974,3,8,222,0
224
+ 2023-08-11,62.98887647925068,4,8,223,0
225
+ 2023-08-12,57.24691983096977,5,8,224,0
226
+ 2023-08-13,85.71766396465938,6,8,225,0
227
+ 2023-08-14,105.89905913427042,0,8,226,0
228
+ 2023-08-15,128.58205372573642,1,8,227,0
229
+ 2023-08-16,109.48060129271389,2,8,228,0
230
+ 2023-08-17,65.50361531330358,3,8,229,0
231
+ 2023-08-18,56.070658756022624,4,8,230,0
232
+ 2023-08-19,51.06437476014382,5,8,231,0
233
+ 2023-08-20,77.17546345434825,6,8,232,0
234
+ 2023-08-21,103.563953989143,0,8,233,0
235
+ 2023-08-22,115.11448226002983,1,8,234,0
236
+ 2023-08-23,85.71906112130833,2,8,235,0
237
+ 2023-08-24,64.24374079837013,3,8,236,0
238
+ 2023-08-25,38.401175406240604,4,8,237,0
239
+ 2023-08-26,58.743687721101956,5,8,238,0
240
+ 2023-08-27,70.73916264728629,6,8,239,0
241
+ 2023-08-28,94.20610369381534,0,8,240,0
242
+ 2023-08-29,95.92129240245963,1,8,241,0
243
+ 2023-08-30,88.33303074979567,2,8,242,0
244
+ 2023-08-31,53.01819260121479,3,8,243,0
245
+ 2023-09-01,41.514755110330036,4,9,244,0
246
+ 2023-09-02,74.81993708615263,5,9,245,0
247
+ 2023-09-03,66.75013119086593,6,9,246,0
248
+ 2023-09-04,87.54920952888355,0,9,247,0
249
+ 2023-09-05,115.58493440171975,1,9,248,0
250
+ 2023-09-06,110.35339873887506,2,9,249,0
251
+ 2023-09-07,55.80618828769003,3,9,250,0
252
+ 2023-09-08,88.14302184833798,4,9,251,1
253
+ 2023-09-09,58.76502845809956,5,9,252,0
254
+ 2023-09-10,89.20062391372534,6,9,253,0
255
+ 2023-09-11,86.82567658245779,0,9,254,0
256
+ 2023-09-12,97.40052930139188,1,9,255,0
257
+ 2023-09-13,91.88133088594608,2,9,256,0
258
+ 2023-09-14,67.28379525257637,3,9,257,0
259
+ 2023-09-15,47.11884094612185,4,9,258,0
260
+ 2023-09-16,53.74480727960463,5,9,259,0
261
+ 2023-09-17,63.233322212076835,6,9,260,0
262
+ 2023-09-18,91.75566924474083,0,9,261,0
263
+ 2023-09-19,96.2516758591793,1,9,262,0
264
+ 2023-09-20,86.61990492912929,2,9,263,0
265
+ 2023-09-21,58.54322669230969,3,9,264,0
266
+ 2023-09-22,53.161184377262366,4,9,265,0
267
+ 2023-09-23,62.258835871564024,5,9,266,0
268
+ 2023-09-24,74.89887206160968,6,9,267,0
269
+ 2023-09-25,95.97956435819776,0,9,268,0
270
+ 2023-09-26,98.39422814114069,1,9,269,0
271
+ 2023-09-27,84.43141255250384,2,9,270,0
272
+ 2023-09-28,56.96375581910312,3,9,271,0
273
+ 2023-09-29,51.7535676654397,4,9,272,0
274
+ 2023-09-30,53.294068923497335,5,9,273,0
275
+ 2023-10-01,90.39868012525555,6,10,274,0
276
+ 2023-10-02,105.83299669205515,0,10,275,0
277
+ 2023-10-03,167.97097738190922,1,10,276,1
278
+ 2023-10-04,78.57263535079369,2,10,277,0
279
+ 2023-10-05,54.16619789997151,3,10,278,0
280
+ 2023-10-06,59.16294689583925,4,10,279,0
281
+ 2023-10-07,56.66944689358917,5,10,280,0
282
+ 2023-10-08,78.07243095137457,6,10,281,0
283
+ 2023-10-09,79.95021078918965,0,10,282,0
284
+ 2023-10-10,106.29540585351704,1,10,283,0
285
+ 2023-10-11,89.13847848789446,2,10,284,0
286
+ 2023-10-12,55.09050837666176,3,10,285,0
287
+ 2023-10-13,46.852344924990376,4,10,286,0
288
+ 2023-10-14,57.75001691292521,5,10,287,0
289
+ 2023-10-15,75.80571617995234,6,10,288,0
290
+ 2023-10-16,92.80586070121187,0,10,289,0
291
+ 2023-10-17,99.36569415382365,1,10,290,0
292
+ 2023-10-18,84.88608309739239,2,10,291,0
293
+ 2023-10-19,66.67401355520462,3,10,292,0
294
+ 2023-10-20,63.95647732759373,4,10,293,0
295
+ 2023-10-21,36.74708991376289,5,10,294,0
296
+ 2023-10-22,75.21095556624681,6,10,295,0
297
+ 2023-10-23,98.3543972797637,0,10,296,0
298
+ 2023-10-24,104.43948237887459,1,10,297,0
299
+ 2023-10-25,119.00726104191754,2,10,298,1
300
+ 2023-10-26,53.4340127348196,3,10,299,0
301
+ 2023-10-27,56.92021355306186,4,10,300,0
302
+ 2023-10-28,73.28777986552238,5,10,301,0
303
+ 2023-10-29,67.09985490228851,6,10,302,0
304
+ 2023-10-30,106.19371077355174,0,10,303,0
305
+ 2023-10-31,101.85932781379289,1,10,304,0
306
+ 2023-11-01,90.85824452212454,2,11,305,0
307
+ 2023-11-02,61.62916010539709,3,11,306,0
308
+ 2023-11-03,54.25846915550642,4,11,307,0
309
+ 2023-11-04,72.57983347051174,5,11,308,0
310
+ 2023-11-05,86.81441688126979,6,11,309,0
311
+ 2023-11-06,115.99521777288344,0,11,310,0
312
+ 2023-11-07,116.8309305560727,1,11,311,0
313
+ 2023-11-08,97.85534338238921,2,11,312,0
314
+ 2023-11-09,87.06655646113254,3,11,313,0
315
+ 2023-11-10,63.576913422530026,4,11,314,0
316
+ 2023-11-11,72.00152527731781,5,11,315,0
317
+ 2023-11-12,83.04520003257974,6,11,316,0
318
+ 2023-11-13,105.99927008071244,0,11,317,0
319
+ 2023-11-14,105.22712629958404,1,11,318,0
320
+ 2023-11-15,105.71800342286122,2,11,319,0
321
+ 2023-11-16,67.21021264587186,3,11,320,0
322
+ 2023-11-17,69.90727185272988,4,11,321,0
323
+ 2023-11-18,67.49689378931144,5,11,322,0
324
+ 2023-11-19,98.49223199442008,6,11,323,0
325
+ 2023-11-20,157.94277961640208,0,11,324,1
326
+ 2023-11-21,129.19318462432096,1,11,325,0
327
+ 2023-11-22,107.52599897144142,2,11,326,0
328
+ 2023-11-23,67.99471453920162,3,11,327,0
329
+ 2023-11-24,67.10210200766362,4,11,328,0
330
+ 2023-11-25,63.689087919109994,5,11,329,0
331
+ 2023-11-26,89.07175032291799,6,11,330,0
332
+ 2023-11-27,125.46754427626938,0,11,331,0
333
+ 2023-11-28,123.92605576502237,1,11,332,0
334
+ 2023-11-29,100.33544318777662,2,11,333,0
335
+ 2023-11-30,76.75654329591627,3,11,334,0
336
+ 2023-12-01,72.24222118438033,4,12,335,0
337
+ 2023-12-02,67.72070973685062,5,12,336,0
338
+ 2023-12-03,92.28152417619552,6,12,337,0
339
+ 2023-12-04,120.3498519979959,0,12,338,0
340
+ 2023-12-05,132.58652042378287,1,12,339,0
341
+ 2023-12-06,115.3561615537186,2,12,340,0
342
+ 2023-12-07,71.1348463487832,3,12,341,0
343
+ 2023-12-08,79.05221645945764,4,12,342,0
344
+ 2023-12-09,82.7039452744156,5,12,343,0
345
+ 2023-12-10,105.6721405673552,6,12,344,0
346
+ 2023-12-11,135.52841962785533,0,12,345,0
347
+ 2023-12-12,111.61637560634304,1,12,346,0
348
+ 2023-12-13,110.56747960871608,2,12,347,0
349
+ 2023-12-14,99.03330811815641,3,12,348,0
350
+ 2023-12-15,68.8347496845987,4,12,349,0
351
+ 2023-12-16,98.83347902136282,5,12,350,0
352
+ 2023-12-17,110.23272109695637,6,12,351,0
353
+ 2023-12-18,134.32154830820943,0,12,352,0
354
+ 2023-12-19,128.52878799220494,1,12,353,0
355
+ 2023-12-20,126.80302300292367,2,12,354,0
356
+ 2023-12-21,148.0421499264092,3,12,355,1
357
+ 2023-12-22,88.38810058929268,4,12,356,0
358
+ 2023-12-23,93.95706725331783,5,12,357,0
359
+ 2023-12-24,114.5215950297227,6,12,358,0
360
+ 2023-12-25,125.73070314781161,0,12,359,0
361
+ 2023-12-26,137.01890046472553,1,12,360,0
362
+ 2023-12-27,124.1883212688225,2,12,361,0
363
+ 2023-12-28,107.51796036479728,3,12,362,0
364
+ 2023-12-29,99.66060948180674,4,12,363,0
365
+ 2023-12-30,88.75905981756206,5,12,364,0
366
+ 2023-12-31,116.51139351120894,6,12,365,0
367
+ 2024-01-01,149.64743144297316,0,1,1,0
368
+ 2024-01-02,137.41302622027843,1,1,2,0
369
+ 2024-01-03,123.99595780452573,2,1,3,0
370
+ 2024-01-04,111.23614274564099,3,1,4,0
371
+ 2024-01-05,103.58398079142974,4,1,5,0
372
+ 2024-01-06,102.48421333228195,5,1,6,0
373
+ 2024-01-07,133.30575262139317,6,1,7,0
374
+ 2024-01-08,149.8084607182064,0,1,8,0
375
+ 2024-01-09,155.24890922419678,1,1,9,0
376
+ 2024-01-10,140.15237831510294,2,1,10,0
377
+ 2024-01-11,133.3758570920896,3,1,11,0
378
+ 2024-01-12,100.31457707825591,4,1,12,0
379
+ 2024-01-13,91.48021459651113,5,1,13,0
380
+ 2024-01-14,140.6108954123045,6,1,14,0
381
+ 2024-01-15,144.381102254284,0,1,15,0
382
+ 2024-01-16,154.45037316393723,1,1,16,0
383
+ 2024-01-17,151.2518252581878,2,1,17,0
384
+ 2024-01-18,106.97412750881396,3,1,18,0
385
+ 2024-01-19,96.96047346885702,4,1,19,0
386
+ 2024-01-20,163.9144375806662,5,1,20,1
387
+ 2024-01-21,126.39782566356135,6,1,21,0
388
+ 2024-01-22,156.50992479689114,0,1,22,0
389
+ 2024-01-23,162.70568226267474,1,1,23,0
390
+ 2024-01-24,147.8838231623126,2,1,24,0
391
+ 2024-01-25,113.36029901916152,3,1,25,0
392
+ 2024-01-26,131.9879466159023,4,1,26,1
393
+ 2024-01-27,117.7500653234399,5,1,27,0
394
+ 2024-01-28,133.75496540050938,6,1,28,0
395
+ 2024-01-29,161.41288407154778,0,1,29,0
396
+ 2024-01-30,168.83818041894742,1,1,30,0
397
+ 2024-01-31,151.45404694080761,2,1,31,0
398
+ 2024-02-01,135.38080895915175,3,2,32,0
399
+ 2024-02-02,118.24711748299707,4,2,33,0
400
+ 2024-02-03,126.11493744464299,5,2,34,0
401
+ 2024-02-04,136.41002642374482,6,2,35,0
402
+ 2024-02-05,160.77696600269354,0,2,36,0
403
+ 2024-02-06,169.22941751595351,1,2,37,0
404
+ 2024-02-07,161.30038875970948,2,2,38,0
405
+ 2024-02-08,130.4920519488709,3,2,39,0
406
+ 2024-02-09,124.87801017894594,4,2,40,0
407
+ 2024-02-10,123.99479463858296,5,2,41,0
408
+ 2024-02-11,145.3048451027742,6,2,42,0
409
+ 2024-02-12,221.17562133953112,0,2,43,1
410
+ 2024-02-13,155.80645958943023,1,2,44,0
411
+ 2024-02-14,184.42558600458636,2,2,45,1
412
+ 2024-02-15,125.77375642458499,3,2,46,0
413
+ 2024-02-16,105.974138127939,4,2,47,0
414
+ 2024-02-17,124.57385894889363,5,2,48,0
415
+ 2024-02-18,156.06215211638082,6,2,49,0
416
+ 2024-02-19,222.61036149558038,0,2,50,1
417
+ 2024-02-20,177.0377507992231,1,2,51,0
418
+ 2024-02-21,171.13742652698184,2,2,52,0
419
+ 2024-02-22,151.83622962303343,3,2,53,0
420
+ 2024-02-23,127.61152498791623,4,2,54,0
421
+ 2024-02-24,144.28734358184138,5,2,55,0
422
+ 2024-02-25,154.19857562776767,6,2,56,0
423
+ 2024-02-26,166.75566340317727,0,2,57,0
424
+ 2024-02-27,173.964820041588,1,2,58,0
425
+ 2024-02-28,153.77753760279876,2,2,59,0
426
+ 2024-02-29,137.24051935329328,3,2,60,0
427
+ 2024-03-01,128.36322702189136,4,3,61,0
428
+ 2024-03-02,142.88114728251148,5,3,62,0
429
+ 2024-03-03,170.1518268550974,6,3,63,0
430
+ 2024-03-04,165.25103533641828,0,3,64,0
431
+ 2024-03-05,184.6450714090067,1,3,65,0
432
+ 2024-03-06,160.00797675076845,2,3,66,0
433
+ 2024-03-07,204.81039249637735,3,3,67,1
434
+ 2024-03-08,132.743228517366,4,3,68,0
435
+ 2024-03-09,124.2958178401845,5,3,69,0
436
+ 2024-03-10,166.22804327571498,6,3,70,0
437
+ 2024-03-11,173.80927051214778,0,3,71,0
438
+ 2024-03-12,179.49623821523318,1,3,72,0
439
+ 2024-03-13,161.96292968470763,2,3,73,0
440
+ 2024-03-14,143.8609009603668,3,3,74,0
441
+ 2024-03-15,139.24931878469016,4,3,75,0
442
+ 2024-03-16,139.3854495656998,5,3,76,0
443
+ 2024-03-17,163.30889352445277,6,3,77,0
444
+ 2024-03-18,183.3437187671922,0,3,78,0
445
+ 2024-03-19,196.0525092556678,1,3,79,0
446
+ 2024-03-20,169.4187379312499,2,3,80,0
447
+ 2024-03-21,138.84030279816005,3,3,81,0
448
+ 2024-03-22,145.84353419811399,4,3,82,0
449
+ 2024-03-23,184.10772840284807,5,3,83,1
450
+ 2024-03-24,170.91403936011272,6,3,84,0
451
+ 2024-03-25,184.7516923438779,0,3,85,0
452
+ 2024-03-26,185.59281383867707,1,3,86,0
453
+ 2024-03-27,176.02406047619664,2,3,87,0
454
+ 2024-03-28,167.25400592739868,3,3,88,0
455
+ 2024-03-29,154.83006327410712,4,3,89,0
456
+ 2024-03-30,143.6792624689479,5,3,90,0
457
+ 2024-03-31,164.02226482573272,6,3,91,0
458
+ 2024-04-01,190.9553379108792,0,4,92,0
459
+ 2024-04-02,180.4545758885963,1,4,93,0
460
+ 2024-04-03,176.39350768638,2,4,94,0
461
+ 2024-04-04,151.85119236183175,3,4,95,0
462
+ 2024-04-05,141.05475432173046,4,4,96,0
463
+ 2024-04-06,136.70361856087047,5,4,97,0
464
+ 2024-04-07,150.1876724975561,6,4,98,0
465
+ 2024-04-08,165.8421935444664,0,4,99,0
466
+ 2024-04-09,178.27868746036702,1,4,100,0
467
+ 2024-04-10,200.16445052419405,2,4,101,1
468
+ 2024-04-11,149.54529982742483,3,4,102,0
469
+ 2024-04-12,153.7917135740902,4,4,103,0
470
+ 2024-04-13,151.88670756337743,5,4,104,0
471
+ 2024-04-14,154.79369309456112,6,4,105,0
472
+ 2024-04-15,184.7121825464708,0,4,106,0
473
+ 2024-04-16,183.38408323470546,1,4,107,0
474
+ 2024-04-17,170.7110047161845,2,4,108,0
475
+ 2024-04-18,152.63422439687588,3,4,109,0
476
+ 2024-04-19,142.42741099647554,4,4,110,0
477
+ 2024-04-20,139.42460826771384,5,4,111,0
478
+ 2024-04-21,170.02125799749058,6,4,112,0
479
+ 2024-04-22,171.73553510437839,0,4,113,0
480
+ 2024-04-23,185.55286754496328,1,4,114,0
481
+ 2024-04-24,192.55011217843023,2,4,115,0
482
+ 2024-04-25,151.64088950544067,3,4,116,0
483
+ 2024-04-26,190.2528302972716,4,4,117,1
484
+ 2024-04-27,141.4206064566727,5,4,118,0
485
+ 2024-04-28,199.05496709452262,6,4,119,1
486
+ 2024-04-29,178.8138144117391,0,4,120,0
487
+ 2024-04-30,182.4604253141735,1,4,121,0
488
+ 2024-05-01,163.77948705250853,2,5,122,0
489
+ 2024-05-02,151.4710025157188,3,5,123,0
490
+ 2024-05-03,127.38739147196146,4,5,124,0
491
+ 2024-05-04,144.03885712292842,5,5,125,0
492
+ 2024-05-05,166.61931521231196,6,5,126,0
493
+ 2024-05-06,180.0822062685548,0,5,127,0
494
+ 2024-05-07,179.34472999393697,1,5,128,0
495
+ 2024-05-08,171.3880159652456,2,5,129,0
496
+ 2024-05-09,143.23083662899444,3,5,130,0
497
+ 2024-05-10,139.28717340232407,4,5,131,0
498
+ 2024-05-11,121.59832591925966,5,5,132,0
499
+ 2024-05-12,152.7206855666726,6,5,133,0
500
+ 2024-05-13,158.6259642019886,0,5,134,0
501
+ 2024-05-14,167.01159159667185,1,5,135,0
502
+ 2024-05-15,175.9402934799108,2,5,136,0
503
+ 2024-05-16,150.07146292487357,3,5,137,0
504
+ 2024-05-17,123.1943047334632,4,5,138,0
505
+ 2024-05-18,121.31543436545057,5,5,139,0
506
+ 2024-05-19,128.714705676347,6,5,140,0
507
+ 2024-05-20,167.1703775667802,0,5,141,0
508
+ 2024-05-21,195.24277219088808,1,5,142,0
509
+ 2024-05-22,165.3583561791109,2,5,143,0
510
+ 2024-05-23,135.22684081749827,3,5,144,0
511
+ 2024-05-24,129.40882786999015,4,5,145,0
512
+ 2024-05-25,117.53150864334054,5,5,146,0
513
+ 2024-05-26,146.68282319011686,6,5,147,0
514
+ 2024-05-27,168.89249756199936,0,5,148,0
515
+ 2024-05-28,171.71796308638426,1,5,149,0
516
+ 2024-05-29,164.68315999308638,2,5,150,0
517
+ 2024-05-30,138.88927025842708,3,5,151,0
518
+ 2024-05-31,127.4159059809528,4,5,152,0
519
+ 2024-06-01,120.8469072182838,5,6,153,0
520
+ 2024-06-02,152.53343155163049,6,6,154,0
521
+ 2024-06-03,177.37366294964747,0,6,155,0
522
+ 2024-06-04,160.84826938767281,1,6,156,0
523
+ 2024-06-05,201.02409491688726,2,6,157,1
524
+ 2024-06-06,142.93919481140583,3,6,158,0
525
+ 2024-06-07,116.62028865451884,4,6,159,0
526
+ 2024-06-08,133.62839514109055,5,6,160,0
527
+ 2024-06-09,137.81803291302052,6,6,161,0
528
+ 2024-06-10,171.95470090105704,0,6,162,0
529
+ 2024-06-11,165.59957684581875,1,6,163,0
530
+ 2024-06-12,152.4892633535022,2,6,164,0
531
+ 2024-06-13,140.6449323328546,3,6,165,0
532
+ 2024-06-14,111.10115114684082,4,6,166,0
533
+ 2024-06-15,110.68446317886718,5,6,167,0
534
+ 2024-06-16,133.55810604489372,6,6,168,0
535
+ 2024-06-17,159.69534588608292,0,6,169,0
536
+ 2024-06-18,147.759352036326,1,6,170,0
537
+ 2024-06-19,151.23769731673934,2,6,171,0
538
+ 2024-06-20,119.50965157286264,3,6,172,0
539
+ 2024-06-21,177.3122885742165,4,6,173,1
540
+ 2024-06-22,94.71241101663567,5,6,174,0
541
+ 2024-06-23,126.4894416759613,6,6,175,0
542
+ 2024-06-24,138.2039689499304,0,6,176,0
543
+ 2024-06-25,149.2797223585019,1,6,177,0
544
+ 2024-06-26,143.7098906794999,2,6,178,0
545
+ 2024-06-27,117.96455268780244,3,6,179,0
546
+ 2024-06-28,103.20831273850182,4,6,180,0
547
+ 2024-06-29,108.15162328744006,5,6,181,0
548
+ 2024-06-30,129.95984353404543,6,6,182,0
549
+ 2024-07-01,139.17177860170324,0,7,183,0
550
+ 2024-07-02,157.08371505619044,1,7,184,0
551
+ 2024-07-03,142.56568363193813,2,7,185,0
552
+ 2024-07-04,118.01232070312875,3,7,186,0
553
+ 2024-07-05,105.22053864283303,4,7,187,0
554
+ 2024-07-06,107.33009777542973,5,7,188,0
555
+ 2024-07-07,140.14911642915928,6,7,189,0
556
+ 2024-07-08,204.6090472412169,0,7,190,1
557
+ 2024-07-09,144.5166049597658,1,7,191,0
558
+ 2024-07-10,126.78690495828599,2,7,192,0
559
+ 2024-07-11,102.23252463989701,3,7,193,0
560
+ 2024-07-12,86.38036446562339,4,7,194,0
561
+ 2024-07-13,93.42691884070908,5,7,195,0
562
+ 2024-07-14,118.8937203291911,6,7,196,0
563
+ 2024-07-15,141.05792128045803,0,7,197,0
564
+ 2024-07-16,143.00144705372568,1,7,198,0
565
+ 2024-07-17,122.32619154938124,2,7,199,0
566
+ 2024-07-18,113.34515602625318,3,7,200,0
567
+ 2024-07-19,97.92359080292256,4,7,201,0
568
+ 2024-07-20,94.95274484148996,5,7,202,0
569
+ 2024-07-21,109.95033155370008,6,7,203,0
570
+ 2024-07-22,138.50871792150951,0,7,204,0
571
+ 2024-07-23,139.85843727524409,1,7,205,0
572
+ 2024-07-24,112.65375679445947,2,7,206,0
573
+ 2024-07-25,101.41545340792874,3,7,207,0
574
+ 2024-07-26,89.94885033942451,4,7,208,0
575
+ 2024-07-27,84.90664104761471,5,7,209,0
576
+ 2024-07-28,112.59799576867817,6,7,210,0
577
+ 2024-07-29,118.42093943929856,0,7,211,0
578
+ 2024-07-30,145.01630629768852,1,7,212,0
579
+ 2024-07-31,130.2297850740655,2,7,213,0
580
+ 2024-08-01,95.98309530980583,3,8,214,0
581
+ 2024-08-02,86.84194125753292,4,8,215,0
582
+ 2024-08-03,68.94563528542217,5,8,216,0
583
+ 2024-08-04,97.98960117625207,6,8,217,0
584
+ 2024-08-05,123.91198520407657,0,8,218,0
585
+ 2024-08-06,121.99524291695793,1,8,219,0
586
+ 2024-08-07,122.25085524728703,2,8,220,0
587
+ 2024-08-08,110.3163162390481,3,8,221,0
588
+ 2024-08-09,70.90250044148713,4,8,222,0
589
+ 2024-08-10,77.95399312178323,5,8,223,0
590
+ 2024-08-11,105.60139841701707,6,8,224,0
591
+ 2024-08-12,135.6784619613339,0,8,225,0
592
+ 2024-08-13,117.37164873568473,1,8,226,0
593
+ 2024-08-14,115.15844607731353,2,8,227,0
594
+ 2024-08-15,105.59204825308727,3,8,228,0
595
+ 2024-08-16,63.83938460573348,4,8,229,0
596
+ 2024-08-17,71.19858273649447,5,8,230,0
597
+ 2024-08-18,97.17884498485348,6,8,231,0
598
+ 2024-08-19,115.53219932491287,0,8,232,0
599
+ 2024-08-20,130.6173350052949,1,8,233,0
600
+ 2024-08-21,112.12482672488412,2,8,234,0
601
+ 2024-08-22,73.90784839024332,3,8,235,0
602
+ 2024-08-23,78.32409121551275,4,8,236,0
603
+ 2024-08-24,74.03658728814946,5,8,237,0
604
+ 2024-08-25,108.03637988269126,6,8,238,0
605
+ 2024-08-26,112.01356471236943,0,8,239,0
606
+ 2024-08-27,116.42610759077128,1,8,240,0
607
+ 2024-08-28,111.98912718763037,2,8,241,0
608
+ 2024-08-29,91.7463560866355,3,8,242,0
609
+ 2024-08-30,75.38871031695088,4,8,243,0
610
+ 2024-08-31,62.84374927722402,5,8,244,0
611
+ 2024-09-01,99.8860227710517,6,9,245,0
612
+ 2024-09-02,106.57083448936446,0,9,246,0
613
+ 2024-09-03,121.28311379207207,1,9,247,0
614
+ 2024-09-04,94.22364636535121,2,9,248,0
615
+ 2024-09-05,87.23925160942011,3,9,249,0
616
+ 2024-09-06,63.44982575722681,4,9,250,0
617
+ 2024-09-07,64.23979069383867,5,9,251,0
618
+ 2024-09-08,99.53893220413634,6,9,252,0
619
+ 2024-09-09,115.09998599359557,0,9,253,0
620
+ 2024-09-10,112.88612954158535,1,9,254,0
621
+ 2024-09-11,115.69607853448966,2,9,255,0
622
+ 2024-09-12,78.6932239490161,3,9,256,0
623
+ 2024-09-13,68.78642372200424,4,9,257,0
624
+ 2024-09-14,75.35680784023522,5,9,258,0
625
+ 2024-09-15,87.65385058440548,6,9,259,0
626
+ 2024-09-16,115.79736608793726,0,9,260,0
627
+ 2024-09-17,112.47085116206566,1,9,261,0
628
+ 2024-09-18,99.81356487491668,2,9,262,0
629
+ 2024-09-19,92.21949997466851,3,9,263,0
630
+ 2024-09-20,59.38505169615594,4,9,264,0
631
+ 2024-09-21,114.0815398177219,5,9,265,1
632
+ 2024-09-22,104.84039235080134,6,9,266,0
633
+ 2024-09-23,131.84584812281793,0,9,267,0
634
+ 2024-09-24,113.00076971025415,1,9,268,0
635
+ 2024-09-25,87.1981767089496,2,9,269,0
636
+ 2024-09-26,78.50267864232751,3,9,270,0
637
+ 2024-09-27,65.17033216211378,4,9,271,0
638
+ 2024-09-28,70.77963358671997,5,9,272,0
639
+ 2024-09-29,82.96104443713018,6,9,273,0
640
+ 2024-09-30,116.08560985532205,0,9,274,0
641
+ 2024-10-01,187.27255495861453,1,10,275,1
642
+ 2024-10-02,90.90110844018938,2,10,276,0
643
+ 2024-10-03,86.82647992603158,3,10,277,0
644
+ 2024-10-04,84.21086520479885,4,10,278,0
645
+ 2024-10-05,74.08689667346927,5,10,279,0
646
+ 2024-10-06,89.66463885756349,6,10,280,0
647
+ 2024-10-07,110.89104507068292,0,10,281,0
648
+ 2024-10-08,121.90636356357685,1,10,282,0
649
+ 2024-10-09,89.75442083038807,2,10,283,0
650
+ 2024-10-10,83.37405445012179,3,10,284,0
651
+ 2024-10-11,65.57413792966824,4,10,285,0
652
+ 2024-10-12,150.45309512074232,5,10,286,1
653
+ 2024-10-13,92.04268446933224,6,10,287,0
654
+ 2024-10-14,126.52486974375837,0,10,288,0
655
+ 2024-10-15,109.3907153482288,1,10,289,0
656
+ 2024-10-16,109.615569306166,2,10,290,0
657
+ 2024-10-17,86.01291727749854,3,10,291,0
658
+ 2024-10-18,63.22503114886003,4,10,292,0
659
+ 2024-10-19,76.68112120358948,5,10,293,0
660
+ 2024-10-20,104.77629519756758,6,10,294,0
661
+ 2024-10-21,112.31121110973183,0,10,295,0
662
+ 2024-10-22,106.48400745827072,1,10,296,0
663
+ 2024-10-23,106.65492352295094,2,10,297,0
664
+ 2024-10-24,78.19467025505574,3,10,298,0
665
+ 2024-10-25,69.47295515873022,4,10,299,0
666
+ 2024-10-26,76.72095826871337,5,10,300,0
667
+ 2024-10-27,83.61954748578607,6,10,301,0
668
+ 2024-10-28,104.24126648875281,0,10,302,0
669
+ 2024-10-29,126.2170320910156,1,10,303,0
670
+ 2024-10-30,105.02967570281172,2,10,304,0
671
+ 2024-10-31,67.3866975983133,3,10,305,0
672
+ 2024-11-01,81.05499615728775,4,11,306,0
673
+ 2024-11-02,82.19048731939047,5,11,307,0
674
+ 2024-11-03,94.26426518232842,6,11,308,0
675
+ 2024-11-04,109.41432031860157,0,11,309,0
676
+ 2024-11-05,131.90059884296423,1,11,310,0
677
+ 2024-11-06,114.93033609812832,2,11,311,0
678
+ 2024-11-07,109.95928125654775,3,11,312,0
679
+ 2024-11-08,81.20048471498329,4,11,313,0
680
+ 2024-11-09,86.24400402556242,5,11,314,0
681
+ 2024-11-10,101.83798348377566,6,11,315,0
682
+ 2024-11-11,129.7477616601651,0,11,316,0
683
+ 2024-11-12,133.54499590666862,1,11,317,0
684
+ 2024-11-13,125.5442126279019,2,11,318,0
685
+ 2024-11-14,90.18656164112538,3,11,319,0
686
+ 2024-11-15,77.87727752063167,4,11,320,0
687
+ 2024-11-16,82.89305448893701,5,11,321,0
688
+ 2024-11-17,113.14430308048641,6,11,322,0
689
+ 2024-11-18,138.90503783075695,0,11,323,0
690
+ 2024-11-19,128.63708912966018,1,11,324,0
691
+ 2024-11-20,115.95372121419624,2,11,325,0
692
+ 2024-11-21,100.74823227741192,3,11,326,0
693
+ 2024-11-22,83.32884025771658,4,11,327,0
694
+ 2024-11-23,98.33156735881246,5,11,328,0
695
+ 2024-11-24,92.84671419661481,6,11,329,0
696
+ 2024-11-25,124.40013574821337,0,11,330,0
697
+ 2024-11-26,165.72401174675076,1,11,331,1
698
+ 2024-11-27,104.98683285214679,2,11,332,0
699
+ 2024-11-28,94.77359210557873,3,11,333,0
700
+ 2024-11-29,82.26892897406523,4,11,334,0
701
+ 2024-11-30,93.4485379480632,5,11,335,0
702
+ 2024-12-01,124.15270512688018,6,12,336,0
703
+ 2024-12-02,133.48594824754315,0,12,337,0
704
+ 2024-12-03,179.24572095783216,1,12,338,1
705
+ 2024-12-04,127.6122834786166,2,12,339,0
706
+ 2024-12-05,115.4352717915776,3,12,340,0
707
+ 2024-12-06,86.38138756204222,4,12,341,0
708
+ 2024-12-07,92.41009429868903,5,12,342,0
709
+ 2024-12-08,177.1603374416761,6,12,343,1
710
+ 2024-12-09,138.3845164202284,0,12,344,0
711
+ 2024-12-10,150.8560304431664,1,12,345,0
712
+ 2024-12-11,132.73700315981228,2,12,346,0
713
+ 2024-12-12,117.46542923908402,3,12,347,0
714
+ 2024-12-13,121.94271910086545,4,12,348,1
715
+ 2024-12-14,104.4682384167687,5,12,349,0
716
+ 2024-12-15,123.13615358372951,6,12,350,0
717
+ 2024-12-16,135.35452786422087,0,12,351,0
718
+ 2024-12-17,138.1184635813581,1,12,352,0
719
+ 2024-12-18,143.3062252399703,2,12,353,0
720
+ 2024-12-19,114.04110746957394,3,12,354,0
721
+ 2024-12-20,95.86949154854594,4,12,355,0
722
+ 2024-12-21,108.83305567565309,5,12,356,0
723
+ 2024-12-22,138.90179803222165,6,12,357,0
724
+ 2024-12-23,131.90873341419322,0,12,358,0
725
+ 2024-12-24,143.74176648934497,1,12,359,0
726
+ 2024-12-25,135.5399340448806,2,12,360,0
727
+ 2024-12-26,133.65374550632777,3,12,361,0
728
+ 2024-12-27,111.43540098671606,4,12,362,0
729
+ 2024-12-28,120.87796417305815,5,12,363,0
730
+ 2024-12-29,125.90184818207823,6,12,364,0
731
+ 2024-12-30,146.35096581330126,0,12,365,0
task2_segmentation.py CHANGED
@@ -7,6 +7,7 @@ Run: python3 task2_segmentation.py
7
  Out: bias_before_after.png, disparate_impact.png
8
  """
9
 
 
10
  import numpy as np
11
  import pandas as pd
12
  import matplotlib.pyplot as plt
@@ -14,6 +15,12 @@ from sklearn.cluster import KMeans
14
  from sklearn.preprocessing import StandardScaler
15
 
16
  RNG = np.random.default_rng(42)
 
 
 
 
 
 
17
 
18
  # 1. Generate biased customer data
19
  # Urban customers have more data, higher frequency, higher spend β€” mimicking
@@ -196,8 +203,8 @@ def main():
196
  print("EcoCart Customer Segmentation β€” Bias Detection & Mitigation")
197
  print("="*70)
198
 
199
- # Generate and segment (biased)
200
- df = generate_biased_data()
201
  df = segment(df)
202
  before = compute_fairness(df)
203
  print(f"\nBEFORE mitigation:")
 
7
  Out: bias_before_after.png, disparate_impact.png
8
  """
9
 
10
+ import os
11
  import numpy as np
12
  import pandas as pd
13
  import matplotlib.pyplot as plt
 
15
  from sklearn.preprocessing import StandardScaler
16
 
17
  RNG = np.random.default_rng(42)
18
+ CSV_PATH = os.path.join(os.path.dirname(os.path.abspath(__file__)), "data", "customers.csv")
19
+
20
+
21
+ def load_customers():
22
+ """Load the 400-customer dataset from data/customers.csv."""
23
+ return pd.read_csv(CSV_PATH)
24
 
25
  # 1. Generate biased customer data
26
  # Urban customers have more data, higher frequency, higher spend β€” mimicking
 
203
  print("EcoCart Customer Segmentation β€” Bias Detection & Mitigation")
204
  print("="*70)
205
 
206
+ # Load and segment (biased)
207
+ df = load_customers()
208
  df = segment(df)
209
  before = compute_fairness(df)
210
  print(f"\nBEFORE mitigation:")
task3_4_routing.py CHANGED
@@ -6,46 +6,84 @@ Run: python3 task3_4_routing.py
6
  Out: network_map.png, algo_comparison.png, green_vs_fast.png
7
  """
8
 
9
- import heapq, math, time, tracemalloc, statistics
10
  from collections import deque
 
11
  import matplotlib.pyplot as plt
12
  import matplotlib.patches as mpatches
13
  import networkx as nx
14
 
15
  # ── 1. Network ──────────────────────────────────────────────
16
- NODES = {
17
- # Urban cluster (dense, short edges)
18
- "U1":(1.0,1.0,"urban"),"U2":(2.0,1.5,"urban"),"U3":(3.0,1.0,"urban"),
19
- "U4":(1.5,2.5,"urban"),"U5":(2.5,3.0,"urban"),"U6":(3.5,2.0,"urban"),
20
- "U7":(1.0,3.5,"urban"),"U8":(2.0,4.0,"urban"),"U9":(3.0,4.0,"urban"),
21
- "U10":(4.0,3.5,"urban"),
22
- # Rural cluster (sparse, long edges)
23
- "R1":(6.0,1.0,"rural"),"R2":(8.0,2.0,"rural"),"R3":(10.0,1.5,"rural"),
24
- "R4":(7.0,4.0,"rural"),"R5":(9.0,4.5,"rural"),"R6":(11.0,3.5,"rural"),
25
- "R7":(6.5,6.0,"rural"),"R8":(9.0,7.0,"rural"),"R9":(11.0,6.0,"rural"),
26
- "R10":(8.0,5.5,"rural"),
27
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
28
  def _dist(a, b):
29
  return math.hypot(NODES[a][0]-NODES[b][0], NODES[a][1]-NODES[b][1])
30
- _PAIRS = [
31
- ("U1","U2"),("U2","U3"),("U1","U4"),("U2","U4"),("U2","U5"),
32
- ("U3","U6"),("U4","U5"),("U5","U6"),("U4","U7"),("U5","U8"),
33
- ("U6","U10"),("U7","U8"),("U8","U9"),("U9","U10"),("U5","U9"),
34
- ("R1","R2"),("R2","R3"),("R1","R4"),("R2","R4"),("R3","R6"),
35
- ("R4","R5"),("R5","R6"),("R4","R7"),("R5","R10"),("R7","R10"),
36
- ("R7","R8"),("R8","R9"),("R6","R9"),("R8","R10"),("R5","R8"),
37
- ("U3","R1"),("U10","R4"),("U6","R1"),("U9","R7"),
38
- ]
39
- # Road distance = 1.15Γ— straight-line
40
- EDGES = [(a, b, round(_dist(a,b)*1.15, 2)) for a, b in _PAIRS]
41
- # CO2 cost per edge: urban roads have traffic β†’ higher emissions per km
42
- # Rural roads: 0.12 kg CO2/km; Urban roads: 0.21 kg CO2/km
43
- def _co2(a, b, km):
44
- za, zb = NODES[a][2], NODES[b][2]
45
- rate = 0.28 if za == "urban" and zb == "urban" else 0.18 if za != zb else 0.10
46
- return round(km * rate, 3)
47
 
48
- CO2_EDGES = [(a, b, _co2(a, b, w)) for a, b, w in EDGES]
49
  ADJ_KM = {n: [] for n in NODES}
50
  ADJ_CO2 = {n: [] for n in NODES}
51
  for i, (a, b, w) in enumerate(EDGES):
 
6
  Out: network_map.png, algo_comparison.png, green_vs_fast.png
7
  """
8
 
9
+ import os, heapq, math, time, tracemalloc, statistics
10
  from collections import deque
11
+ import pandas as pd
12
  import matplotlib.pyplot as plt
13
  import matplotlib.patches as mpatches
14
  import networkx as nx
15
 
16
  # ── 1. Network ──────────────────────────────────────────────
17
+ _DATA_DIR = os.path.join(os.path.dirname(os.path.abspath(__file__)), "data")
18
+ NODES_CSV = os.path.join(_DATA_DIR, "network_nodes.csv")
19
+ EDGES_CSV = os.path.join(_DATA_DIR, "network_edges.csv")
20
+
21
+
22
+ def _build_inline_network():
23
+ """Inline source-of-truth for the 20-node delivery graph. Used by
24
+ data/export_data.py to (re)generate the CSV snapshots."""
25
+ nodes = {
26
+ # Urban cluster (dense, short edges)
27
+ "U1":(1.0,1.0,"urban"),"U2":(2.0,1.5,"urban"),"U3":(3.0,1.0,"urban"),
28
+ "U4":(1.5,2.5,"urban"),"U5":(2.5,3.0,"urban"),"U6":(3.5,2.0,"urban"),
29
+ "U7":(1.0,3.5,"urban"),"U8":(2.0,4.0,"urban"),"U9":(3.0,4.0,"urban"),
30
+ "U10":(4.0,3.5,"urban"),
31
+ # Rural cluster (sparse, long edges)
32
+ "R1":(6.0,1.0,"rural"),"R2":(8.0,2.0,"rural"),"R3":(10.0,1.5,"rural"),
33
+ "R4":(7.0,4.0,"rural"),"R5":(9.0,4.5,"rural"),"R6":(11.0,3.5,"rural"),
34
+ "R7":(6.5,6.0,"rural"),"R8":(9.0,7.0,"rural"),"R9":(11.0,6.0,"rural"),
35
+ "R10":(8.0,5.5,"rural"),
36
+ }
37
+ pairs = [
38
+ ("U1","U2"),("U2","U3"),("U1","U4"),("U2","U4"),("U2","U5"),
39
+ ("U3","U6"),("U4","U5"),("U5","U6"),("U4","U7"),("U5","U8"),
40
+ ("U6","U10"),("U7","U8"),("U8","U9"),("U9","U10"),("U5","U9"),
41
+ ("R1","R2"),("R2","R3"),("R1","R4"),("R2","R4"),("R3","R6"),
42
+ ("R4","R5"),("R5","R6"),("R4","R7"),("R5","R10"),("R7","R10"),
43
+ ("R7","R8"),("R8","R9"),("R6","R9"),("R8","R10"),("R5","R8"),
44
+ ("U3","R1"),("U10","R4"),("U6","R1"),("U9","R7"),
45
+ ]
46
+ def d(a, b):
47
+ return math.hypot(nodes[a][0]-nodes[b][0], nodes[a][1]-nodes[b][1])
48
+ edges = [(a, b, round(d(a,b)*1.15, 2)) for a, b in pairs]
49
+ def co2(a, b, km):
50
+ za, zb = nodes[a][2], nodes[b][2]
51
+ rate = 0.28 if za == "urban" and zb == "urban" else 0.18 if za != zb else 0.10
52
+ return round(km * rate, 3)
53
+ co2_edges = [(a, b, co2(a, b, w)) for a, b, w in edges]
54
+ return nodes, edges, co2_edges
55
+
56
+
57
+ def _load_network_from_csv():
58
+ """Load the delivery graph from data/network_nodes.csv + data/network_edges.csv."""
59
+ nodes_df = pd.read_csv(NODES_CSV)
60
+ edges_df = pd.read_csv(EDGES_CSV)
61
+ nodes = {
62
+ row["node"]: (float(row["x"]), float(row["y"]), row["region"])
63
+ for _, row in nodes_df.iterrows()
64
+ }
65
+ edges = [
66
+ (row["from"], row["to"], float(row["distance_km"]))
67
+ for _, row in edges_df.iterrows()
68
+ ]
69
+ co2_edges = [
70
+ (row["from"], row["to"], float(row["co2_kg"]))
71
+ for _, row in edges_df.iterrows()
72
+ ]
73
+ return nodes, edges, co2_edges
74
+
75
+
76
+ if os.path.exists(NODES_CSV) and os.path.exists(EDGES_CSV):
77
+ NODES, EDGES, CO2_EDGES = _load_network_from_csv()
78
+ else:
79
+ # First-time bootstrap (CSVs not yet generated) β€” fall back to inline.
80
+ NODES, EDGES, CO2_EDGES = _build_inline_network()
81
+
82
+
83
  def _dist(a, b):
84
  return math.hypot(NODES[a][0]-NODES[b][0], NODES[a][1]-NODES[b][1])
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
85
 
86
+
87
  ADJ_KM = {n: [] for n in NODES}
88
  ADJ_CO2 = {n: [] for n in NODES}
89
  for i, (a, b, w) in enumerate(EDGES):
task5_forecasting.py CHANGED
@@ -6,6 +6,7 @@ Run: python3 task5_forecasting.py
6
  Out: forecast.png, residuals.png, feature_importance.png
7
  """
8
 
 
9
  import numpy as np
10
  import pandas as pd
11
  import matplotlib.pyplot as plt
@@ -13,6 +14,12 @@ from sklearn.linear_model import LinearRegression
13
  from sklearn.ensemble import RandomForestRegressor
14
  from sklearn.metrics import mean_absolute_error, mean_squared_error, r2_score
15
  RNG = np.random.default_rng(42)
 
 
 
 
 
 
16
 
17
 
18
  # ── 1. Synthetic sales data ────────────────────────────────
@@ -62,7 +69,7 @@ def main():
62
  print("EcoCart Demand Forecasting β€” LR vs Random Forest")
63
  print("="*70)
64
 
65
- df = generate_sales()
66
  df = add_features(df)
67
  split = int(len(df) * 0.8)
68
  train, test = df.iloc[:split], df.iloc[split:]
 
6
  Out: forecast.png, residuals.png, feature_importance.png
7
  """
8
 
9
+ import os
10
  import numpy as np
11
  import pandas as pd
12
  import matplotlib.pyplot as plt
 
14
  from sklearn.ensemble import RandomForestRegressor
15
  from sklearn.metrics import mean_absolute_error, mean_squared_error, r2_score
16
  RNG = np.random.default_rng(42)
17
+ CSV_PATH = os.path.join(os.path.dirname(os.path.abspath(__file__)), "data", "sales_history.csv")
18
+
19
+
20
+ def load_sales():
21
+ """Load the 730-day daily sales dataset from data/sales_history.csv."""
22
+ return pd.read_csv(CSV_PATH, parse_dates=["date"])
23
 
24
 
25
  # ── 1. Synthetic sales data ────────────────────────────────
 
69
  print("EcoCart Demand Forecasting β€” LR vs Random Forest")
70
  print("="*70)
71
 
72
+ df = load_sales()
73
  df = add_features(df)
74
  split = int(len(df) * 0.8)
75
  train, test = df.iloc[:split], df.iloc[split:]