I'm trying to write a little budget program in python. This is my first program I'm writing to learn python. The first step is to calculate how many days until either the 1st or 15th (paydays) depending on today's date. Can someone help me out a little?

As they say below, datetime is the way to proceed, but that has got to be one of the hairier modules to cut your teeth on. It isn't complex because it is poorly written, it's just that the Gregorian Calendar and a spherical earth have a lot of attributes.
–
mswApr 30 '10 at 6:08

Interesting question, and here's a complete solution. I'll start with my function definition, I've put this in a file named payday.py:

def nexypayday(fromdate=None):
"""
@param fromdate: An instance of datetime.date that is the day to go from. If
not specified, todays date is used.
@return: The first payday on or after the date specified.
"""

Next we need some tests. This is to clearly define the behaviour of our method. Because you're new to python, I'm going to go all out and give you an example of using unittests.

This is a runnable python module. You can go ahead and name that test_payday.py and run it with python test_payday.py. This should immediately fail with various error messages because we've not got the right code written yet.

After some fiddling with how datetime.date works, I've worked out: mydatetime.day is the day of the month, mydatetime + datetime.timedelta(days=1) will create a new datetime one day on in the year. Thus I can throw together this in payday.py.

import datetime
def nextpayday(fromdate=None):
"""
@param fromdate: An instance of datetime.date that is the day to go from. If
not specified, todays date is used.
@return: The first payday on or after the date specified.
"""
if fromdate is None:
fromdate = datetime.date.today()
# while the day of the month isn't 1 or 15, increase the day by 1
while fromdate.day not in (1, 15):
fromdate = fromdate + datetime.timedelta(days=1)
return fromdate

Run the unit tests and it should be all golden. Note that in my tests I've made it that if I check what the 'next' payday is from a payday, it returns its own day. Changing that to returning the 'next' payday is left as an exercise for the reader.

+1 for the full explanation and unit tests. However, the actual solution could be more elegant - this is a bit of a brute force method. Also, the OP wants the count of days from today, not the actual pay date (trivial to add, of course).
–
EMPApr 30 '10 at 6:56

and it's not runnable ... 1s/nexy/next/
–
John MachinApr 30 '10 at 7:30

1

If the answer's wrong. Edit it. There are tests, just make sure they pass. :)
–
JerubMay 11 '10 at 5:11

Another method would be to find both and return the shorter one
–
Carson MyersApr 30 '10 at 4:56

@Carson Myers, explicit is better. You need to find the shorter AND positive one, otherwise. Specifically, find tdelta with 15th of the current month, if positive, great and all done; else, return the tdelta with next month's first day.
–
DingleApr 30 '10 at 19:39

yes, you're right, I was thinking along the lines of "find the next 1 and the next 15, and return the closer one", but I guess you can't just find the next 15, you would have to check within certain months.
–
Carson MyersApr 30 '10 at 20:45

I don't want to entirely spoil your learning experience by just typing the answer, but the Python library makes this quite easy. Have a look at the datetime module, particularly the date and timedelta classes.