1

Getting syntax error for the following line trying to use assert to test.

#test is_valid_date for April 4, 2014 and Januarary 3, 2012
print assert(is_valid_date(2014,4,4))
print assert(is_valid_date(2012,1,3))

Shouldn't the assert return true for the above if the function is_valid_date returns true?

Here is the actual is_valid_date implementation.

def is_valid_date(year, month, day):
    """
    Inputs:
      year  - an integer representing the year
      month - an integer representing the month
      day   - an integer representing the day

    Returns:
      True if year-month-day is a valid date and
      False otherwise
    """
    if year > datetime.MINYEAR and year < datetime.MAXYEAR:
        if month >= 1 and month <= 12:
            d = days_in_month(year, month)
            if day >= 1 and day <= d:
                return True

    return False
user2357112
  • 260,549
  • 28
  • 431
  • 505
charlie
  • 187
  • 4
  • 15

2 Answers2

2

assert is not a function, it's a statement, and as such cannot be used inside the expression for print.

What you probably want to do is this:

is_valid = is_valid_date(2014, 4, 4)
print is_valid
assert is_valid

That is, first execute the print statement, then execute the assert statement (although, for a function returning only True or False there's no much benefit in printing the return value before the assertion).

If you find yourself writing code like that often, you can consider writing your own utility function:

def verbose_assert(value):
    print value
    assert value
verbose_assert(is_valid_date(2014, 4, 4))

Or even like this:

def assert_is_valid_date(*args):
    is_valid = is_valid_date(*args)
    print is_valid
    assert is_valid
assert_is_valid_date(2014, 4, 4)
Andrea Corbellini
  • 17,339
  • 3
  • 53
  • 69
1

What do you expect assert to return and why would you want to print that value? Your usage is just not very idiomatic. Take out the print and add a description of the thing you are testing to the assert as its second argument.

assert is_valid_date(2014,4,4), "2014,4,4 is a valid date tuple"
assert is_valid_date(2012,1,3), "2012,1,3 is a valid date tuple"

Tangentially, maybe you want to refactor your function to avoid the arrow antipattern

def is_valid_date(year, month, day):
    """
    Inputs:
      year  - an integer representing the year
      month - an integer representing the month
      day   - an integer representing the day

    Returns:
      True if year-month-day is a valid date and
      False otherwise
    """
    if year <= datetime.MINYEAR:
        return False
    if year >= datetime.MAXYEAR:
        return False
    if month < 1:
        return False
    if month > 12:
        return False
    if day < 1:
        return False
    if day > days_in_month(year, month):
        return False    
    return True

This is perhaps overdoing it, but you'll notice how adding new conditions is now easy, and adding debug prints to see exactly where the code is rejecting an input is now very straightforward.

tripleee
  • 175,061
  • 34
  • 275
  • 318
  • Thanks tripleee. I edited the above. Is the assert statement supposed to return something to stdout? – charlie Jan 09 '18 at 09:31
  • It prints something, though certainly emphatically *not* to standard output, if the assertion fails. You want diagnostics on stderr, not stdout. – tripleee Jan 09 '18 at 09:32