#1
  1. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Dec 2012
    Posts
    39
    Rep Power
    2

    Days between dates using "YYYY,MM,DD" as the format and no datetime


    Hello!

    I have a question. How does one find the days between two dates without using the datetime module?

    I have been working on some code and I have gotten this so far to determine if each year in between each date is a leap year or not BUT, it seems very slow.

    Code:
    def isLeapYear(a):
        if a % 400 == 0:
            return True
        elif a % 100 == 0:
            return False
        elif a % 4 == 0:
            return True
        else:
            return False
        
    def yearDifference(year1, year2):
        leap_count = 0
        begin_year = year1
        end_year = year2
        while begin_year <= end_year:
            test_leap = isLeapYear(begin_year)
            begin_year += 1
            if test_leap == True:
                leap_count += 1
        year_diff = (year2 - year1) * 365 + leap_count
        return year_diff
    
    def daysBetweenDates(year1, month1, day1, year2, month2, day2):
    There is the code I have so far. I still don't know what I should do when it comes to the months and days. I feel like the days and months in the first year should be subtracted, and the days and months in the second year should be added.

    Any help would be awesome!!! Thank you!

    This is also from the Udacity site the course of intro to computer programming.
  2. #2
  3. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    May 2009
    Posts
    474
    Rep Power
    33
    For starters, make sure year 2 > year1 before passing them to the function. yearDifference(year1, year2) should be passed year1+1 and year2-1 since year1 and year2 are not complete years almost all of the time. To calculate the days per month use a list.
    Code:
    days_per_month = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
    if is_leap_year(year1):
        days_per_month[1] = 29
    
    month1 = 6
    day1 = 5
    month_days = 0
    ## will not count the sixth month (month1) since it is not complete
    for ctr in range(month1):  ## and/or range(month1+1, 13)
        month_days += days_per_month[ctr]
    print "%d days since the beginning of the year" % (month_days+day1)
    Finally take a look at the Python Style Guide. Caps are only used in class names, not in function names. It makes other's code easier to read and understand.
    Last edited by dwblas; May 18th, 2013 at 12:46 AM.
  4. #3
  5. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Dec 2012
    Posts
    39
    Rep Power
    2
    Thank you for your reply
  6. #4
  7. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Dec 2012
    Posts
    39
    Rep Power
    2
    Ok so I wrote some code that was accepted! Here is it:

    Code:
    def isLeapYear(year1, year2):
        year_1 = year1
        year_2 = year2
        non_leap_years = []
        leap_years = []
        while year_1 <= year_2:
            non_leap_years.append(year_1)
            year_1 += 1
        for i in non_leap_years:
            if i % 4 == 0 or i % 400 == 0:
                leap_years.append(i)
                non_leap_years.remove(i)
                if i % 100 == 0:
                    leap_years.remove(i)
                    non_leap_years.append(i)
        year_days = len(non_leap_years) * 365 + len(leap_years) * 366
        return year_days, leap_years, non_leap_years
    
    def daysBetweenDates(year1, month1, day1, year2, month2, day2):
        year_days, leap_years, non_leap_years = isLeapYear(year1, year2)
        days_of_months = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
        if year1 in leap_years:
            days_of_months[1] = 29
        elif leap_years == None:
            days_of_months[1] = 28
        front_subtract = sum(days_of_months[:month1 - 1]) + day1
        if year2 in leap_years:
            days_of_months[1] = 29
        elif leap_years == None:
            days_of_months[1] = 28
        back_subtract = sum(days_of_months[month2 - 1:]) - day2
        days_between = year_days - front_subtract - back_subtract
        return days_between
    Thank you for your help!

    I wonder if anyone could show me a way to write this much smaller and more efficient then it is (assuming it ever was effiecient!!!)? Thanks!!!
  8. #5
  9. Contributing User
    Devshed Demi-God (4500 - 4999 posts)

    Join Date
    Aug 2011
    Posts
    4,837
    Rep Power
    480

    OK, I'll play.


    1: Your program gives incorrect result, off by 1, for
    Code:
    print(daysBetweenDates(1871, 10, 18, # Charles Babbage
               2004, 10, 19, # Ken Iverson
               ))
    2: As you modified your functions you didn't change their names. Consequently you have functions which don't do what the names imply.

    3: I had planned to time the programs. I don't know which is faster, I inserted a function call. Of course, I removed a list deletion. Anyway, I don't bother timing incorrect programs.

    4: My code is 6 lines longer than yours, but then again, 29 lines of my code are explanation and tests.

    Code:
    '''
        >>> print('Command "python -m doctest q.py" to run doctests.')
        Command "python -m doctest q.py" to run doctests.
    '''
    
    def isLeapYear(year):
        '''
            Return True iff the year is a leap year.
    
            >>> [isLeapYear(year) for year in (1,2,3,4,100,200,300,400,)]
            [False, False, False, True, False, False, False, True]
        '''
        return not ((year % 4) or ((year % 100 == 0) and (year % 400)))
    
    def LeapYears(year1, year2):
        '''
            return the number of leap years between the inclusive range year1 and year2
    
            >>> LeapYears(1996, 2000)
            2
        '''
        assert year1 <= year2
        return sum(isLeapYear(year) for year in range(year1, year2+1))
    
    def daysBetweenDates(year1, month1, day1, year2, month2, day2):
        '''
            confirmed with
            http://www.wolframalpha.com/input/?i=days+between+2004-OCT-19+and+1871-OCT-18
    
            >>> daysBetweenDates(
            ...     1871, 10, 18, # Charles Babbage
            ...     2004, 10, 19, # Ken Iverson
            ... )
            ...
            48579
        '''
        assert year1 <= year2
        leap_years = LeapYears(year1, year2)
        days_of_months = [31, None, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
        days_of_months[1] = 28 + isLeapYear(year1)
        front_subtract = sum(days_of_months[:month1 - 1]) + day1
        days_of_months[1] = 28 + isLeapYear(year2)
        back_subtract = sum(days_of_months[month2 - 1:]) - day2
        return 365 * (1 + year2 - year1) + LeapYears(year1, year2) - front_subtract - back_subtract
    Last edited by b49P23TIvg; May 18th, 2013 at 10:07 AM.
    [code]Code tags[/code] are essential for python code and Makefiles!
  10. #6
  11. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Dec 2012
    Posts
    39
    Rep Power
    2
    Yeah with Udactiy the functions have to be named specifically or the code checker will not accept it, so naming the function isLeapYear() was a required name.

    Thank you for the rewrite.
  12. #7
  13. Contributing User
    Devshed Demi-God (4500 - 4999 posts)

    Join Date
    Aug 2011
    Posts
    4,837
    Rep Power
    480
    I agree with your post. You made no false claims about caring that your program doesn't work. No false promises that you'll write a test in the future.
    [code]Code tags[/code] are essential for python code and Makefiles!
  14. #8
  15. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Dec 2012
    Posts
    39
    Rep Power
    2
    I'm sorry if I offended you in anyway. I am still not very knowledgeable when it comes to coding stuff, still just trying to wrap my head around one language

    As far as this code went I had been banging my head against the wall for almost 4 days trying to figure out how to solve it, so when I put it through the checker at Udacity and it said "Correct!" I assumed it was correct! Sadly I guess it wasn't, there is a hole somewhere.

    Finally thank you for re writing that code. I didn't take it or use it or anything, I was just curious to see how much better the code could be.

    I have another snippet of code if you'd like to critique it:

    Code:
    def print_abacus(value):
        aba_list = list(str(value))  
        abacus = "00000*****"
        xtra_aba = range(10 - len(aba_list))
        if value == 0:
            print("|00000*****   |\n" * 10)
                            # |00000*****   |
                            # |00000*****   |
                            # |00000*****   |
                            # |00000*****   |
                            # |00000*****   |
                            # |00000*****   |
                            # |00000*****   |
                            # |00000*****   |
                            # |00000*****   |
    
        else:
            for i in xtra_aba:
                print("|" + abacus + "   |")
            for i in aba_list:
                print("|" + abacus[:-int(i)] + "   " + abacus[-int(i):] + "|")
    
                              # |00000*****   |
                              # |00000*****   |
                              # |00000****   *|
                              # |00000***   **|
                              # |00000**   ***|
                              # |00000*   ****|
                              # |00000   *****|
                              # |0000   0*****|
                              # |000   00*****|
                              # |00   000*****| value:  12345678
  16. #9
  17. Contributing User
    Devshed Demi-God (4500 - 4999 posts)

    Join Date
    Aug 2011
    Posts
    4,837
    Rep Power
    480
    I haven't found the problem, and I don't like the representation of the abacus. An abacus has a solid frame. That's not your fault. I did find someone else's solution. zeros display differently.

    Code:
    $ python [color=red]theirs[/py].py # value = 10203
    |00000*****   |
    |00000*****   |
    |00000*****   |
    |00000*****   |
    |00000*****   |
    |00000****   *|
    |00000*****   |
    |00000***   **|
    |00000*****   |
    |00000**   ***|
    
    
    $ python [color=red]yours[/py].py  # value=10203
    |00000*****   |
    |00000*****   |
    |00000*****   |
    |00000*****   |
    |00000*****   |
    |00000****   *|
    |   00000*****|
    |00000***   **|
    |   00000*****|
    |00000**   ***|
    [code]Code tags[/code] are essential for python code and Makefiles!
  18. #10
  19. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Dec 2012
    Posts
    39
    Rep Power
    2
    I guess my zeros display differently because of the index? Could add another if statement to recognize it maybe. Thank you for catching that. At Udacity it only has a few test cases that need to be passed.

    I try to find other ways to condense the code and fix the zero input.

    Thank you again!

IMN logo majestic logo threadwatch logo seochat tools logo