sharkdp / insect

High precision scientific calculator with support for physical units
https://numbat.dev/
MIT License
3.17k stars 125 forks source link

Dummy Units for calculating Workhours? (aka man-hours, person-hours, person-days, ...) #388

Closed johannesjh closed 12 months ago

johannesjh commented 1 year ago

I would love to use insect.sh for calculating project efforts using workhours (aka man-hours, person-hours, and its derivatives such as person-days, person-years, fulltime equivalents etc) . Could you add a dummy unit for this purpose? (or a way to define custom units?)

Background: Compare wikipedia https://en.wikipedia.org/wiki/Man-hour

The advantage of the man-hour concept is that it can be used to estimate the impact of staff changes on the amount of time required for a task, which can done by dividing the number of man-hours by the number of workers available. For example, if a task takes 20 man-hours to complete then a team of 2 people will complete it in 10 hours of work, while a team of 5 people will complete it in 4 hours.

Feature Request: The smallest possible change would be to add a new unit workhour , similar to the other dummy units from #136.

# in insect.sh pseudo code, I don't think this syntax exists:
define-unit workhour

# in purescript code:
Q.workhour ==> ["workhour", "workhours", "manhour", "manhours"]

Motivation: This would enable calculations such as the following examples

# I could then derive the following other units.
# These could also be hardcoded in insect.sh, or user-defined.
workday = 8 workhours
workyear = 200 workdays
fte = 1 workyear per year  # one full-time equivalent employee

# Which would allow to do calculations such as:

# half a million euros can finance how many workdays?
rate = 1000 EUR / workday
result = 0.5 million EUR / rate
# should return 500 workdays

# three full time equivalent employees working for half a year... are working for how many workdays?
result = 3 FTE * 0.5 year -> workday
# should return 300 workdays

# half a million euros can finance how many FTEs (full-time equivalent employees) over half a year?
budget = 0.5 million EUR
rate = 1000 EUR / workday
duration = 0.5 year
result = budget / rate / duration
# should return 5 FTE
sharkdp commented 1 year ago

This is an excellent idea, thank you very much. And I have good news. I am currently working on a complete rewrite on Insect. One of the key new features is that users are able to define units on their own (see unit keyword below, and ignore the additional dimension definition for now... this might not be mandatory in the future). I translated your pseudo Insect code to actual Insect-new code:

image

And this program correctly prints what you expected:

500.000000 workday
300.000000 workday
5.000000 FTE

(yeah, I need to work on the output formatting)

The bad news is that this new version is quite far from feature parity with the current version, so this will take some time until I can release it.

In the meantime, we could certainly think about introducing this to the current version somehow, but hard-coding those units (e.g. workday = 8 workhours) seems a bit strange.

johannesjh commented 1 year ago

Hi! Thank you, these are great news regarding the rewrite!! (note about the custom dimensions, sympy seems to have a similar separation between units and their underlying dimensions... and yes, I also think that workhours are best represented in a different dimension than regular time).

In the meantime, a minimal change would be to only introduce a single, hardcoded dummy unit, either workhour or workday. This would enable all of the above calculations without hardcoding any country- or project-dependant stuff. This change would add a single line of code, similar to Q.workhour ==> ["workhour", "workhours", "manhour", "manhours"], right? Would you accept this as PR - or be so kind to implement it yourself, since I have never programmed in purescript yet?

thank you and best regards, Johannes

sharkdp commented 1 year ago

In the meantime, a minimal change would be to only introduce a single, hardcoded dummy unit, either workhour or workday. This would enable all of the above calculations without hardcoding any country- or project-dependant stuff.

I don't think that works. We do have "dummy" units like this, see: https://github.com/sharkdp/insect/issues/136#issuecomment-362827365. We could abuse e.g. piece to mean "workhour". But then this happens:

image

That is correct, but we can not convert to workdays, because that is not a proper unit:

  result ➞ workday

   = 4000 piece

As a workaround, you can do

  result / workday

   = 500

which yields the desired result. But it's a bit unsatisfactory.

This change would add a single line of code, similar to Q.workhour ==> ["workhour", "workhours", "manhour", "manhours"], right?

There is a bit more work involved in a dependency: https://github.com/sharkdp/purescript-quantities — but following what we do for e.g. "piece" or "person" should work.

sharkdp commented 12 months ago

@johannesjh You can now play with this online: https://numbat.dev/ (I added your code as an example Numbat program here: https://github.com/sharkdp/numbat/blob/master/examples/workhours.nbt)

johannesjh commented 12 months ago

This is awesome, thank you, great work on numbat!! (I think we can close this issue, thank you so much!!!)