Re: [Tutor] question about object oriented programming and inheritance using datetime module

2007-01-16 Thread Kent Johnson
Terry Carroll wrote:
> An example is if you wanted to create a "birthdate" class, which was just 
> like a regular date, but also included the birthstone that corresponded to 
> the date.  We could create a "birthdate" module that included a 
> "Birthdate" class:
> 
> ###
> 
> import datetime
> 
> class Birthdate(datetime.date):
> 
> def __init__(self, year, month, day):
> stones = ["Garnet", "Amethyst", "Aquamarine",
>   "Diamond", "Emerald", "Perl",
>   "Ruby", "Python", "Sapphire",
>   "Opal", "Topaz", "Turquoise"]
> self.birthstone = stones[month-1]

I think you are missing the line
   datetime.date.__init__(self, year, month, day)

somewhere in here.

I am very surprised that this works, my understanding was that 
datetime.date was immutable and required overriding __new__() rather 
than __init__(). But it does work...

Kent

___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] question about object oriented programming and inheritance using datetime module

2007-01-16 Thread Terry Carroll
On Mon, 15 Jan 2007, Kent Johnson wrote:

> [EMAIL PROTECTED] wrote:
> 
> > My class inherits from the date class, but I 
> > have to type 'from datetime import date' before I can initialize the 
> > class definition.  Is there some way to avoid this ? 
> 
> No, and really there is no reason to want to avoid this. You have to 
> import any external module that you want to use directly. Imports are 
> very common in Python code and there is no reason not to use them.

I had a similar issue when I started Python, so I think I know what tpc
may be after.

My thought was that I did not want to do the import if the class was not 
actually going to be used.

I was really thinking about it the wrong way, though.  Really, I would not 
want to do the import unless the class was going to be *defined* for use.  
The right approach here is to put the class into a module, and the import 
statement into the new module as well.

Then, a program that needs to use the class imports the module; and that 
module, only if it is imported, imports the classes on which it depends.

In this case, tpc's class might be defined in a MyDateStuff.py module,
which contains:




import datetime

class age_calculator(datetime.date):
   etc.



Then, when he imports MyDateStuff, it imports datetime and defines 
age_calculator.

I second Kent's concerns over this, though.  It sounds like age_calculator
is really a method that uses datetime.date; not a subclass of
datetime.date.

The question you should ask is: will an age_calculator object actually 
also be a date object?  If so, subclassing makes sense.  Otherwise, think 
of using a method.

Put another way, you should think of a statement like 

   class age_calculator(datetime.date):

as meaning "define a new class named age_calculator; an age_calculator
object is a type of date object."

An example is if you wanted to create a "birthdate" class, which was just 
like a regular date, but also included the birthstone that corresponded to 
the date.  We could create a "birthdate" module that included a 
"Birthdate" class:

###

import datetime

class Birthdate(datetime.date):

def __init__(self, year, month, day):
stones = ["Garnet", "Amethyst", "Aquamarine",
  "Diamond", "Emerald", "Perl",
  "Ruby", "Python", "Sapphire",
  "Opal", "Topaz", "Turquoise"]
self.birthstone = stones[month-1]

###

We could create a Birthdate object like this:

>>> import birthdate
>>> z = birthdate.Birthdate(1971, 7, 12)

Note, it has the birthstone for July:

>>> z.birthstone
'Ruby'

It also has inherited the other attributes and methods of the standard
datetime.date class on which it was based:

>>> z.isoformat()
'1971-07-12'

Because a birthdate is after all, just a particular kind of date; and the 
Birthdate class is just a particular kind of date class.

But in your case, with a name like "age_calculator", it doesn't sound like 
an "age_calculator" is a kind of date.  It sounds like a thing that 
calculates ages.

___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] question about object oriented programming and inheritance using datetime module

2007-01-15 Thread Kent Johnson
[EMAIL PROTECTED] wrote:
> hey guys, I've been experimenting with Python's datetime module, and I 
> created a function that, given a person's birthdate, calculates how old 
> that person is.  Now I want to create a class called age_calculator that 
> does much the same thing.  

Why? You have a perfectly good function that does what you want, there 
is no need to turn it into a class. One of the strengths of Python is 
that not everything needs to be a class.

> My class inherits from the date class, but I 
> have to type 'from datetime import date' before I can initialize the 
> class definition.  Is there some way to avoid this ? 

No, and really there is no reason to want to avoid this. You have to 
import any external module that you want to use directly. Imports are 
very common in Python code and there is no reason not to use them.

Inheriting from date isn't a very good idea. You should inherit from 
date if your class will be a specialized kind of date. I guess you could 
think of your class as adding an age() method to date, but you are 
thinking of it as a calculator. Also date objects are immutable which 
makes it harder to create a subclass of date. (You have to override 
__new__() rather than __init__(), but explaining that will probably just 
confuse you at this point.)

There are a few things in your code that are a bit confused - you need 
to call the base class __init__() in your __init__() method, and 
__init__() does not return a value. You should probably read up a bit 
more on classes in Python, either a book or one of the on-line tutorials.

> 
> Also, once I type the import statement and initialize my class 
> definition, I can create an instance of age_calculator.  The instance of 
> age_calculator stores the given birthdate, and gives me a infinite loop 
> traceback when I call self.today().  If I don't inherit from date, I 
> would need to put the import statement somewhere inside a method, and I 
> don't recall ever seeing that done.

It is OK to put an import inside a function or method, but why do you 
think you need to do this?

>  Part of me feels like that's not as 
> elegant as defining an age_calculator class that inherits from 
> datetime.date, but I'm not sure how to do this.  For what it's worth, 
> here's my pseudocode (that inherits from date module) and working code 
> (that does not inherit from date module):
> 
> from datetime import date
> 
> class age_calculator(date):
> def __init__(self, year, month, day):
> time_delta = self.today() - self
> number_of_years = time_delta.days / 365
> return number_of_years

I'm not sure why this gives an infinite loop (not even sure what an 
"infinite loop traceback" is), but you have not initialized the base 
class so the year, month, day parameters are not used at all.

> 
> class age_calculator:
> def __init__(self, year, month, day):
> self.year = year
> self.month = month
> self.day = day
> 
> def calculate_age(self):
> from datetime import date
> birth_date = date( self.year, self.month, self.day)
> date_today = date.today()
> time_delta = date_today - birth_date
> number_of_years = time_delta.days / 365
> return number_of_years

This is better, but compare it to your functional version and you should 
see why the function is preferred.

Kent

> 
> age_calculator(1964, 9, 27).calculate_age()
> 42
> 
> 
> 
> 
> ___
> Tutor maillist  -  Tutor@python.org
> http://mail.python.org/mailman/listinfo/tutor


___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] question about object oriented programming and inheritance using datetime module

2007-01-15 Thread Luke Paireepinart
[EMAIL PROTECTED] wrote:
> hey guys, I've been experimenting with Python's datetime module, and I 
> created a function that, given a person's birthdate, calculates how 
> old that person is.  Now I want to create a class called 
> age_calculator that does much the same thing.  My class inherits from 
> the date class, but I have to type 'from datetime import date' before 
> I can initialize the class definition.  Is there some way to avoid 
> this ? 
No.
In order to use class inheritance syntax,
class some_class(some_object):

some_object must be defined.
Otherwise you'll get a variable not defined error.
You could make your own class called 'date' and inherit from that,
but what would be the point of that?
>
> Also, once I type the import statement and initialize my class 
> definition, I can create an instance of age_calculator.  The instance 
> of age_calculator stores the given birthdate, and gives me a infinite 
> loop traceback when I call self.today().  If I don't inherit from 
> date, I would need to put the import statement somewhere inside a 
> method, and I don't recall ever seeing that done.
What makes you think you'd have to import within a method?
Import datetime.date into the global namespace.
That's perfectly alright.
Especially since your class depends on it being available.
>   Part of me feels like that's not as elegant as defining an 
> age_calculator class that inherits from datetime.date, but I'm not 
> sure how to do this.  For what it's worth, here's my pseudocode (that 
> inherits from date module) and working code (that does not inherit 
> from date module):
The way you'd go about doing this is to make an extra function that is 
unique to your inherited class (for example, calculate_age).
>
> from datetime import date
>
> class age_calculator(date):
> def __init__(self, year, month, day):
> time_delta = self.today() - self
> number_of_years = time_delta.days / 365
> return number_of_years
This init method is overriding the init of the inherited date class.
The reason today() doesn't work is probably because of this.
>
> class age_calculator:
> def __init__(self, year, month, day):
> self.year = year
> self.month = month
> self.day = day
>
> def calculate_age(self):
> from datetime import date
> birth_date = date( self.year, self.month, self.day)
> date_today = date.today()
> time_delta = date_today - birth_date
> number_of_years = time_delta.days / 365
> return number_of_years
>
Just move the import outside of the class.
from datetime import date
class age_calculator:
def __init__(self, year, month, day):
self.year = year
self.month = month
self.day = day

def calculate_age(self):
birth_date = date( self.year, self.month, self.day)
date_today = date.today()
time_delta = date_today - birth_date
number_of_years = time_delta.days / 365
return number_of_years

I don't think you really want to inherit from date.
HTH,
-Luke
___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


[Tutor] question about object oriented programming and inheritance using datetime module

2007-01-15 Thread tpc

hey guys, I've been experimenting with Python's datetime module, and I
created a function that, given a person's birthdate, calculates how old that
person is.  Now I want to create a class called age_calculator that does
much the same thing.  My class inherits from the date class, but I have to
type 'from datetime import date' before I can initialize the class
definition.  Is there some way to avoid this ?

Also, once I type the import statement and initialize my class definition, I
can create an instance of age_calculator.  The instance of age_calculator
stores the given birthdate, and gives me a infinite loop traceback when I
call self.today().  If I don't inherit from date, I would need to put the
import statement somewhere inside a method, and I don't recall ever seeing
that done.  Part of me feels like that's not as elegant as defining an
age_calculator class that inherits from datetime.date, but I'm not sure how
to do this.  For what it's worth, here's my pseudocode (that inherits from
date module) and working code (that does not inherit from date module):

from datetime import date

class age_calculator(date):
   def __init__(self, year, month, day):
   time_delta = self.today() - self
   number_of_years = time_delta.days / 365
   return number_of_years

class age_calculator:
   def __init__(self, year, month, day):
   self.year = year
   self.month = month
   self.day = day

   def calculate_age(self):
   from datetime import date
   birth_date = date(self.year, self.month, self.day)
   date_today = date.today()
   time_delta = date_today - birth_date
   number_of_years = time_delta.days / 365
   return number_of_years

age_calculator(1964, 9, 27).calculate_age()
42
___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor