From a522e50d21e366e489d19fbd174d65bdb3d19988 Mon Sep 17 00:00:00 2001 From: SanJacobs Date: Sat, 23 Apr 2022 14:35:54 +0200 Subject: Started work on splitting price-segments --- src/main.cpp | 18 ++++++++++---- src/time.cpp | 78 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++--- src/time.h | 41 ++++++++++++++++++++++---------- 3 files changed, 117 insertions(+), 20 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index e554fb1..21b25cc 100755 --- a/src/main.cpp +++ b/src/main.cpp @@ -16,11 +16,10 @@ You should have received a copy of the GNU General Public License along with this program. If not, see https://www.gnu.org/licenses/ */ -// TODO: Make a system that effeciently stores a range of time, and lets you split it up neatly -// The slicing function could use a pointer to output the posterior half of the time range into -// The slicing process should figure out how many slices will need to be made before doing the slices, so a correctly sized array can be allocated on the stack instead of using a vec on the heap - +// TODO: Write function/method/constructor that slices a workday up into the differently priced segments // TODO: Make the system that determines the price of each of those slices of time +// TODO: Add ruleset selector (That only allows you to pick the advert ruleset at first) +// TODO: Make cool logo #include #include "time.h" @@ -41,6 +40,7 @@ int main(int argc, char* argv[]) std::cout << timeprint(workday) << std::endl; + std::cout << "\n\n --- TIME MATH TEST ---\n\n"; std::cout << "Difference between calltime and wraptime:\n"; @@ -62,9 +62,12 @@ int main(int argc, char* argv[]) std::cout << "\nSplitting second_half at erronious point...\n"; moment erronious_splitpoint{0, 10, 27, 11, 2010}; - std::cout << timeprint(timesplit(second_half, erronious_splitpoint)); + std::cout << timeprint(timesplit(second_half, erronious_splitpoint)) << "\n"; + + std::cout << "\n\n --- TIME WINDING TEST ---\n\n"; + moment testtime{30, 8, 25, 2, 2012}; std::cout << "Testtime: " << timeprint(testtime) << std::endl; @@ -112,6 +115,11 @@ int main(int argc, char* argv[]) std::cout << "-----\nStep 1: Adding the days\n\n"; + bool not_done = true; + while(not_done) { + + } + return 0; } } diff --git a/src/time.cpp b/src/time.cpp index 78f2a53..248d81b 100755 --- a/src/time.cpp +++ b/src/time.cpp @@ -2,7 +2,7 @@ // Look. listen here. There's no way I'm going to start taking DST into account. // I have to draw the line somewhere, and frankly, once you start doing "Change an hour on the 4th moon of the 2nd week of March in France, but only if the tulips haven't sprung... etc... etc.." I'm out. -// The fact that DST is designed this way, though, luckily makes it so you are unlikely to be on the clock during a DST transition. +// The fact that DST is designed this way, though, makes it so you are unlikely to be on the clock during a DST transition. // @@ -40,12 +40,22 @@ bool moment::operator!=(const moment& other) const { hours!=other.hours || minutes!=other.minutes); } +moment moment::operator+(const delta& other) const { + moment output{*this}; + wind(output, other.minutes, other.hours, other.days); + return output; +} +moment moment::operator-(const delta& other) const { + moment output{*this}; + wind(output, other.minutes*-1, other.hours*-1, other.days*-1); + return output; +} delta moment::operator-(const moment& other) const { // Uses what I call an accumulator-decumulator design // Count how long it takes to approach a benchmark, - // and that's the difference - // + // and that count is the difference + if(*this==other) return{0,0,0}; delta accumulator{0,0,0}; @@ -63,10 +73,16 @@ delta moment::operator-(const moment& other) const { wind(decumulator, 0, 0, -1); accumulator.days++; } + while(decumulator.hours - benchmark.hours > 1) { wind(decumulator, 0, -1, 0); accumulator.hours++; } + while(accumulator.hours > 23) { + accumulator.hours -= 24; + accumulator.days++; + } + while(decumulator != benchmark) { wind(decumulator, -1, 0, 0); accumulator.minutes = accumulator.minutes+1; @@ -75,10 +91,15 @@ delta moment::operator-(const moment& other) const { accumulator.minutes -= 60; accumulator.hours++; } + return accumulator; } std::ostream& operator<<(std::ostream& stream, const delta& other) { + if(other.days==0 && other.hours==0 && other.minutes==0){ + stream << "None."; + return stream; + } if(other.days) stream << other.days << " days, "; if(other.hours) stream << other.hours << " hours, "; if(other.minutes) stream << other.minutes << " minutes."; @@ -86,6 +107,45 @@ std::ostream& operator<<(std::ostream& stream, const delta& other) { } +// +// --- CONSTRUCTORS --- +// + +workday::workday(const moment& previous_wrap, + const moment& calltime, + const moment& wraptime, + const moment& planned_wraptime) { + call = calltime; + wrap = wraptime; + planned_wrap = planned_wraptime; + timeblock initial_block{call, wrap}; + moment splitpoints[10]{ // --$-- Points where the price may change --$-- // + + previous_wrap+(delta){0, 10, 0}, // Sleepbreach, 10 hours after previous wrap + (moment){0, 5, call.day, call.month, call.year}, // 2 hours before 7, aka 5 + (moment){0, 6, call.day, call.month, call.year}, // 6 in the morning + call+(delta){0, 8, 0}, // Normal 8 hours of work + call+(delta){0, 9, 0}, // 1st hour of overtime is over + planned_wraptime, // End of warned overtime + call+(delta){0, 14, 0}, // The 14-hour mark + (moment){0, 22, call.day, call.month, call.year}, // 22:00 in the evening + (moment){0, 23, call.day, call.month, call.year}+(delta){0, 1, 0}, // Midnight + (moment){0, 23, call.day, call.month, call.year}+(delta){0, 7, 0}, // 6, next morning + + }; + + int j = 0; + for(int i = 0; i<=10; i++) { + const moment* each_moment = &splitpoints[i]; + if(*each_moment > call && *each_moment < wrap) { + blocks[j++] = timesplit(initial_block, *each_moment); + // FIXME: The way timesplit will work is to be reversed, so this will act as expected. + } + } + +} + + // // --- METHODS --- // @@ -97,6 +157,13 @@ double timeblock::hourcount() { timedelta.days*24); } +weekday moment::getweekday() { + // Based on implementation from NProg on StackOverflow. Thanks. + int y = year; + static int t[] = { 0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4 }; + y -= month < 3; + return static_cast((y + y / 4 - y / 100 + y / 400 + t[month - 1] + day - 1) % 7); +} // @@ -110,10 +177,12 @@ std::string padint(const int input, const int minimum_signs) { } timeblock timesplit(timeblock& input_block, const moment splitpoint) { + // FIXME: Reverse the outputs. second_half replaces input_block, and return the first half. // Splits a timeblock at splitpoint. // It changes the input_block to end at splitpoint, and returns a new timeblock // that lasts from splitpoint to where the input_block used to end. if(splitpoint < input_block.start || splitpoint > input_block.end) { + // FIXME: This should use <= and >=, but they don't exist for moments... yet... ;) std::cerr << "ERROR: Splitpoint outside of timeblock!\n"; std::cerr << "Timeblock: " << timeprint(input_block) << std::endl; std::cerr << "Splitpoint: " << timeprint(splitpoint) << std::endl; @@ -171,6 +240,9 @@ void wind(moment& input_moment, const int minutes, const int hours, const int da input_moment.day += current_month_length; } } +void wind(moment& input_moment, const delta& time_delta) { + wind(input_moment, time_delta.minutes, time_delta.hours, time_delta.days); +} std::string timeprint(moment input_moment) { using namespace std; diff --git a/src/time.h b/src/time.h index 9e793ec..8bd886c 100755 --- a/src/time.h +++ b/src/time.h @@ -6,6 +6,16 @@ #include #include +enum weekday{ + monday, + tuesday, + wednesday, + thursday, + friday, + saturday, + sunday +}; + struct delta{ unsigned int minutes; unsigned int hours; @@ -20,29 +30,34 @@ struct moment{ signed int month; signed int year; + weekday getweekday(); + bool operator<(const moment& other) const; bool operator>(const moment& other) const; bool operator==(const moment& other) const; bool operator!=(const moment& other) const; delta operator-(const moment& other) const; + moment operator+(const delta& other) const; + moment operator-(const delta& other) const; }; struct timeblock{ moment start; moment end; double hourcount(); + float valuefactor = 1; }; struct workday{ moment call; moment wrap; moment planned_wrap; - timeblock blocks[12]; + timeblock blocks[14]; // - // 1. sleepbreach - // 2. call - // 3. early morning - // 4. start of day + // 1. call + // 2. sleepbreach + // 3. 6:00 + // 4. started 2 hours before 7 // 5. 1st hr overtime // 6. post-1 hour overtime // 7. end of warned ot @@ -52,22 +67,23 @@ struct workday{ // 11. 06:00 // 12. wrap // - workday(moment calltime, moment wraptime, moment planned_wraptime) { - - } - workday(moment previous_wrap, moment calltime, moment wraptime, moment planned_wraptime) { - - } + workday(const moment& previous_wrap, + const moment& calltime, + const moment& wraptime, + const moment& planned_wraptime); }; std::string padint(const int input, const int minimum_signs); timeblock timesplit(timeblock& input_block, const moment splitpoint); + // XXX: I have now found that it would be really nice if the first half is returned, + // and the second half replaces the instance at input_block; // Splits a timeblock at splitpoint. // It changes the input_block to end at splitpoint, and returns a new timeblock // that lasts from splitpoint to where the input_block used to end. -void wind(moment &input_moment, const int minutes, const int hours, const int days); +void wind(moment& input_moment, const int minutes, const int hours, const int days); +void wind(moment& input_moment, const delta& time_delta); int days_in(const int month, const int year); @@ -77,4 +93,5 @@ long sortable_time(const timeblock input_timeblock); moment timeinput(const int or_year, const int or_month, const int or_day); moment timeinput(); +// TODO: It would be nice to have a version that can take in a const reference to a moment, prompt for clock-time, and return the first moment at that clock-time forward in time from the input moment -- cgit v1.2.1