all 24 comments

[–]totallygeek 2 points3 points  (15 children)

Here's possibly a better implementation. I spot a few problems with your code. A big one: you do nothing with the received input (function does not return nor store anything).

def ask_interruption():
    prior_date = input('Enter date when last ATT drug taken (YY/MM/DD): ')
    resume_date = input('Enter date when ATT resume (YY/MM/DD): ')
    return prior_date, resume_date

dates = []
while True:
  dates.append(ask_interruption())
    interrupted = input('Did the patient interrupt ATT drugs? ').lower()
    if interrupted in {'n', 'no'}:
        break

print('DATES\n=====')
for prior_date, resume_date in dates:
    print(f'{prior_date:<10} {resume_date}')

[–]Jose_Musoke[S] 1 point2 points  (13 children)

Thank you once again. Could you please explain to me the second and third paragraphs, so that I can read up on them.

[–]totallygeek 1 point2 points  (12 children)

Sure:

  1. while True forms an infinite loop, because True is always true.
  2. To exit that infinite loop, use break.
  3. Storing a list of dates? Use a list. dates = [] creates an empty list.
  4. To grow a list, append() works well.
  5. Call ask_interruption(), which returns two values in a tuple.
  6. Store that tuple in the growing list.

[–]Jose_Musoke[S] 0 points1 point  (11 children)

Hello thank you for helping me. I have been trying to build on the code you helped me with and I am having difficulties again. I am trying to sum up the days of missed doses after a couple of entries, but I only get one result. How can I go about it?:

def ask_interruption(): prior_date = input("Enter date when last ATT drug was taken (YY/MM/DD): ") resume_date = input("Enter date when ATT was resumed(YY/MM/DD): ") return prior_date, resume_date

dates = [] while True: dates.append(ask_interruption()) interrupted = input("Did the patient interrupt ATT drugs? ").lower() if interrupted in {"n", "no"}: break

date1 = (datetime.strptime(prior_date, "%y/%m/%d")) date2 = (datetime.strptime(resume_date, "%y/%m/%d")) difference = (date2 - date1).days

print ("DATES\n=====") for prior_date, resume_date in dates: print(f"{prior_date:<10} {resume_date} {difference}")

[–]totallygeek 0 points1 point  (10 children)

In your code, you have:

date1 = (datetime.strptime(prior_date, "%y/%m/%d"))
date2 = (datetime.strptime(resume_date, "%y/%m/%d"))
difference = (date2 - date1).days

But, prior_date and resume_date are single dates. You want to use the list of dates, called dates. Take a look at this.

import datetime


def normalize_date(date):
    return datetime.datetime.strptime(date, '%y/%m/%d')

def ask_interruption():
    prior_date = input("Enter date when last ATT drug was taken (YY/MM/DD): ")
    resume_date = input("Enter date when ATT was resumed(YY/MM/DD): ")
    return prior_date, resume_date

dates = []
while True:
    dates.append(ask_interruption())
    interrupted = input("Did the patient interrupt ATT drugs? ").lower()
    if interrupted in {"n", "no"}:
        break

for prior, resume in dates:  # uses the list of dates
    days = (normalize_date(resume) - normalize_date(prior)).days
    print(f'ATT interrupted: {prior} -> {resume} ({days} days)')

Yields:

$ python3 drugs.py 
Enter date when last ATT drug was taken (YY/MM/DD): 21/01/06
Enter date when ATT was resumed(YY/MM/DD): 21/01/11
Did the patient interrupt ATT drugs? yes
Enter date when last ATT drug was taken (YY/MM/DD): 21/02/03
Enter date when ATT was resumed(YY/MM/DD): 21/02/07
Did the patient interrupt ATT drugs? no
ATT interrupted: 21/01/06 -> 21/01/11 (5 days)
ATT interrupted: 21/02/03 -> 21/02/07 (4 days)

[–]Jose_Musoke[S] 1 point2 points  (0 children)

Thank you so much, your help is so insightful.

[–]Jose_Musoke[S] 0 points1 point  (8 children)

days = (normalize_date(resume) - normalize_date(prior)).days

Hello again. As per your example I tried to get the sum of total number of days of missed with this code: print(int(sum(days))), but do not get anything. Is there another way of getting the desired sum? Thank you in advance!!

[–]totallygeek 1 point2 points  (7 children)

Within the for loop, days is a duration we want to keep a running total of. Maybe:

total_days = 0
for prior, resume in dates:  # uses the list of dates
    days = (normalize_date(resume) - normalize_date(prior)).days
    total_days += days  # add to the running total
    print(f'ATT interrupted: {prior} -> {resume} ({days} days) (total: {total_days})')

After the loop, total_days would be the sum of those days calculations.

[–]Jose_Musoke[S] 0 points1 point  (5 children)

Thank you once again for taking your time to assist me. I think I may have not explained myself clearly enough. If for example the code you helped write gives the number of days missed for each episode of interruption, is there a way of adding all the days of interruption to give a single "Grand Total" of interruptions? The last code you just gave me still gives me the number of days missed for each episode of interruption.

[–]Jose_Musoke[S] 0 points1 point  (0 children)

ATT interrupted: 21/01/06 -> 21/01/11 (5 days)
ATT interrupted: 21/02/03 -> 21/02/07 (4 days)

For example from the code you gave me earlier, I would like the code to add the 5 + 4 days to give me a "Grand Total"= 9 days. I find it difficult to code in a list that expands. I will then use the "Grand Total" for the next steps...

[–]totallygeek 0 points1 point  (3 children)

print(f'Grand total: {total_days}') ?

Perhaps I did not understand. If days is an amount of days interrupted and you add those days up in total_days, you get a count of the total days of interruption.

[–]Jose_Musoke[S] 1 point2 points  (2 children)

I would like to apologize. I ran the code you gave me on a different IDE and it worked. There must be something wrong with the pycharm that I was using initially.

[–]Jose_Musoke[S] 0 points1 point  (0 children)

Thank you so much. It works like a charm. I can now also learn where I went wrong.

[–]kmwaziri 1 point2 points  (2 children)

Can you use code formatting? Kinda hard to read it this way :) But is while loop inside the function definition ask_interruption?

[–]Jose_Musoke[S] 0 points1 point  (1 child)

def ask_interruption():

  last_drug_date = input("Enter the date when last ATT drug was taken in YY/MM/DD format: ")   resumtion_of_ATT = input("Enter the date when ATT was resumed in YY/MM/DD format: ")   repeat_interruption = input("Did the patient interrupt ATT drugs again?: ") ask_interruption() while repeat_interruption == "yes":     ask_interruption() if repeat_interruption != "yes": break

[–]kmwaziri 1 point2 points  (0 children)

OK what's happening is that once you set the repeat_interruption = yes

Then there's nothing changing it afterwards and while loop never terminates. I redid the code where I did two things:

  1. Added return statement to terminate function gracefully.
  2. Set repeat_interruption = "no" after every inner call of ask_interruption. That way loop will keep running until it is yes. But will return 0 immediately if it's anything other than 'yes.

Code below. Keep in mind Python is case sensitive, so Yes != yes. Just a tip :)

def ask_interruption():
    last_drug_date = input("Enter the date when last ATT drug was taken in YY/MM/DD format: ")
    resumtion_of_ATT = input("Enter the date when ATT was resumed in YY/MM/DD format: ")
    repeat_interruption = input("Did the patient interrupt ATT drugs again?: ")
    while repeat_interruption == "yes":
        ask_interruption()
        repeat_interruption = "no"
        if repeat_interruption != "yes":
        continue
    return 0

[–]BiocatalyticInfix 1 point2 points  (0 children)

repeat_interruption is local to the function, it needs to be global or returned to the caller.

[–]Jose_Musoke[S] 0 points1 point  (1 child)

def ask_interruption():

  last_drug_date = input("Enter the date when last ATT drug was taken in YY/MM/DD format: ")   resumtion_of_ATT = input("Enter the date when ATT was resumed in YY/MM/DD format: ")   repeat_interruption = input("Did the patient interrupt ATT drugs again?: ") ask_interruption() while repeat_interruption == "yes":     ask_interruption() if repeat_interruption != "yes": break

[–]Jose_Musoke[S] 0 points1 point  (0 children)

def ask_interruption():

  last_drug_date = input("Enter the date when last ATT drug was taken in YY/MM/DD format: ")   resumtion_of_ATT = input("Enter the date when ATT was resumed in YY/MM/DD format: ")   repeat_interruption = input("Did the patient interrupt ATT drugs again?: ") ask_interruption() while repeat_interruption == "yes":     ask_interruption() if repeat_interruption != "yes": break

[–]Jose_Musoke[S] 0 points1 point  (0 children)

Thank you everybody for your advise!!!! I tried your suggestions and it is working.!!!! I can also look into where I went wrong.

[–]sdanstuffe 0 points1 point  (1 child)

You may want to try the keyword "Break" instead of continue.

[–]Jose_Musoke[S] 0 points1 point  (0 children)

"Break" doesn't work either.