Search code examples
pythonpython-datetime

python-datetime outputting -1 day instead of desired output


So, my goal is to change this output from datetime:

time left: -1 day, 23:57:28

To this:

time left: 0:00:30

Now, this needs to be dynamic, as the code is supposed to be changed in the dictionary. I'm trying to figure out why it is outputting with

-1 day, 23:57:28

I've tried moving where it executes and even changing some other code. I just don't understand why it's showing with -1 day. It seems likes it is executing one too many times

Also, a side note, the purpose of this program is to figure out how many songs can fit into a playlist given a time restraint. I can't seem to figure out the right if statement for it to work. Could someone also help with this?

This is the current output of the program:

0:02:34
0:06:30
Reached limit of 0:07:00
time left: -1 day, 23:57:28

See code below:

import datetime

#durations and names of songs are inputted here
timeDict = {
    'Song1' : '2:34',
    'Song2' : '3:56',
    'Song3' : '3:02'
}


def timeAdder():

   #assigns sum to the datetime library's timedelta class
    sum = datetime.timedelta()

    #sets the limit, can be whatever
    limit = '0:07:00'

    #calculates the sum
    for i in timeDict.values():
         (m, s) = i.split(':')
         d = datetime.timedelta(minutes=int(m), seconds=int(s))
         sum += d

       #checks whether the limit has been reached
         while str(sum)<limit:
             print(sum)
             break

        
         
         
         #commits the big STOP when limit is reached
         if str(sum)>limit:
            print("Reached limit of " + limit)
            break

    #timeLeft variable created as well as datetime object conversion to a string       
    x = '%H:%M:%S'
    timeLeft = datetime.datetime.strptime(limit, x) - datetime.datetime.strptime(str(sum), x)

    for i in timeDict:
        if timeDict[i] <= str(timeLeft): 
            print("You can fit " + i + " into your playlist.")
    print("time left: " + str(timeLeft))
            

def main():
    timeAdder()
    
main()

Any help with this would be appreciated.


Solution

  • It seems likes it is executing one too many times

    Bingo. The problem is here:

    sum += d
    
    ...
    
    #commits the big STOP when limit is reached
    if str(sum)>limit:
      print("Reached limit of " + limit)
      break
    

    You are adding to your sum right away, and then checking whether it has passed the limit. Instead, you need to check whether adding to the sum will pass the limit before you actually add it.

    Two other things: first, sum is a Python keyword, so you don't want to use it as a variable name. And second, you never want to compare data as strings, you will get weird behavior. Like:

    >>> "0:07:30" > "2:34"
    False
    

    So all of your times should be timedelta objects.

    Here is new code:

    def timeAdder():
       #assigns sum to the datetime library's timedelta class
        sum_ = datetime.timedelta()
    
        #sets the limit, can be whatever
        limit = '0:07:00'
        (h, m, s) = (int(i) for i in limit.split(":"))
        limitDelta = datetime.timedelta(hours=h, minutes=m, seconds=s)
    
        #calculates the sum
        for i in timeDict.values():
             (m, s) = i.split(':')
             d = datetime.timedelta(minutes=int(m), seconds=int(s))
    
             if (sum_ + d) > limitDelta:
                print("Reached limit of " + limit)
                break
             
             # else, loop continues
             sum_ += d
             print(sum_)
         
        timeLeft = limitDelta - sum_
    
        for songName, songLength in timeDict.items():
            (m, s) = (int(i) for i in songLength.split(':'))
            d = datetime.timedelta(minutes=m, seconds=s)
            if d < timeLeft: 
                print("You can fit " + songName + " into your playlist.")
        print("time left: " + str(timeLeft))
    

    Demo