From mark at microenh.com Mon Mar 2 15:55:29 2009 From: mark at microenh.com (Mark Erbaugh) Date: Mon, 02 Mar 2009 09:55:29 -0500 Subject: [CentralOH] random.seed Message-ID: <1236005729.7376.7.camel@quad> I've written a Python program that generates tests and answer keys from a pool of questions. It uses random.seed with a user entered value so that the user can regenerate the same test sequence if needed. This morning, I discovered that the same seed doesn't produce the same random values on 32-bit and 64-bit systems. I think the problem is that hash() generates different values on the 32 and 64 bit systems. I found that by using random.seed(hash() & 0xffffffff) I can get the same results. Is there a better way? Is my way "safe" and repeatable? Mark From wam at cisco.com Mon Mar 2 18:13:49 2009 From: wam at cisco.com (William McVey) Date: Mon, 02 Mar 2009 12:13:49 -0500 Subject: [CentralOH] random.seed In-Reply-To: <1236005729.7376.7.camel@quad> References: <1236005729.7376.7.camel@quad> Message-ID: <1236014029.6371.33.camel@tardis> On Mon, 2009-03-02 at 09:55 -0500, Mark Erbaugh wrote: > I've written a Python program that generates tests and answer keys from > a pool of questions. It uses random.seed with a user entered value so > that the user can regenerate the same test sequence if needed. > > This morning, I discovered that the same seed doesn't produce the same > random values on 32-bit and 64-bit systems. This doesn't seem to be an issue for the systems I'm on: On a 32 bit Linux system: $ lshw | egrep 'width' *-cpu width: 32 bits $ python Python 2.5.1 (r251:54863, Jul 31 2008, 23:17:40) [GCC 4.1.3 20070929 (prerelease) (Ubuntu 4.1.2-16ubuntu2)] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> import random >>> foo, bar = random.Random(), random.Random() >>> foo.seed(5) >>> [foo.randint(0,1000) for x in range(20)] [623, 742, 795, 943, 740, 923, 29, 466, 944, 649, 901, 113, 469, 246, 544, 574, 13, 216, 279, 917] >>> bar.seed(2<<32 + 12345) >>> [bar.randint(0,1000) for x in range(20)] [337, 126, 741, 299, 335, 418, 786, 851, 810, 611, 987, 352, 535, 427, 857, 601, 47, 553, 390, 294] On a 64 bit Linux system: $ lshw | egrep 'cpu|width' *-cpu:0 width: 64 bits $ python Python 2.5.2 (r252:60911, Jul 31 2008, 17:31:22) [GCC 4.2.3 (Ubuntu 4.2.3-2ubuntu7)] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> import random >>> foo, bar = random.Random(), random.Random() >>> foo.seed(5) >>> [foo.randint(0,1000) for x in range(20)] [623, 742, 795, 943, 740, 923, 29, 466, 944, 649, 901, 113, 469, 246, 544, 574, 13, 216, 279, 917] >>> bar.seed(2<<32 + 12345) >>> [bar.randint(0,1000) for x in range(20)] [337, 126, 741, 299, 335, 418, 786, 851, 810, 611, 987, 352, 535, 427, 857, 601, 47, 553, 390, 294] > I think the problem is that hash() generates different values on > the 32 and 64 bit systems. I found that by using > > random.seed(hash() & 0xffffffff) This is where you problem is. hash() is not guaranteed to be consistent across hosts. I don't think it's even guaranteed to be consistent across invocations on the same host. The fact that it is stable across hosts on the same platform is an implementation artifact which shouldn't be depended upon. You can check out http://docs.python.org/reference/datamodel.html#object.__hash__ for more info on why hash() returns different values on 32bit system and 64 bit systems. I would highly suggest using one the hash functions in the hashlib standard module, which are based on defined standards which are guaranteed to yield a stable value across invocations, hosts, platforms, python implementations. Alternatively, if you demand high performance but not an extremely large set of possible seed values, you could look into the binascii module which have several routines to map a string into integer in a consistent manner (e.g. binascii.crc32). > I can get the same results. Is there a better way? Yes. Use hashlib. > Is my way "safe" and repeatable? Nope. You have a workaround for an implementation artifact; however, Jython, IronPython, or PyPy may choose to calculate hash() values of strings differently than CPython. Even differing versions of CPython on the same platform may introduce incompatible hash() values as well. -- William From mark at microenh.com Mon Mar 2 18:36:27 2009 From: mark at microenh.com (Mark Erbaugh) Date: Mon, 02 Mar 2009 12:36:27 -0500 Subject: [CentralOH] random.seed In-Reply-To: <1236014029.6371.33.camel@tardis> References: <1236005729.7376.7.camel@quad> <1236014029.6371.33.camel@tardis> Message-ID: <1236015387.8269.6.camel@quad> On Mon, 2009-03-02 at 12:13 -0500, William McVey wrote: > On Mon, 2009-03-02 at 09:55 -0500, Mark Erbaugh wrote: > > I've written a Python program that generates tests and answer keys from > > a pool of questions. It uses random.seed with a user entered value so > > that the user can regenerate the same test sequence if needed. > > > > This morning, I discovered that the same seed doesn't produce the same > > random values on 32-bit and 64-bit systems. > > This doesn't seem to be an issue for the systems I'm on: > > I think the problem is that hash() generates different values on > > the 32 and 64 bit systems. I found that by using Thanks for checking. The reason you got the same results is that random.seed doesn't use hash if the seed is an int or long. In my case, I was using strings where it does use hash. > This is where you problem is. hash() is not guaranteed to be consistent > across hosts. I don't think it's even guaranteed to be consistent across > invocations on the same host. The fact that it is stable across hosts on > the same platform is an implementation artifact which shouldn't be > depended upon. You can check out > http://docs.python.org/reference/datamodel.html#object.__hash__ for more > info on why hash() returns different values on 32bit system and 64 bit > systems. I would highly suggest using one the hash functions in the > hashlib standard module, which are based on defined standards which are > guaranteed to yield a stable value across invocations, hosts, platforms, > python implementations. Alternatively, if you demand high performance > but not an extremely large set of possible seed values, you could look > into the binascii module which have several routines to map a string > into integer in a consistent manner (e.g. binascii.crc32). > > > I can get the same results. Is there a better way? > > Yes. Use hashlib. > > > Is my way "safe" and repeatable? > > Nope. You have a workaround for an implementation artifact; however, > Jython, IronPython, or PyPy may choose to calculate hash() values of > strings differently than CPython. Even differing versions of CPython on > the same platform may introduce incompatible hash() values as well. Thanks for the information. Mark From harrisbw at notes.udayton.edu Wed Mar 18 21:48:50 2009 From: harrisbw at notes.udayton.edu (Bryan Harris) Date: Wed, 18 Mar 2009 16:48:50 -0400 Subject: [CentralOH] Handy function to decimate a list of numbers (get every Nth item) Message-ID: <200903181648.50987.harrisbw@notes.udayton.edu> Hey all, I came up with this little snippet to get every Nth line in a list. Google didn't turn anything up in the first few pages. Does anybody know a better way? This seems like the kind of thing python would be able to do automatically using the % (modulo) symbol or something. Code: def decimate(array,points): if type(points) != type(1): #line 1.5 doesn't mean anything! raise Error, "number of points should be an integer" if len(array)/2<=points: #Not worth doing for an array this small return array new_array=[] #get the line numbers rather than stepping through the entire list interval=int(len(array)/points) line_numbers = range(0,len(array),interval) for each in line_numbers: new_array=new_array + [array[each]] return(new_array) -- Bryan Harris Research Engineer Structures and Materials Evaluation Group harrisbw at notes.udayton.edu http://www.udri.udayton.edu/ (937) 229-5561 From mark at microenh.com Wed Mar 18 22:02:39 2009 From: mark at microenh.com (Mark Erbaugh) Date: Wed, 18 Mar 2009 17:02:39 -0400 Subject: [CentralOH] Handy function to decimate a list of numbers (get every Nth item) In-Reply-To: <200903181648.50987.harrisbw@notes.udayton.edu> References: <200903181648.50987.harrisbw@notes.udayton.edu> Message-ID: <1237410159.17611.6.camel@quad> On Wed, 2009-03-18 at 16:48 -0400, Bryan Harris wrote: > Hey all, I came up with this little snippet to get every Nth line in a list. > Google didn't turn anything up in the first few pages. Does anybody know a > better way? This seems like the kind of thing python would be able to do > automatically using the % (modulo) symbol or something. > > Code: > def decimate(array,points): > if type(points) != type(1): #line 1.5 doesn't mean anything! > raise Error, "number of points should be an integer" > > if len(array)/2<=points: #Not worth doing for an array this small > return array > > new_array=[] > #get the line numbers rather than stepping through the entire list > interval=int(len(array)/points) > line_numbers = range(0,len(array),interval) > > for each in line_numbers: > new_array=new_array + [array[each]] > return(new_array) > > How about array[::points]? demo: array = ['Line %d] % i for i in range(100)] array[::10] ['Line 0', 'Line 10', ... 'Line 90'] Mark From david.car7 at gmail.com Thu Mar 19 01:22:59 2009 From: david.car7 at gmail.com (David Car) Date: Wed, 18 Mar 2009 20:22:59 -0400 Subject: [CentralOH] Handy function to decimate a list of numbers (get every Nth item) In-Reply-To: <1237410159.17611.6.camel@quad> References: <200903181648.50987.harrisbw@notes.udayton.edu> <1237410159.17611.6.camel@quad> Message-ID: <37f7fbce0903181722x386bea25m7922f9f72c138c@mail.gmail.com> Yeah, Marks is the fast way to do it. Regards, David On Wed, Mar 18, 2009 at 5:02 PM, Mark Erbaugh wrote: > On Wed, 2009-03-18 at 16:48 -0400, Bryan Harris wrote: > > Hey all, I came up with this little snippet to get every Nth line in a > list. > > Google didn't turn anything up in the first few pages. Does anybody know > a > > better way? This seems like the kind of thing python would be able to do > > automatically using the % (modulo) symbol or something. > > > > Code: > > def decimate(array,points): > > if type(points) != type(1): #line 1.5 doesn't mean anything! > > raise Error, "number of points should be an integer" > > > > if len(array)/2<=points: #Not worth doing for an array this small > > return array > > > > new_array=[] > > #get the line numbers rather than stepping through the entire list > > interval=int(len(array)/points) > > line_numbers = range(0,len(array),interval) > > > > for each in line_numbers: > > new_array=new_array + [array[each]] > > return(new_array) > > > > > > > How about array[::points]? > > demo: > > array = ['Line %d] % i for i in range(100)] > > array[::10] > > ['Line 0', 'Line 10', ... 'Line 90'] > > Mark > > > > _______________________________________________ > CentralOH mailing list > CentralOH at python.org > http://mail.python.org/mailman/listinfo/centraloh > -------------- next part -------------- An HTML attachment was scrubbed... URL: From harrisbw at notes.udayton.edu Tue Mar 31 19:19:17 2009 From: harrisbw at notes.udayton.edu (Bryan Harris) Date: Tue, 31 Mar 2009 13:19:17 -0400 Subject: [CentralOH] Veusz - New project PPA Message-ID: <200903311319.17178.harrisbw@notes.udayton.edu> Hi all, I have started working on a project called Veusz. (Pronounced VIEWS). It's a scientific plotting software similar to Kaleidagraph. It's written all in Python and PtQT. I got the thing building Ubuntu packages and started a PPA. If you add the following lines in synaptic: deb http://ppa.launchpad.net/brywilharris/ppa/ubuntu intrepid main deb-src http://ppa.launchpad.net/brywilharris/ppa/ubuntu intrepid main You can get the latest version of veusz. (There's also a Jaunty version, which I'll start updating when Jaunty comes out.) Have fun! Please give me feedback! Bryan -- Bryan Harris Research Engineer Structures and Materials Evaluation Group brywilharris+gna at gmail.com http://www.udri.udayton.edu/ (937) 229-5561