[Tutor] generating independent random numbers

Carter Danforth carter.danforth at gmail.com
Thu Sep 30 03:17:36 CEST 2010


On Wed, Sep 29, 2010 at 1:53 PM, Dave Angel <davea at ieee.org> wrote:

>  On 9/28/2010 5:11 PM, Carter Danforth wrote:
>
>> Thanks for the replies, Dave and Joel. The reason I'm not just using the
>> time or datetime modules for a random date is because it's restricted to
>> 1970-2038; I'm pulling dates from 1600-3099. Thanks a lot for the pointer
>> about the leap years, Dave, as well the class instances; just updated it
>> and
>> it's all working now, and also included the rest of the code too w/ answer
>> verification and time tracking.
>>
>> I want to start using this program to test myself for speed calculation
>> using Zeller's formula, it's pretty cool for determining the days of dates
>> -
>> http://mathforum.org/dr/math/faq/faq.calendar.html
>>
>> Because of the way variables C and D are split up from the year in the
>> formula, I split up the year for self.c and self.y.
>>
>> ------------------------
>>
>> import random, time, datetime, calendar
>>
>> class Date:
>>     def __init__(self):
>>         self.c = random.randint(16,30)
>>         self.y = random.randint(0,99)
>>         self.month = random.randint(1,12)
>>         self.year = self.c*100 + self.y
>>
>>         apr = [4,6,9,11]
>>         feb = [2]
>>         notleap = [1700, 1800, 1900, 3000]
>>
>>         if self.month in feb:
>>             if self.year%4 == 0:
>>                 if self.year in notleap:
>>                     self.k = random.randint(1,28)
>>                 else:
>>                     self.k = random.randint(1,29)
>>             else:
>>                 self.k = random.randint(1,28)
>>         elif self.month in apr:
>>             self.k = random.randint(1,30)
>>         else:
>>             self.k = random.randint(1,31)
>>
>>         if self.month in [1,2]:
>>             d = self.y - 1
>>             m = self.month + 10
>>         else:
>>             d = self.y
>>             m = self.month - 2
>>
>>         z = self.k + (13*m-1)/5 + d + d/4 + self.c/4 - 2*self.c
>>
>>         if z<  0:
>>             r = (abs(z)/7)*7 + z + 7
>>         else:
>>             r = z%7
>>
>>         dict = { 0: 'Sunday', 1: 'Monday', 2: 'Tuesday', 3: 'Wednesday',
>> 4:
>> 'Thursday', 5: 'Friday', 6: 'Saturday' }
>>         self.day = dict[r]
>>
>> t1m = time.localtime().tm_min
>> t1s = time.localtime().tm_sec
>> t1 = t1m + t1s/100.0
>> n = 0
>> x = 0
>>
>> while n<  10:
>>     newdate = Date()
>>
>>     print '\n',calendar.month_name[newdate.month], newdate.k,',',
>> newdate.year,'=',
>>     answer = raw_input()
>>     if answer.capitalize() == newdate.day:
>>         pass
>>     else:
>>         x += 1
>>     n += 1
>>
>> t2m = time.localtime().tm_min
>> t2s = time.localtime().tm_sec
>> t2 = t2m + t2s/100.0
>> td = t2 - t1
>>
>> print '\n',x,'out of 10 wrong\nAvg time/question:',td/10,'\nTotal
>> time:',td
>>
>> <snip>
>>
>>  You top-posted again.  Put your comments after the part you're quoting,
> not before.
>
> You still have a problem in the code, and I still think it's in the
> 2*self.c, though I don't have time to debug it.
>
> Look up the day for  1/1/2099, and for 1/1/2100  and it comes out the same.
>  That's not correct.  No adjacent years start on the same day, it's always
> either one day or two.
>
> You have too much in one function (method), which makes it hard to debug
> it.  Factor it into separate functions, and then test each independently.
>  And using k  for day and d for year make no sense to me, though perhaps it
> does in some other language.
>
> DaveA
>
>
Hey Dave, you probably left c and y alone when comparing the years. If the
date's 1/1/2099, then self.c = 20 and self.y=99. If you try doing it again
while changing those values, for 1/1/2099, the day comes out to be Thursday,
and for 1/1/2100 you'll get Wednesday.

Glad you pointed out the 2100 date though, there actually was a problem in
it, but it's not the 2*self.c; I had to account for d = y - 1 when y = 00
(zeller subtracts months by 2, so it needs to be the previous yr for
jan/feb).

Below is the updated code, I put in a few comments to make it read easier.

----------------------

import random, time, datetime, calendar

class Date:
    def __init__(self):
        self.c = random.randint(16,30) # first two digits in a year
        self.y = random.randint(0,99)  # last two digits in a year
        self.month = random.randint(1,12)
        self.year = self.c*100 + self.y

        apr = [4,6,9,11]
        feb = [2]
        notleap = [1700, 1800, 1900, 2100, 2200, 2300, 2500, 2600, 2700,
2900, 3000]

        if self.month in feb:          # assigns days, given the month
            if self.year%4 == 0:
                if self.year in notleap:
                    self.k = random.randint(1,28)
                else:
                    self.k = random.randint(1,29)
            else:
                self.k = random.randint(1,28)
        elif self.month in apr:
            self.k = random.randint(1,30)
        else:
            self.k = random.randint(1,31)

        if self.month in [1,2]:        # months in zeller's rule are
subtracted by 2
            if self.y == 0:            # need to acct for jan/feb year
change
                d = 99
                m = self.month + 10
            else:
                d = self.y - 1
                m = self.month + 10
        else:
            d = self.y
            m = self.month - 2

        z = self.k + (13*m-1)/5 + d + d/4 + self.c/4 - 2*self.c  # -->
Zeller's formula

        if z < 0:                      # the remainder of z/7 determines the
day of the week
            r = (abs(z)/7)*7 + z + 7   # need to account for negative z
values by adding 7 to remainder
        else:
            r = z%7

        week =
('Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday')
        self.day = week[r]

t1m = time.localtime().tm_min
t1s = time.localtime().tm_sec
t1 = t1m + t1s/100.0
n = 0
x = 0

while n < 10:
    newdate = Date()
    print '\n  ',calendar.month_name[newdate.month], str(newdate.k) +
',',newdate.year,'=',
    answer = raw_input()
    if answer.capitalize() == newdate.day:
        pass
    else:
        x += 1
    n += 1

t2m = time.localtime().tm_min
t2s = time.localtime().tm_sec
t2 = t2m + t2s/100.0
td = t2 - t1

print '\n',x,'out of 10 wrong\nAvg time/question:',td/10,'\nTotal time:',td
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20100929/fc9d331f/attachment.html>


More information about the Tutor mailing list