[Tutor] generating independent random numbers

Dave Angel davea at ieee.org
Tue Sep 28 04:21:41 CEST 2010



On 2:59 PM, Steven D'Aprano wrote:
> On Tue, 28 Sep 2010 08:55:36 am Carter Danforth wrote:
>
>> class Date:
>>      c = random.randint(16,30)
>>      y = random.randint(0,99)
>>      month = random.randint(1,12)
> Here's your problem: you are creating a class where all the attributes
> (called "members" in some other languages) belong to the class and are
> shared by all instances.
>
> Python classes are themselves objects, and the code inside the class
> body gets executed *once*, when the class is created. So in this case,
> the Date class chooses a single random month, *once*, and all instances
> share this attribute Date.month.
>
> To get the behaviour you are after, you need to use instance attributes,
> which means referring to self. The usual place to do this is in the
> __init__ method, which is called when the instance is being
> initialised:
>
> class Date:
>      def __init__(self):
>          self.month = random.randint(1,12)
>          # etc.
>
>
>
> By the way, why do you calculate a century and year separately, then add
> c+y to get the year? It would be easier to just say:
>
> year = random.randint(1600, 3099)
>
>
>
That's the big problem, although it's also worth pointing out that 
you'll need a new instance each time through the loop.  It's not enough 
to call Date(), you also have to bind it to a name, and use that name 
for attribute lookup.    So something like
     mydate = Date()
     year = mydate.y + ....

But there are at least a few subtle problems left.  One is that many of 
the years are divisible by four but do not have 29 days in February.  
For example, 1800, 1900, 2100 are not leap years.

Next problem is that the dates are not evenly distributed over the 
entire range of years.  The 14th of February will be more likely to be 
chosen than the sixth of July.  You can decide that this is deliberate, 
but it is a consideration.

Third, the program doesn't do anything to check the user's answer.  For 
that matter, there's no timing going on either.

Depending on the learning goals of this project, I'd consider using the 
datetime module, and method:

mydate = date.fromordinal(/ordinal/)

Now you can make a single randint() call, once you precalculate the 
starting and ending dates desired.   And this module also gives you 
other things you need, such as the weekday() method.

DaveA

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20100927/db9177ef/attachment-0001.html>


More information about the Tutor mailing list