55502f40dc8b7c769880b10874abc9d0

I'm learning python and I was thinking that there has to be a better way to do this, right?

def __init__(self, month, day, year):
        if type(month) != int:
            raise NotIntegerError, "month must be an integer"
        if type(day) != int:
            raise NotIntegerError, "day must be an integer"
        if type(year) != int:
            raise NotIntegerError, "year must be an integer"
        if not (0 < month < 13):
            raise OutOfRangeError, "month out of range (must be 1..12)"
        if not (0 < day < 32):
            raise OutOfRangeError, "day out of range (must be 1..31)"
        if (year < 0):
            raise OutOfRangeError, "year out of range (must be > 0)"
        self.month = month
        self.day = day
        self.year = year

Refactorings

No refactoring yet !

D41d8cd98f00b204e9800998ecf8427e

bob

April 3, 2010, April 03, 2010 08:54, permalink

1 rating. Login to rate!

one thing you could do is use assertions (but it isn't all that much simpler):

def __init__(self, month, day, year):
        assert type(month) is int, "month must be an integer"
        assert type(day) is int, "day must be an integer"
        assert type(year) is int, "year must be an integer"
        assert 0 < month < 13, "month out of range (must be 1..12)"
        assert 0 < day < 32, "day out of range (must be 1..31)"
        assert year >= 0, "year out of range (must be > 0)"
        self.month = month
        self.day = day
        self.year = year
D41d8cd98f00b204e9800998ecf8427e

vanhellion

April 12, 2010, April 12, 2010 12:54, permalink

1 rating. Login to rate!

Simpler to just use lists, I imagine.

class X:
    self.valid_months = range(12)
    self.valid_days = range(1, 32)
    def __init__(self, month, day, year):
        assert month in self.valid_months, 'month must be one of %s' % self.valid_months
        assert day in self.valid_days, 'day must be one of %s' % self.valid_days

        self.month = month
D41d8cd98f00b204e9800998ecf8427e

vanhellion

April 12, 2010, April 12, 2010 12:57, permalink

No rating. Login to rate!

Accidently hit submit

# Continuation of above
        self.day = day
        assert year >= 0, 'year must be an integer 0 or greater'
        self.year = year
D41d8cd98f00b204e9800998ecf8427e

Python Wackjob

April 16, 2010, April 16, 2010 19:28, permalink

1 rating. Login to rate!

In general, it is considered unpythonic to assert the type of an object. We typically are more concerned with the interface exposed to us by some object, rather than the class(es) that the object may or may not be inherited from. This paradigm is known as duck typing. That is "if it looks like a duck, and sounds like a duck, it must be a duck." Put another way, if some object acts like an integer, and sounds like an integer, it must be an integer. Does the underlying implementation of the object really matter, as long as the end result is the same? I would say that although checking to see if the variables are bounded is perfectly acceptable (e.g. years is between 1 - 12, or 0 - 11), asserting their type is (99% of the time) not. Instead, consider what operations are requisite for your class to work correctly, and assert that those objects provide the correct interface.

D98546582072c50ff1970a49f4862132

Sam

November 26, 2010, November 26, 2010 21:29, permalink

No rating. Login to rate!

The datetime module does all of this for you, why reinvent it?

import datetime

    def __init__(self, month, day, year):
        the_date = datetime.datetime(month=month, day=day, year=year)
        self.month = the_date.month
        self.day = the_date.day
        self.year = the_date.year

        # Or you could just assign the "the_date" object to the object instead.

Your refactoring





Format Copy from initial code

or Cancel