brutus / boozelib

a Python module to calculate blood alcohol levels
GNU General Public License v3.0
8 stars 2 forks source link

Help with documentation #2

Closed nikhilmaddirala closed 3 years ago

nikhilmaddirala commented 3 years ago

Thank you for creating this library! I'm having some trouble understanding the concepts of BAC "raise" and "degradation". Can you please help me understand if/how I can use your library to model the following scenario:

- 1. Drink 1st beer (5%, 350ml), 6:00 - 6:30pm
- 2. Drink 2nd beer (5%, 350ml), 6:30 - 7:00pm
- 3. Drink 3rd beer (5%, 350ml), 7:00 - 7:15pm
- Finally, I want to calculate my BAC at 8:00pm and again at 8:30pm.

Thanks in advance for any help you can offer! :)

nikhilmaddirala commented 3 years ago

Update: I think I understand the logic behind raise and degradation, but I'm still confused about a couple of things. Consider the example from the Readme:

>>> get_blood_alcohol_content(
>>> ... age=32, weight=96, height=186, sex=False, volume=500, percent=4.9
>>> ... )
>>> 0.28773587455687716

This example seems to be saying that after consuming 500ml of 4.9% alcohol, this person will reach a BAC of ~0.28. But when will the BAC reach this level? I think it takes ~ 15-20 minutes for the alcohol to get absorbed into the blood. Moreover, it also depends on how quickly / slowly the person consumes the drink. Therefore, I feel that this function needs some kind of time parameter.

brutus commented 3 years ago

I usually combine get_blood_alcohol_content and get_blood_alcohol_degradation in such cases. Depending on your use case, something like this might work:

def get_blood_alcohol_raise(
    *,
    age: int,
    weight: int,
    height: int,
    sex: bool,
    volume: int,
    percent: float,
    minutes: int,
) -> float:
    """Return the blood alcohol contents raise (per mill).

    For a person after a drink over *minutes*.

    """
    person = dict(age=age, weight=weight, height=height, sex=sex)
    drink = dict(volume=volume, percent=percent)
    bac_inc = get_blood_alcohol_content(**{**person, **drink})
    bac_dec = get_blood_alcohol_degradation(minutes=minutes, **person)
    return bac_inc - bac_dec

Used like…

bac_raise = get_blood_alcohol_raise(
    age=32, weight=96, height=186, sex=False, volume=500, percent=4.9, minutes=15
)
nikhilmaddirala commented 3 years ago

Thanks for your reply! Here's my problem with your approach:

Usage: get_blood_alcohol_raise(age=32, weight=96, height=186, sex=False, volume=500, percent=4.9, minutes=0)
Expected result: 0
Actual result: 0.28773587455687716

My expected result is 0, because alcohol is not immediately absorbed into the bloodstream when I consume a drink. Does this make sense?

brutus commented 3 years ago

I think I understand your point and you're right about that…

I'm not sure how to aproach the problem though… even if we find a formular that maps bac increase in respect to time (and it's general enough, to work for a broad range of persons), we still are left with a lot of variables: stomach contents, how well hydrated is the person, how used to consuming alcohol, etc. I feel, this should rather be solved by the person using the library - aware of their use case, needs and limitations, than hidden away inside a library function.

That said, if you have an idea how to aprach this, I'm open for suggestions.

As a side note: I created this library mainly to have a very simple module to play around with and try different Python testing and packaging best practice. And this is in no way a serious medical approach and also accepts a rather big level of abstraction. Depending on your use case, this might be okay; but I would not deem it fit for serious health and / or legal stuff ;)

nikhilmaddirala commented 3 years ago

Makes sense, @brutus — I totally understand your concerns. Let me get back to you if I think of any good solutions. My goal was to create graphs such as those generated by Intellidrink (an app which no longer exists):

image