|
Brazil5259 Posts
So, I'm a CS student. My parents own a radio company(they are lit. Motorola resellers) and they have their share of needs in the world of computing, but they never actually asked me to do something until now. That's because only now have I been actually learning how to develop stuff properly.
Queue the request. It's a fairly simple system to create deadlines for certain jobs in the company, and show who is delaying or not. It's kinda cool.
The issues are, of course, the details. The request was simple: "we want to provide a time window in hours for a job, and the program has to give a date as the deadline". Simple right? Except that the deadline has to account for work days and hours.
Since I have little experience with the various programming languages, my language of choice is Java. Reason being that I'm more used to it and because I know it's very easy to find well documented libraries for almost everything in Java. And alas, there is joda-time as a sweeet date/time language. Love it.
However, It obviously does not include the concept of work days/hours. So how the f* do I implement that?
Man, have I learned a lot of lessons today. First I tried to implement a new class called WorkDateTime to simulate LocalDateTime. Too complicated and most of the functions were duplicates. Scratched.
I ended up making a function that converts a LocalDateTime to the next work hour compatible: so something at 12:20 would be converted to 13:30 on the same day, and Friday 19:00 would become Monday 08:00 of the next week. Joda-time is really good at that.
But the issue was with addition. Since I had a number of hours to serve as a base for my deadline, I needed to find a way to add these hours into a base time(the time of assignment for the job) and not count the non-working hours. Do I add and then count backwards? Do I try to predict it? Fuck this isn't trivial at all.
While trying to think of the solution, one came to mind that made me chuckle: add the hours one by one. For each addition, verify if the time "overflowed" past work hours. If so, convert the time to the next work hour and add the overflow. Finish the loop when there are neither hours nor overflow to add anymore.
I chuckled because that's one hell of an inefficient algorithm. It runs on more-than-linear time compared to the size of the deadline. I thought "that's stupid!" and went back to trying to figure out an efficient algorithm.
I spent literally 8 hours doing that(with a break to watch Liquid win and Brazil get destroyed by Germany). I still haven't figured out how would I implement the algorithm to consider the work hours when adding the new hour.
What did I do? I implemented the "inefficient" one. Not because I gave up, but because it wasn't worth to go to the next day thinking about it when the "inefficiency" isn't THAT costly: the calculation is done once per part of job(so about 150 times a day tops) and most of the deadlines are 2 to 5 hours, maybe one or another with a 20 hour deadline. When you translate this to computer processing, it's a ridiculously small value. The time I waste trying to figure out the efficient one will never be worth the smudge of efficiency I would harvest.
So I literally brute forced my way through this one. Lesson learned: just because it may not be the most efficient, if the efficiency is negligible the development cost isn't worth it.
On a side note, the IntelliJ Idea is awesome. Now to figure out how to work with databases... *shrug*
|
5 star for a programming blog.
|
|
To quote Knuth: "We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil"
Before you ever try to come up with a better algorithm to solve the problem you are facing its a really good idea to do some back of the envelope calculations and figure out how much your inefficiency is actually going to cost in real world terms. Its probably a little late to point that out now but hey you learned the lesson. Best of luck continuing with your development!
|
Cool to see a programming blog Been practicing on and off myself aswell and the algorithms really are the challenging part :D This question is more intended as quick brainstorming from a student looking to learn rather than advice from someone knowledgeable :D
Instead of adding the hours one by one and checking to see if they overflow to the next day, could you not "re-label" the hours so that hours 1-9 are monday, 10-18 are tuesday and so on? If a job takes 22 hours you'ld know that it falls into the scope of wednesday.
|
On July 09 2014 18:09 SilverSkyLark wrote: What IDE are you using?
Since he mentions IntelliJ IDEA, I would guess that.
Good on you for jumping on IDEA, it's an incredible IDE. If you're writing in Java, and trying to use databases, you should definitely consider using Hibernate. It's pretty awesome.
|
Brazil5259 Posts
On July 09 2014 21:26 Noyect wrote:Cool to see a programming blog Been practicing on and off myself aswell and the algorithms really are the challenging part :D This question is more intended as quick brainstorming from a student looking to learn rather than advice from someone knowledgeable :D Instead of adding the hours one by one and checking to see if they overflow to the next day, could you not "re-label" the hours so that hours 1-9 are monday, 10-18 are tuesday and so on? If a job takes 22 hours you'ld know that it falls into the scope of wednesday. This falls off when dealing with holidays, company breaks etc. Basically, later I'll need to have a holiday database as well.
Also yeah I'm using intellij idea
|
On July 09 2014 18:12 LightTemplar wrote: To quote Knuth: "We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil"
Before you ever try to come up with a better algorithm to solve the problem you are facing its a really good idea to do some back of the envelope calculations and figure out how much your inefficiency is actually going to cost in real world terms. Its probably a little late to point that out now but hey you learned the lesson. Best of luck continuing with your development! To be honest, it's really hard to know just how efficient your code has to be, because you don't know if you're slowing database queries or writing inefficient code that occasionally results in crashes/spikes to your services.
I think if you don't know how efficient your code needs to be it can be worthwhile to take the time to think of a way to optimize it slightly.
(I just need to really have a massive failure before I agree with Knuth).
|
How would you go about figuring out 23 work hours from now, starting at 2pm today, as a human, with pen and paper.
This is how you should start when you develop an algorithm.
I would start with breaking it into 2 separate pieces, how many days from now, and how many hours into that day.
23 hours is 2 days (8 hrs each) and 7 hours (23 - (2*8) = 7) Simply advance current time by 2 days and 7 hours. But wait, what if it's 12:00pm right now, that would mean I've already worked 3 hours today, so if I go 7 hours forward I'll end up with 10 hours. Delegate back to the same logic, 10 hours is 1 day and 2 hours. Advance a day, start 2 hours in.
We can see a pattern starting to form here, you have a concept of hours in a work day, and you have a concept of how that maps to hours in a day. The same pattern holds for days of work in a week.
If it's the 5th work day in the week and the last hour in that day, adding two hours will have to advance the day, which will advance the week.
The class could be laid out with a configuration something like this: hours_in_workday: 8 start_of_week: monday start_of_weekend: saturday length_of_weekend: 2 days start_of_day: 9:00am start_of_lunch: 12:00pm lunch_duration: 1:00hr
With this information you can construct a pretty simple time keeping system, and configure it as needed. Insert national holidays, etc.. etc..
While this solution is definitely more efficient than yours, I never once considered performance. All I was thinking of was the simplest solution that was easy to understand. I start with how I would solve the problem by hand with pen and paper. It's rather straight forward and kind of trivial when you really think about it. The only 'logic' is a switch to simply say 'is this number of hours larger than the work day' and 'is this number of days larger than the work week'.
Code clarity and simplicity is what allows you to build and maintain complex code bases.
There is a unique skillset for figuring out how you're really solving a problem, I mean if I told you to figure out what time you'd be done with something next week if you start on a wednesday afternoon at 2pm if it were to take you exactly 34 hours and you worked exactly 40 hours a week.
You'd be able to figure it out, and you wouldn't iterate through each hour to do it. You might even optimize your solution without even realizing it, subtracting the number of hours left in the current week since you know it will be some time next week, and then subtracting from that in 8 hour chunks to determine how many days into the next week it would be, and then subtracting 4 to determine how many hours after your lunch break it will be.
Converting that to code is a separate matter, and can be done many different ways, and that is where the real performance issues can be benchmarked and addressed.
|
On July 09 2014 23:58 Stegosaurus wrote:Since he mentions IntelliJ IDEA, I would guess that. Good on you for jumping on IDEA, it's an incredible IDE. If you're writing in Java, and trying to use databases, you should definitely consider using Hibernate. It's pretty awesome.
I think it is worthwhile to learn the basics of SQL though before jumping straight into Hibernate. I see a lot of people struggling with native SQL cause they've been too used to Hibernate.
|
Thought this was gonna be about the scheduling problem and algorithms from the beginning. Also, pretty sure your solution is linear time :p
|
haha I'd do this sort of thing on math tests where they had you add large numbers in series, I'd just write a quick program for the TI-83+ to brute force the problem rather than solve it analytically
|
|
|
|
|