1

Very noob to python and programming overall. Why does this code:

def daysBetweenDates(year1, month1, day1, year2, month2, day2):
    years = [year1, year2]
    def leapyr(n):
        if n % 400 == 0:
            return True
        elif n % 100 == 0:
            return False
        elif n % 4 == 0:
            return True
        else:
            return False

    for i, year in enumerate(years):
        if leapyr(year):
            years[i] = year * 366
            print 'l:', years, year1, year2
        else:
            years[i] = year * 365
            print 'n:', years, year1, year2

daysBetweenDates(1,1,1,4,2,1)

Change year1 and year2 in years[ ], but does not change year1 and year2?

n: [365, 4] 1 4
l: [365, 1464] 1 4

edit: working code

def daysBetweenDates(year1, month1, day1, year2, month2, day2):
    years = [year1, year2]
    def leapyr(n):
        if n % 400 == 0:
            return True
        elif n % 100 == 0:
            return False
        elif n % 4 == 0:
            return True
        else:
            return False

    for i, year in enumerate(years):
        if leapyr(year):
            years[i] = year * 366
            year1 = years[0]
            year2 = years[1]
            print 'l:', years, year1, year2
        else:
            years[i] = year * 365
            year1 = years[0]
            year2 = years[1]
            print 'n:', years, year1, year2

daysBetweenDates(1,1,1,400,2,1)

Now gives correct answer:

n: [365, 400] 365 400
l: [365, 146400] 365 146400

Your post looks like too much code, here put some more text here. Text is important.

user2144553
  • 105
  • 2
  • 7

2 Answers2

0

Years is a list and the values inside are copied by reference if it is a mutable object (i.e. a dict, list, etc) or by value if the variable is not mutable (int, string, tuple, etc). so when you modify an int value in a list, it doesn't reflect on the int variables used to build it.

drekyn
  • 438
  • 2
  • 7
  • Nothing to do with primitive types; it's mutable versus immutable that is the distiction. A tuple is not a 'primitive' type, is it? What about the `complex` number type? It is immutable but has components. – Martijn Pieters Mar 07 '13 at 14:17
  • Right, I'll modify that bit. – drekyn Mar 07 '13 at 14:35
0

The variable year1 and year2 are getting passed by value when you create the list years. Hence when you then modify it in:

years[i] = year * 365

you're just changing the value in the list and not the variable it was created from.

This SO question has good information on how arguments are passed in Python: How do I pass a variable by reference?

From my skim of this it seems like you might need to pass the dates to your daysBetweenDates function as an object rather than primitive ints.

Community
  • 1
  • 1
Choc13
  • 796
  • 7
  • 23
  • Trying to second guess what you're doing from the method name here, but could you not define another method called calculateDays(year, month, day) in which you would just perform the math on the arguments to convert it to days. Then you would just need to call this twice from within daysBetweenDates? From what I can see you only need to list to do your loop over 2 years. – Choc13 Mar 07 '13 at 14:27
  • But how the values are passed to the function are not at issue here. It's the OP's expectation on how local variables act that is the problem. – Martijn Pieters Mar 07 '13 at 14:36
  • I agree that his primary goal should be to learn about the way Python passes arguments around, but I was just trying to offer some help with a way to solve the problem that wouldn't result in having to remember to update the argument every time an operation was made on the copy. – Choc13 Mar 07 '13 at 14:52
  • >Trying to second guess what you're doing from the method name here If you are curios, then here is the exercise: https://www.udacity.com/course/viewer#!/c-cs101/l-48689154/m-48749054 I decided to solve it using enumerate (and got stuck) even though lesson wants us to use knowledge we have aquired from previous lessons. – user2144553 Mar 07 '13 at 14:55