2

I was asked, as an exercise, to build a class in python, named "Date". I have to build few functions according to the requirements. The first one is an "init" model that takes a day, month, year, hours, and minutes and returns a valid Date object(when valid means that a month, for instance, can't be 13.) The next is a function that raises a specific error if some Data is invalid, like 13 as a month. My problem is that Whenever I call "Date(23,14,1998).month", it returns "13" instead of an error. I am also not sure how a valid Date object is created. I could use your help. My code:

class Date:
    days_per_month = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]

def __init__(self, day, month, year, hours=0, minutes=0):
        self.day=day
        self.month=month
        self.year=year
        self.hours=hours
        self.minutes=minutes

    def validate(self):
        if type(self.month)==int:
            if self.month<1:
                raise ValueError('Error: month value must be positive')
            if self.month>12:
                raise ValueError('Error: month value cannot exceed 12')
        else:
            raise ValueError('Error: month value must be an integer')
        if type(self.day)==int:
            if self.day>days_in_month(self):
                raise ValueError('Error: maximum days in this month exceeded')
            elif self.day<1:
                raise ValueError('Error: day value must be positive')
        else:
            raise ValueError('Error: day value must be an integer')
        if type(self.hours)==int:
            if self.month>23:
                raise ValueError('Error: hours value cannot exceed 23')
            elif self.month<0:
                raise ValueError('Error: hours value cannot be negative')
        else:
            raise ValueError('Error: hours value must be an integer')
        if type(self.minutes)==int:
            if self.month>59:
                raise ValueError('Error: minutes value cannot exceed 59')
            elif self.month<0:
                raise ValueError('Error: minutes value cannot be negative')
        else:
            raise ValueError('Error: minutes value must be an integer')

    def days_in_month(self):
        if self.month == 2 and self.is_leap_year():
               return 29
        return self.days_per_month[self.month-1]

    def is_leap_year(self):
        if self.year % 400 == 0:
            return True
        elif self.year % 100 == 0:
            return False
        elif self.year % 4 == 0:
            return True
        else:
            return False
3
  • 1
    Is it just the formatting displayed here, or is your def __init__() really not indented? Commented May 14, 2015 at 19:57
  • 2
    All ifs after the type check are month instead of the correct type. (self.month instead of self.minutes, for example). Classic copy and paste error. Commented May 14, 2015 at 19:59
  • Your validate is never used the way you want it to be used. Commented May 14, 2015 at 20:02

4 Answers 4

4

You should call your validate method, ideally at constructor time (i.e. in your __init__ method). This will ensure that your error checking is done before anyone gets to use the Date object.

Sign up to request clarification or add additional context in comments.

4 Comments

I tried to do something like that, but Validate itself relies on _init_() and therefore cannot be used, isn't that so?
@Meitar, check my comment. This recommendation is valid, but there is an error on the code.
You need to fix your indentation first, it's 100% necessary in Python.
Oh I see, the way it runs.
3

Consider calling self.validate() in __init__ after assigning the variable.

Comments

2

Two things: first, there are some errors on the code. You must indent correctly your init method. Second, you copy and pasted the portions above and put month in several places where it should be minute, for example:

if type(self.hours)==int:
        if self.month>23: ## Should be HOURS
            raise ValueError('Error: hours value cannot exceed 23')
        elif self.month<0: ## should be hours
            raise ValueError('Error: hours value cannot be negative')
    else:
        raise ValueError('Error: hours value must be an integer')
    if type(self.minutes)==int:
        if self.month>59: ## Should be MINUTES
            raise ValueError('Error: minutes value cannot exceed 59')
        elif self.month<0: ## Should be MINUTES
            raise ValueError('Error: minutes value cannot be negative')
    else:
        raise ValueError('Error: minutes value must be an integer')

Check the rest of the code. Also, you should call the validate function by the end of the init method:

class Date:
days_per_month = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]

    def __init__(self, day, month, year, hours=0, minutes=0):
        self.day=day
        self.month=month
        self.year=year
        self.hours=hours
        self.minutes=minutes  
        self.validate()

Comments

2

It looks like in your __init__ you can do:

class Date:
    days_per_month = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]

    def __init__(self, day, month, year, hours=0, minutes=0):
        self.day=day
        self.month=month
        self.year=year
        self.hours=hours
        self.minutes=minutes
        self.validate()

Also note an error in validate() line if self.day>days_in_month(self): should be if self.day>self.days_in_month():

I ran your code with these two changes and it works and catches obvious errors, though you'll probably want to do more testing.

2 Comments

But now if I ask for "days" for example, it executes the months error. Is that correctable?
Can you comment a specific example. If I do print Date(31,4,1998).day (which is wrong because April goes to 30) I get ValueError: Error: maximum days in this month exceeded

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.