Thoughtworks - repository developer-joyofenergy-cpp by RS
1 //file: z_developerJoyOfEnergy.cpp
2 //RS stands for Roberto Santander
3 #include "stdafx.h"
4 /***********START***************/
5 //(){}
6 /***********END*****************/
7 #include
8 #include
9 #include
10 #include
11 #include // std::chrono::seconds, std::chrono::milliseconds
12 // std::chrono::duration_cast
13 #include
14 #include
15
16 //----Rob Santander Notes -------------
17 /* communications/asynchronous
18 #include
19 #include
20 #include
21 #include
22 #include
23 */
24 //-----------------------
25
26 //RS this constant expressions a used to identify the type of billing
27 constexpr auto DR_EVILS_DARK_ENERGY_ENERGY_SUPPLIER = "Dr Evil's Dark Energy";
28 constexpr auto THE_GREEN_ECO_ENERGY_SUPPLIER = "The Green Eco";
29 constexpr auto POWER_FOR_EVERYONE_ENERGY_SUPPLIER = "Power for Everyone";
30
31 constexpr auto MOST_EVIL_PRICE_PLAN_ID = "price-plan-0";
32 constexpr auto RENEWABLES_PRICE_PLAN_ID = "price-plan-1";
33 constexpr auto STANDARD_PRICE_PLAN_ID = "price-plan-2";
34
35 constexpr auto SARAHS_SMART_METER_ID = "smart-meter-0";
36 constexpr auto PETERS_SMART_METER_ID = "smart-meter-1";
37 constexpr auto CHARLIES_SMART_METER_ID = "smart-meter-2";
38 constexpr auto ANDREAS_SMART_METER_ID = "smart-meter-3";
39 constexpr auto ALEXS_SMART_METER_ID = "smart-meter-4";
40
41 /*
42 //-------compilation errors Visual Studio Community start-----
43 //this block has been commented because come instructions are not
44 //compatible with the available compiler in Visual Studio Community C++14
45 class ElectricityReadingService {
46 public:
47 ElectricityReadingService(std::unordered_map
48 std::vector>& meterAssociatedReadings)
49 : meterAssociatedReadings(meterAssociatedReadings) {}
50
51 std::optional> GetReading(const std::string& meterId) {
52 //RS https://en.cppreference.com/w/cpp/utility/optional
53 //RS std::optional this is C++ 17 library
54 //RS Visual Studio is compatible with C++14 so far
55 auto found = meterAssociatedReadings.find(meterId);
56 if (found != meterAssociatedReadings.end()) {
57 return found->second;
58 }
59 return {};
60 }
61
62 private:
63 std::unordered_map>& meterAssociatedReadings;
64 };
65
66 class PricePlanService {
67 public:
68 using time_point_type = std::chrono::time_point;
69
70 std::optional>
71 getConsumptionCostOfElectricityReadingsForEachPricePlan(std::string smartMeterId) {
72 //RS https://en.cppreference.com/w/cpp/utility/optional
73 //RS std::optional this is C++ 17 library
74 //RS Visual Studio is compatible with C++14 so far
75 std::optional>
76 electricityReadings = meterReadingService.getReadings(smartMeterId);
77 if (!electricityReadings.has_value()) {
78 return {};
79 }
80
81 std::map consumptionCostOfElectricityReadingsForEachPricePlan;
82 for (auto pricePlan : pricePlans) {
83 consumptionCostOfElectricityReadingsForEachPricePlan.insert(
84 std::make_pair(pricePlan.getPlanName(),
85 calculateCost(electricityReadings.value(), pricePlan)));
86 }
87 return consumptionCostOfElectricityReadingsForEachPricePlan;
88 }
89
90 PricePlanService(std::vector& pricePlans, MeterReadingService& meterReadingService)
91 : pricePlans(pricePlans), meterReadingService(meterReadingService) {}
92
93 private:
94 const std::vector& pricePlans;
95 MeterReadingService& meterReadingService;
96
97 static auto calculateTimeElapsed(std::vector electricityReadings) {
98 ElectricityReading first = *electricityReadings.begin();
99 ElectricityReading last = *electricityReadings.begin();
100 std::vector::iterator it;
101 for (it = electricityReadings.begin(); it != electricityReadings.end(); it++) {
102 if (it->getTime() < first.getTime()) {
103 first = *it;
104 }
105 if (it->getTime() > first.getTime()) {
106 last = *it;
107 }
108 }
109
110 std::chrono::duration duration = last.getTime() - first.getTime();
111
112 return duration;
113 }
114
115 static int calculateCost(
116 const std::vector& electricityReadings, const PricePlan& pricePlan) {
117 int average = calculateAverageReading(electricityReadings);
118 auto secondsElapsed = std::chrono::duration_cast
119 (calculateTimeElapsed(electricityReadings));
120 int averagedCost = average * 3600 / secondsElapsed.count();
121 return averagedCost * pricePlan.getUnitRate();
122 }
123
124 static int calculateAverageRead(const std::vector& electricityReadings) {
125 int summedReadings = 0;
126 for (auto& electricityReading : electricityReadings) {
127 summedReadings += electricityReading.getReading();
128 }
129 return summedReadings / int(electricityReadings.size());
130 }
131 };
132 class MeterReadingService {
133 public:
134 std::optional> getReadings(const std::string& smartMeterId) {
135 //RS https://en.cppreference.com/w/cpp/utility/optional
136 //RS std::optional this is C++ 17 library
137 //RS Visual Studio is compatible with C++14 so far
138 std::shared_lock lock(mtx);
139 if (meterAssociatedReadings.find(smartMeterId) == meterAssociatedReadings.end()) {
140 return {};
141 }
142 return meterAssociatedReadings[smartMeterId];
143 }
144
145 void storeReadings(const std::string& smartMeterId,
146 std::vector& electricityReadings) {
147 std::unique_lock lock(mtx);
148 if (meterAssociatedReadings.find(smartMeterId) == meterAssociatedReadings.end()) {
149 meterAssociatedReadings[smartMeterId] = {};
150 }
151 meterAssociatedReadings[smartMeterId].insert
152 (meterAssociatedReadings[smartMeterId].end(), electricityReadings.begin(),
153 electricityReadings.end());
154 }
155
156 explicit MeterReadingService(std::unordered_map
157 std::vector>& meterAssociatedReadings)
158 : meterAssociatedReadings(meterAssociatedReadings) {}
159
160 private:
161 std::unordered_map>& meterAssociatedReadings;
162 mutable std::shared_mutex mtx;
163 };
164
165
166 auto readings() {
167 std::unordered_map> result;
168 for (auto& [meter, plan] : smart_meter_to_price_plan_accounts()) {
169 result[meter] = Generator{}.generate(21);
170 }
171 return result;
172 }
173 //-------compilation errors Visual Studio Community end-----
174 */
175
176
177 //RS The following classes are compatible with the available compiler
178 class PricePlan {
179 // todo:
180 public:
181 using time_point_type = std::chrono::time_point;
182 class PeakTimeMultiplier {
183 public:
184 enum DayOfWeek {
185 SUNDAY,
186 MONDAY,
187 TUESDAY,
188 WEDNESDAY,
189 THURSDAY,
190 FRIDAY,
191 SATURDAY
192 };
193
194 PeakTimeMultiplier(DayOfWeek dayOfWeek, int multiplier) :
195 dayOfWeek(dayOfWeek), multiplier(multiplier) {}
196
197 DayOfWeek dayOfWeek;
198 int multiplier;
199 };
200
201 PricePlan(std::string planName, std::string energySupplier,
202 int unitRate, std::vector peakTimeMultipliers)
203 : planName(std::move(planName)), energySupplier(std::move(energySupplier)),
204 unitRate(unitRate), peakTimeMultipliers(std::move(peakTimeMultipliers)) {}
205
206 std::string getEnergySupplier() const { return energySupplier; }
207
208 std::string getPlanName() const { return planName; }
209
210 int getUnitRate() const { return unitRate; }
211
212 int getPrice(time_point_type dateTime) const {
213 auto time_t_dateTime = std::chrono::system_clock::to_time_t(dateTime);
214 auto t = std::localtime(&time_t_dateTime);
215 auto it = std::find_if(peakTimeMultipliers.begin(),
216 peakTimeMultipliers.end(), [=](auto& p) {
217 return p.dayOfWeek == t->tm_wday;
218 });
219 if (it == peakTimeMultipliers.end()) {
220 return unitRate;
221 }
222 return unitRate * it->multiplier;
223 }
224 //-Roberto Santander
225
226
227 private:
228 const std::string energySupplier;
229 const std::string planName;
230 const int unitRate; // unit price per kWh
231 const std::vector peakTimeMultipliers;
232 };
233
234
235
236 class ElectricityReading {
237 public:
238 using time_point_type = std::chrono::time_point;
239
240 ElectricityReading(time_point_type time, size_t reading) : time(time), reading(reading) {}
241
242 time_point_type getTime() const { return time; }
243
244 size_t getReading() const { return reading; }
245
246 bool operator==(const ElectricityReading& rhs) const { return time == rhs.time && reading == rhs.reading; }
247 bool operator!=(const ElectricityReading& rhs) const { return !(rhs == *this); }
248
249 private:
250 time_point_type time;
251 size_t reading; // scale out in 0.1w for precision
252 };
253
254
255 std::vector pricePlans() {
256 std::vector price_plans;
257 price_plans.push_back(PricePlan(MOST_EVIL_PRICE_PLAN_ID, DR_EVILS_DARK_ENERGY_ENERGY_SUPPLIER, 10, {}));
258 price_plans.push_back(PricePlan(RENEWABLES_PRICE_PLAN_ID, THE_GREEN_ECO_ENERGY_SUPPLIER, 2, {}));
259 price_plans.push_back(PricePlan(STANDARD_PRICE_PLAN_ID, POWER_FOR_EVERYONE_ENERGY_SUPPLIER, 1, {}));
260 return price_plans;
261 }
262
263 std::unordered_map smart_meter_to_price_plan_accounts() {
264 return { {SARAHS_SMART_METER_ID, MOST_EVIL_PRICE_PLAN_ID},
265 {PETERS_SMART_METER_ID, RENEWABLES_PRICE_PLAN_ID},
266 {CHARLIES_SMART_METER_ID, MOST_EVIL_PRICE_PLAN_ID},
267 {ANDREAS_SMART_METER_ID, STANDARD_PRICE_PLAN_ID},
268 {ALEXS_SMART_METER_ID, RENEWABLES_PRICE_PLAN_ID} };
269 };
270
271
272 class Generator {
273 public:
274 std::vector generate(int number) {
275 std::vector readings;
276 readings.reserve(number);
277 auto now = std::chrono::system_clock::now();
278 for (int i = number; i > 0; i--) {
279 auto r = std::abs(std::rand()) % 4000;
280 readings.emplace_back(now - std::chrono::minutes(i * 3), 4000);
281 }
282 return readings;
283 }
284 };
285
286 class MeterReadings {
287 public:
288 MeterReadings() {}
289
290 MeterReadings(std::string smartMeterId, std::list electricityReadings)
291 : smartMeterId(smartMeterId), electricityReadings(electricityReadings) {};
292
293 std::list getElectricityReadings() { return electricityReadings; }
294
295 std::string getSmartMeterId() { return smartMeterId; }
296
297 private:
298 std::list electricityReadings;
299 std::string smartMeterId;
300 };
301 //THE FOLLOWING IS C++ CODE WRITTEN BY ROBERTO SANTANDER Aug 12 - 2024
302
303 /***********START***************/
301 /***********START***************/
302 //RS my code
303 void developerJOE(void) {
304 setJobID("devJoyOfEnergy");
305 master = 1;
306 boost::posix_time::ptime chronojobStart, t2, chronojobDiff;
307
308 chronojobStart = boost::posix_time::second_clock::local_time();
309 fout << "\n\tfirst clock --- " << to_simple_string(chronojobStart) << endl;
310
311 chronojobStart = boost::posix_time::microsec_clock::local_time();
312 fout << "\n\tmicrosec_clock --- " << to_simple_string(chronojobStart);
313 fout << "\n\tmc date --- " << to_simple_string(chronojobStart.date());
314 fout << "\n\tmc time of day --- " << to_simple_string(chronojobStart.time_of_day());
315
316 ///-------------------
317 string label = "From now on RS stands for Roberto Santander";
318
319 //std::unordered_map myRSunordered_map;
320 //myRSunordered_map = smart_meter_to_price_plan_accounts;
321
322 label = "what does smart_meter_to_price_plan_accounts() functon do? ";
323 out("h3", label);
324
325 label = "This is an undored map, it uses the global declaration at the top of this file, and it contains the following ";
326 out("p", label);
327
328 auto myRSunordered_map = smart_meter_to_price_plan_accounts();
329
330 for (auto& x : myRSunordered_map) {
331 fout << "\n\tRS: first: " << x.first << " second: " << x.second;
332 //out("p", label);
333 }
334
335 label = "myRSunordered_map:";
336 out("p", label);
337
338 fout << "\n\tmyRSunordered_map.size() is " << myRSunordered_map.size();
339 out("p", "myRSunordered_map.size() is: ", myRSunordered_map.size());
340
341 fout << "\n\tModifying the unordered map ";
342
343 //std::unordered_map myRSPair;
344 std::pair myRSPair;
345 //std::myRSPair ;
346
347 //for (unsigned short int i = 0; i <= myRSunordered_map.size(); i++ ) {
348
349 unsigned short changeThis = 2;
350 string lavelChangeThis = "price-plan-2";
351
352 unsigned short int i(0);
353 fout << "\n\n\tThis myRSunordered_map";
354 for (auto& x : myRSunordered_map) {
355 ++i;
356 fout << "\n\tmyRSPairfirst i: " << i << " " << x.first << " second: " << x.second;
357 //myRSPair = { x.first, x.second };
358 //if(myPair.first == "price-plan-0"){}
359 //fout << "\n\n\tmyRSPairfirst <0>: " << std::get<0>(myRSPair) << " <1>: " << std::get<1>(myRSPair);
360 //out("p", label);
361 }
362
363 fout << "\n\n\tHere the modification of the unordered map, no price-plan-0";
364 //unsigned short int i(0);
365 i = 0;
366 for (auto& x : myRSunordered_map) {
367 ++i;
368 fout << "\n\tmyRSPairfirst i: " << i << " " << x.first << " second: " << x.second;
369 myRSPair = { x.first, x.second };
370 //if(myPair.first == "price-plan-0"){}
371 if (std::get<1>(myRSPair) == MOST_EVIL_PRICE_PLAN_ID) {
372 //myRSunordered_map.erase(myRSunordered_map.begin() + 1); // erasing by iterator
373 fout << "\n\t\tI want to eliminate this plan of myRSunordered_map: " << "\t x.first: " << x.first << " second: " << x.second;
374 myRSPair = std::make_pair(std::get<0>(myRSPair), STANDARD_PRICE_PLAN_ID);
375 myRSunordered_map.insert(myRSPair); // move insertion
376 x.second = STANDARD_PRICE_PLAN_ID;
377
378 }
379 //out("p", label);
380 }
381
382 i = 0;
383 fout << "\n\n\tLets check it - there should be no price-plan-0";
384 for (auto& x : myRSunordered_map) {
385 ++i;
386 fout << "\n\tmyRSPairfirst i: " << i << " " << x.first << " second: " << x.second;
387 //fout << "\n\tmyRSPairfirst: " << x.first << " second: " << x.second;
388 }
389
390
391
392 ///----------------------
393 label = "ABOUT class PricePlan ";
394 out("h2", label);
395 label = "I will identify the use of the class PricePlan, ";
396
397 //---------------------------------------------------------
398 //RS(Roberto Santander) PricePlan obj
399 PricePlan RSPricePlanObj(); //construtor
400
401 //compiler error unresolved externals
402 //fout << "\n\tRSPricePlanObj().getEnergySupplier(): " << RSPricePlanObj().getEnergySupplier();
403 //fout << "\n\tRSPricePlanObj().getPlanName(): " << RSPricePlanObj().getPlanName();
404 //fout << "\n\tRSPricePlanObj().getUnitRate(): " << RSPricePlanObj().getUnitRate();
405
406 fout << "\n\tusing time_point_type = std::chrono::time_point;";
407 fout << "\n\ttime_point_type dateTime;";
408 using time_point_type = std::chrono::time_point;
409 time_point_type dateTime;
410 auto time_t_dateTime = std::chrono::system_clock::to_time_t(dateTime);
411 auto t = std::localtime(&time_t_dateTime);
412 fout << "\n\ttime_t_dateTime: " << time_t_dateTime;
413 fout << "\n\tt: " << t;
414
415 //unresolved external
416 //fout << "\n\tRSPricePlanObj().getPrice(): " << RSPricePlanObj().getPrice(dateTime);
417
418 auto myPPRobSan = pricePlans();
419 //for (std::vector::iterator it = myPPRobSan.begin(); it != myPPRobSan.end(); ++it) { }
420 i = 0;
421 for (auto& x : myPPRobSan) {
422 ++i;
423 fout << "\n\tx.getEnergySupplier i: " << i << " Supplier: " << x.getEnergySupplier() << "\tplan: " << x.getPlanName();
424 }
425
426 //---------------------------------------------------------
427 fout << "\n\tClass ElectricityReading / objRSElectricityReadingObj(): ";
428 ElectricityReading RSElectricityReadingObj();
429
430 //RSElectricityReadingObj().getReading();
431 //unresolved external
432 //fout << "\n\tRSElectricityReadingObj().getReading();: " << RSElectricityReadingObj().getReading();
433
434 //auto thisTime = RSElectricityReadingObj().getTime();
435 //fout << "\n\tRSElectricityReadingObj().getReading();: " << thisTime;
436
437 ///-----------------------------------
438 std::vector vecPlan = pricePlans();
439 fout << "\n\n\tmy vecPlan contains:";
440 for (std::vector::iterator it = vecPlan.begin(); it != vecPlan.end(); ++it) {
441 //fout << ' ' << *it;
442 //std::cout << '\n';
443 }
444
445 //auto myPPRobSan = pricePlans();
446 //for (std::vector::iterator it = myPPRobSan.begin(); it != myPPRobSan.end(); ++it) { }
447 i = 0;
448 for (auto& vecPlanItem : vecPlan) {
449 ++i;
450 /*
451 vecPlanItem.getEnergySupplier();
452 vecPlanItem.getPlanName();
453 //vecPlanItem.getPrice();
454 vecPlanItem.getUnitRate();
455 */
456
457 fout << "\n\ti: " << i << "vecPlanItem.getEnergySupplier() " << vecPlanItem.getEnergySupplier()
458 << "\n\tvecPlanItem.getPlanName(): " << vecPlanItem.getPlanName()
459 << "\n\tvecPlanItem.getUnitRate(): " << vecPlanItem.getUnitRate();
460 }
461 //-------------------------------------
462
463 //boost::posix_time::microseconds::total_microseconds;
464 using namespace boost::gregorian;
465 using namespace boost::posix_time;
466 {
467 chronojobStart = second_clock::local_time();
468 fout << "\n\tSecond_clock --- " << to_simple_string(chronojobStart) << endl;
469
470 chronojobStart = microsec_clock::local_time();
471 fout << "\n\tmicrosec_clock --- " << to_simple_string(chronojobStart);
472 fout << "\n\tmc date --- " << to_simple_string(chronojobStart.date());
473 fout << "\n\tmc time of day --- " << to_simple_string(chronojobStart.time_of_day());
474 }
475
476 return;
477 }
478 /**** END developerJOE ***/
479
480
481
482 ////Roberto Santander O U T P U T
483
484 | ExSan | C++ | ExSan | MSVSC2022_V17_7.0@ - toolSet(v143) -
485 Sun Aug 13 09:10 : 48 2023
486
487
488 exsan.plusplus@gmail.com https ://twitter.com/#!/ExSan_com
489 JOB: devJoyOfEnergy_1048
490
491 first clock-- - 2023 - Aug - 13 09 : 10 : 48
492
493 microsec_clock-- - 2023 - Aug - 13 09 : 10 : 48.341420
494 mc date-- - 2023 - Aug - 13
495 mc time of day-- - 09 : 10 : 48.341420
496 what does smart_meter_to_price_plan_accounts() functon do ?
497 This is an undored map, it uses the global declaration at the top of this file, and it contains the following
498 RS : first: smart - meter - 0 second : price - plan - 0
499 RS : first : smart - meter - 1 second : price - plan - 1
500 RS : first : smart - meter - 2 second : price - plan - 0
501 RS : first : smart - meter - 3 second : price - plan - 2
502 RS : first : smart - meter - 4 second : price - plan - 1
503 myRSunordered_map :
504 myRSunordered_map.size() is 5
505 myRSunordered_map.size() is : 5
506 Modifying the unordered map
507
508 This myRSunordered_map
509 myRSPairfirst i : 1 smart - meter - 0 second : price - plan - 0
510 myRSPairfirst i : 2 smart - meter - 1 second : price - plan - 1
511 myRSPairfirst i : 3 smart - meter - 2 second : price - plan - 0
512 myRSPairfirst i : 4 smart - meter - 3 second : price - plan - 2
513 myRSPairfirst i : 5 smart - meter - 4 second : price - plan - 1
514
515 Here the modification of the unordered map, no price - plan - 0
516 myRSPairfirst i : 1 smart - meter - 0 second : price - plan - 0
517 I want to eliminate this plan of myRSunordered_map : x.first : smart - meter - 0 second : price - plan - 0
518 myRSPairfirst i : 2 smart - meter - 1 second : price - plan - 1
519 myRSPairfirst i : 3 smart - meter - 2 second : price - plan - 0
520 I want to eliminate this plan of myRSunordered_map : x.first : smart - meter - 2 second : price - plan - 0
521 myRSPairfirst i : 4 smart - meter - 3 second : price - plan - 2
522 myRSPairfirst i : 5 smart - meter - 4 second : price - plan - 1
523
524 Lets check it - there should be no price - plan - 0
525 myRSPairfirst i : 1 smart - meter - 0 second : price - plan - 2
526 myRSPairfirst i : 2 smart - meter - 1 second : price - plan - 1
527 myRSPairfirst i : 3 smart - meter - 2 second : price - plan - 2
528 myRSPairfirst i : 4 smart - meter - 3 second : price - plan - 2
529 myRSPairfirst i : 5 smart - meter - 4 second : price - plan - 1
530 ABOUT class PricePlan
531 using time_point_type = std::chrono::time_point;
532 time_point_type dateTime;
533 time_t_dateTime: 0
534 t : 029306A0
535 x.getEnergySupplier i : 1 Supplier : Dr Evil's Dark Energy plan: price-plan-0
536 x.getEnergySupplier i : 2 Supplier : The Green Eco plan : price - plan - 1
537 x.getEnergySupplier i : 3 Supplier : Power for Everyone plan : price - plan - 2
538
539 Class ElectricityReading / objRSElectricityReadingObj() :
540
541
542 my vecPlan contains :
543 i: 1vecPlanItem.getEnergySupplier() Dr Evil's Dark Energy
544 vecPlanItem.getPlanName() : price - plan - 0
545 vecPlanItem.getUnitRate() : 10
546 i : 2vecPlanItem.getEnergySupplier() The Green Eco
547 vecPlanItem.getPlanName() : price - plan - 1
548 vecPlanItem.getUnitRate() : 2
549 i : 3vecPlanItem.getEnergySupplier() Power for Everyone
550 vecPlanItem.getPlanName() : price - plan - 2
551 vecPlanItem.getUnitRate() : 1
552 Second_clock-- - 2023 - Aug - 13 09 : 10 : 48
553
554 microsec_clock-- - 2023 - Aug - 13 09 : 10 : 48.343422
555 mc date-- - 2023 - Aug - 13
556 mc time of day-- - 09 : 10 : 48.343422
557
558 ENDS devJoyOfEnergy_1048 Elapsed Time : 0.003 sec
559 Boost version : 1.82.0
560
561 EXIT FROM EXSAN
Comments
Post a Comment