Eval (was Re: Question about using python as a scripting language)

2006-08-09 Thread Brendon Towle
Slawomir Nowaczyk noted:#> Heck, whenever *is* it OK to use eval() then?eval is like optimisation. There are two rules:Rule 1: Do not use it.Rule 2 (for experts only): Do not use it (yet).So, that brings up a question I have. I have some code that goes out to a website, grabs stock data, and sends out some reports based on the data.Turns out that the website in question stores its data in the format of a Python list (http://quotes.nasdaq.com/quote.dll?page=nasdaq100, search the source for "var table_body"). So, the part of my code that extracts the data looks something like this:    START_MARKER = 'var table_body = '    END_MARKER = '];'    def extractStockData(data):    pos1 = data.find(START_MARKER)    pos2 = data.find(END_MARKER, pos1)    return eval(data[pos1+len(START_MARKER):END_MARKER])(I may have an off-by-one error in there somewhere -- this is from memory, and the code actually works.)My question is: what's the safe way to do this?B. -- Brendon Towle, PhDCognitive Scientist+1-412-690-2442x127Carnegie Learning, Inc.The Cognitive Tutor Company ®Helping over 375,000 students in 1000 school districts succeed in math. -- 
http://mail.python.org/mailman/listinfo/python-list

Re: Eval (was Re: Question about using python as a scripting language)

2006-08-09 Thread Brendon Towle
On 9 Aug 2006, at 11:04 AM, Chris Lambacher wrote:How is your data stored? (site was not loading for me).In the original source HTML, it's like this (I've deleted all but the beginning and the end of the list for clarity):var table_body = [["ATVI", "Activision, Inc.",12.75,0.15,1.19,2013762,0.04,"N","N"],["YHOO", "Yahoo! Inc.",27.7,0.26,0.95,6348884,0.21,"N","N"]];More sophisiticated situations (like nested lists) may require something like pyparsing.I could do that, or I could do something like the re.* trick mentioned by another poster. But, doesn't it offend anyone else that the only clean way to access functionality that's already in Python is to write long complicated Python code? Python already knows how to extract a list object from a string; why should I have to rewrite that?B.On Wed, Aug 09, 2006 at 10:23:49AM -0400, Brendon Towle wrote:    Slawomir Nowaczyk noted:     #> Heck, whenever *is* it OK to use eval() then?     eval is like optimisation. There are two rules:     Rule 1: Do not use it.     Rule 2 (for experts only): Do not use it (yet).   So, that brings up a question I have. I have some code that goes out to a   website, grabs stock data, and sends out some reports based on the data.   Turns out that the website in question stores its data in the format of a   Python list ([1]http://quotes.nasdaq.com/quote.dll?page=nasdaq100, search   the source for "var table_body"). So, the part of my code that extracts   the data looks something like this:       START_MARKER = 'var table_body = '       END_MARKER = '];'   def extractStockData(data):       pos1 = data.find(START_MARKER)       pos2 = data.find(END_MARKER, pos1)       return eval(data[pos1+len(START_MARKER):END_MARKER])   (I may have an off-by-one error in there somewhere -- this is from memory,   and the code actually works.)   My question is: what's the safe way to do this?   B.   --   Brendon Towle, PhD   Cognitive Scientist   +1-412-690-2442x127   Carnegie Learning, Inc.   The Cognitive Tutor Company ®   Helping over 375,000 students in 1000 school districts succeed in math.References   Visible links   1. http://quotes.nasdaq.com/quote.dll?page=nasdaq100  -- http://mail.python.org/mailman/listinfo/python-list  -- Brendon Towle, PhDCognitive Scientist+1-412-690-2442x127Carnegie Learning, Inc.The Cognitive Tutor Company ®Helping over 375,000 students in 1000 school districts succeed in math. -- 
http://mail.python.org/mailman/listinfo/python-list

Re: Eval (was Re: Question about using python as a scripting language)

2006-08-09 Thread Brendon Towle
On 9 Aug 2006, at 12:03 PM, [EMAIL PROTECTED] wrote:    Brendon> I could do that, or I could do something like the re.* trick    Brendon> mentioned by another poster. But, doesn't it offend anyone else    Brendon> that the only clean way to access functionality that's already    Brendon> in Python is to write long complicated Python code? Python    Brendon> already knows how to extract a list object from a string; why    Brendon> should I have to rewrite that?Doesn't bother me at all.  One, it's not actually Python code, it's_javascript_.  It's just serendipity that the table can be parsed as a Pythonlist.  Two, there's nothing to prevent the authors from changing theformatting in an incompatible way in the future.I think that these are actually the same reason, and can be safely ignored, because item 2 is true no matter what method I use to parse the data. Sure, it's serendipity, but that happens to be the hand I'm dealt at the moment; why not exploit the serendipity?  Three, it's completelyuntrusted input and shouldn't be fed to eval().  This is the crucial point, and the reason I asked the question to begin with.Lisp (which I'm used to) has the read-eval-print loop; I think that my confusion was because:1. Python's eval(X) is essentially the same as Lisp's (eval (read-from-string X)), not Lisp's (eval X) or Lisp's (read-from-string X);2. The '[' character that begins a list should actually be read as a function call, not a data delimiter. (Which, in the context of list comprehensions, makes a lot of sense as I think about it.)Four, it's not actuallycomplicated code (using the csv module would probably be simpler).I'll look into the csv module.And, it may not be complicated on an absolute scale, but Chris' re.* method turned one line of code into about 15; that's certainly a non-trivial increase in complexity.Five, you have to stop thinking of it a "listobject".  It's just a string of bytes which happens at this point in time tointersect with the definition of a Python list.  You're trying to wish itwas something that it's not.I must be confused here. If I call the following function:  eval('[1, 2, 3]')what does that function call return, if not a list object?Sure, the string isn't a list object; it's a string of bytes that happens to be syntactically identical to the definition of a list in python code. I was hoping for a clean and safe way to exploit that identical-ness; apparently, all the clean ways are unsafe, and all the safe ways are unclean.B. -- Brendon Towle, PhDCognitive Scientist+1-412-690-2442x127Carnegie Learning, Inc.The Cognitive Tutor Company ®Helping over 375,000 students in 1000 school districts succeed in math. -- 
http://mail.python.org/mailman/listinfo/python-list

Re: Eval (was Re: Question about using python as a scripting language)

2006-08-10 Thread Brendon Towle
Date: 9 Aug 2006 14:12:01 -0700From: "Simon Forman" <[EMAIL PROTECTED]>Subject: Re: Eval (was Re: Question about using python as a scripting	language)To: python-list@python.orgMessage-ID: <[EMAIL PROTECTED]>Content-Type: text/plain; charset="iso-8859-1"Fredrik Lundh posted a great piece of code to parse a subset of pythonsafely:http://groups.google.ca/group/comp.lang.python/browse_frm/thread/8e427c5e6da35c/a34397ba74892b4eThis, as it turns out, was the most helpful pointer of them all -- thanks!B. -- Brendon Towle, PhDCognitive Scientist+1-412-690-2442x127Carnegie Learning, Inc.The Cognitive Tutor Company ®Helping over 375,000 students in 1000 school districts succeed in math. -- 
http://mail.python.org/mailman/listinfo/python-list

Re: Python-list Digest, Vol 35, Issue 160

2006-08-10 Thread Brendon Towle
Date: Thu, 10 Aug 2006 08:51:12 -0400From: Brendon Towle <[EMAIL PROTECTED]>Subject: Re: Eval (was Re: Question about using python as a scripting	language) Date: 9 Aug 2006 14:12:01 -0700From: "Simon Forman" <[EMAIL PROTECTED]>Subject: Re: Eval (was Re: Question about using python as a scripting	language)To: python-list@python.orgMessage-ID: <[EMAIL PROTECTED]>Content-Type: text/plain; charset="iso-8859-1"Fredrik Lundh posted a great piece of code to parse a subset of pythonsafely:http://groups.google.ca/group/comp.lang.python/browse_frm/thread/ 8e427c5e6da35c/a34397ba74892b4e This, as it turns out, was the most helpful pointer of them all --  thanks!Actually, I spoke too soon. (I should have known better -- always test first.) But:>>>import SafeEval as se>>>se.safeEval('[["AAPL", 35.5, 0.45],["YHOO", 75.68, 0.01]]')[['AAPL', 35.5, 0.45001], ['YHOO', 75.687, 0.01]]>>>se.safeEval('[["AAPL", 35.5, 0.45],["YHOO", 75.68, -0.01]]')SyntaxError: malformed _expression_ (-)Seems that parsing negative numbers is outside of the scope of this routine. Here's the source (which is Frederik's source with one minor renaming; I take no credit here); anyone have any ideas?B. start source import cStringIO, tokenize def sequence(next, token, end):    out = []    token = next()    while token[1] != end:        out.append(atom(next, token))        token = next()        if token[1] == "," or token[1] == ":":            token = next()    return out def atom(next, token):    if token[1] == "(":        return tuple(sequence(next, token, ")"))    elif token[1] == "[":        return sequence(next, token, "]")    elif token[1] == "{":        seq = sequence(next, token, "}")        res = {}        for i in range(0, len(seq), 2):            res[seq[i]] = seq[i+1]        return res    elif token[0] in (tokenize.STRING, tokenize.NUMBER):        return eval(token[1]) # safe use of eval!    raise SyntaxError("malformed _expression_ (%s)" % token[1]) def safeEval(source):    src = ""    src = ""    src = "" for token in src if token[0] is not tokenize.NL)    res = atom(src.next, src.next())    if src.next()[0] is not tokenize.ENDMARKER:        raise SyntaxError("bogus data after _expression_")    return res  end source  -- Brendon Towle, PhDCognitive Scientist+1-412-690-2442x127Carnegie Learning, Inc.The Cognitive Tutor Company ®Helping over 375,000 students in 1000 school districts succeed in math. -- 
http://mail.python.org/mailman/listinfo/python-list

Re: Eval (was Re: Question about the use of python as a scripting language)

2006-08-10 Thread Brendon Towle
Oops -- I missed the subject line on my last post.On 10 Aug 2006, at 9:41 AM, [EMAIL PROTECTED] wrote:    Brendon> Seems that parsing negative numbers is outside of the scope of    Brendon> this routine. Here's the source (which is Frederik's source    Brendon> with one minor renaming; I take no credit here); anyone have    Brendon> any ideas?Negative numbers are actually tokenized as a MINUS followed by a NUMBER:    % python    Python 2.5b2 (trunk:50921, Jul 28 2006, 20:21:50)     [GCC 4.0.0 (Apple Computer, Inc. build 5026)] on darwin    Type "help", "copyright", "credits" or "license" for more information. - 47     -47Try changing your atom function to detect a minus sign, remember that fact,then require the next token to be a number.While I appreciate the suggestion, this is exactly the route I don't want to take -- it essentially involves rewriting the Python parser/tokenizer, which has already been written and tested by people much more qualified than I. In fact, the code I was using (Frederik's code) has already been written and tested by people much more qualified than I, and it _still_ doesn't work.A shortcut occurs to me; maybe someone can tell me what's wrong with my reasoning here. It seems that any string that is unsafe to pass to eval() must involve a function call, and thus must contain an opening paren. Given that I know that the data I expect contains no parens, would people expect this code to be safe:START_MARKER = 'var table_body = 'END_MARKER = '];'    def extractStockData(data):    pos1 = data.find(START_MARKER)    pos2 = data.find(END_MARKER, pos1)    parenPos = data.find('(')    if parenPos >= 0:        raise "Data format changed -- found a paren"    else:        return eval(data[pos1+len(START_MARKER):pos2+1])B. -- Brendon Towle, PhDCognitive Scientist+1-412-690-2442x127Carnegie Learning, Inc.The Cognitive Tutor Company ®Helping over 375,000 students in 1000 school districts succeed in math. -- 
http://mail.python.org/mailman/listinfo/python-list

Re: Eval (was Re: Question about the use of python as a scripting language)

2006-08-10 Thread Brendon Towle
On 10 Aug 2006, at 10:46 AM, [EMAIL PROTECTED] wrote:    Brendon> A shortcut occurs to me; maybe someone can tell me what's wrong    Brendon> with my reasoning here. It seems that any string that is unsafe    Brendon> to pass to eval() must involve a function call, and thus must    Brendon> contain an opening paren. Given that I know that the data I    Brendon> expect contains no parens, would people expect this code to be    Brendon> safe:Unfortunately, no.  If I define a class which has properties, attributeassignment can involve arbitrary numbers of function calls.Oh yeah -- forgot about that. Thanks.But, how could you get that class into my eval() call? Unless I'm missing something (entirely possible -- as we've seen above, I already did), it seems that you have only two options:1. Get the code containing the class on my local machine, and import the class -- in this case, I'm screwed long before I call eval().2. Include it in the page I downloaded -- in this case, the function calls will be part of the string, and the data.pos('(') call will find them.Am I missing a third option? B.-- Brendon Towle, PhDCognitive Scientist+1-412-690-2442x127Carnegie Learning, Inc.The Cognitive Tutor Company ®Helping over 375,000 students in 1000 school districts succeed in math. -- 
http://mail.python.org/mailman/listinfo/python-list

Re: List Splitting

2006-08-21 Thread Brendon Towle
Not the most elegant solution, perhaps, but:>>>t = [ "a", "b", "c", "n", "a", "a", "t", "t", "t" ]>>>outlist = []>>>for x in range(3):...    temp=[]...    for y in range(len(t)/3):...        temp.append(t[3*y+x])...    outlist.append(temp)>>>outlist[['a', 'n', 't'], ['b', 'a', 't'], ['c', 'a', 't']] -- Brendon Towle, PhDCognitive Scientist+1-412-690-2442x127Carnegie Learning, Inc.The Cognitive Tutor Company ®Helping over 375,000 students in 1000 school districts succeed in math. -- 
http://mail.python.org/mailman/listinfo/python-list

Re: Consistency in Python

2006-08-25 Thread Brendon Towle
Date: 25 Aug 2006 04:22:37 -0700From: "Paul Boddie" <[EMAIL PROTECTED]>Subject: Re: Consistency in PythonTo: python-list@python.orgMessage-ID: <[EMAIL PROTECTED]>Content-Type: text/plain; charset="iso-8859-1"Paul McGuire wrote: But with mutators that return self, a client could write any of these:bx = Box().length(100).width(50).height(20)bx = Box().width(50).height(20).length(100)bx = Box().width(50).length(100).height(20)...etc...and the results are the same. This is very convenient, and I've often thought about doing such thingsin my own APIs, but there can sometimes be subtle problems introducedinto programs when you decide to change the nature of such a mutator,or if you have another type/class whose mutators are of a differentnature, such that the width method produces a new Box object (which isquite similar to what the questioner seemed to have in mind) instead ofmutating (or failing to mutate) the existing object.Indeed, it may be important to know whether you're creating new objectsor not, and without metadata the most convenient way to communicatethis is quite probably to define a rigid interface (after all, whyshould width or append return an object?) which cannot be implementedon immutable things.So, it's possible that the above answers the question I have and I'm just not clever enough to see the answer. But:I had a case where I wanted to extract and return the top N elements of a list (where "top" meant "smallest numeric value"; the alternative for "largest numeric value" is a trivial modification). To me, the obvious answer was:def topNElements(lst, n):    return lst.sort()[:n]But, of course, that fails with a TypeError, because lst.sort() returns None, which is not subscriptable. The function really needs to be:def topNElements(lst, n):    lst.sort()    return lst[:n]It gets worse if I want to include an invariant in the list before I sort it:def bogusTopNElementsWithInvariant(lst, n):    return lst.append(INVARIANT).sort()[:n]def topNElementsWithInvariant(lst, n)    lst.append(INVARIANT)    lst.sort()    return lst[:n]So, my question is: Someone obviously thought that it was wise and proper to require the longer versions that I write above. Why?B. -- Brendon Towle, PhDCognitive Scientist+1-412-690-2442x127Carnegie Learning, Inc.The Cognitive Tutor Company ®Helping over 375,000 students in 1000 school districts succeed in math. -- 
http://mail.python.org/mailman/listinfo/python-list

Re: Consistency in Python

2006-08-25 Thread Brendon Towle
Message: 3 Date: Fri, 25 Aug 2006 15:28:46 +0200 From: "Fredrik Lundh" <[EMAIL PROTECTED]> Subject: Re: Consistency in Python  Brendon Towle wrote:  So, my question is: Someone obviously thought that it was wise and proper to require the longer versions that I write above. Why?  a) maybe they had a working carriage return key ?Right. Now that we've got the "Frederik gets sarcastic with a relative Python newcomer" bit out of the way, is there an actual *answer* somewhere in the community? b) http://pyfaq.infogami.com/why-doesn-t-list-sort-return-the-sorted-list    (this also explains how to handle your specific use case)Well, I posted working code, so I thought it should have been obvious that I knew how to handle my use case, and was (am) looking for a language-design level answer as opposed to a working-code level answer. Besides, the article above (although useful *and* freshly modified) doesn't explain how to handle the use case I posted with append(), or the ones I didn't post with extend(), insert(), remove(), dict.update(), and a bunch of others I can't think of off the top of my head. c) in general, mutating *and* returning may be confusing; consider:      lst = [1, 2, 3]     for item in lst.reverse():         print item     ... some other code ...     for item in lst.reverse():         print itemI guess I have three responses to this. The first is that generations of Lisp programmers seem to have handled mutating *and* returning just fine for about the last 50 years; maybe it really isn't all that hard. ("Always know where your CONS cells are coming from." is pretty ingrained in my programming DNA; the Python analog isn't hard.)My second response is that if "... some other code ..." is so long and involved that you've forgotten that you already reversed lst, then your function probably needs to be refactored and/or rewritten.My third response is that it's *always* possible to shoot yourself in the foot. Protecting a naive user from one particular metatarsal projectile insertion at the expense of letting the power-user write more concise code seems a bad tradeoff to me -- but, I'm not involved with Python design, which brings me back to my original question above. Anyone? B. -- Brendon Towle, PhDCognitive Scientist+1-412-690-2442x127Carnegie Learning, Inc.The Cognitive Tutor Company ®Helping over 375,000 students in 1000 school districts succeed in math. -- 
http://mail.python.org/mailman/listinfo/python-list

Re: sending emails using python

2006-09-07 Thread Brendon Towle

On Sep 7, 2006, at 3:50 AM, "sridhar"  
<[EMAIL PROTECTED]>wrote:


> iam having user account on an exchangeserver.
> with that can i send an email using python?
>
> if iam using the following code iam getting error
>
>
> fromAddress = '[EMAIL PROTECTED]'
> toAddress = '[EMAIL PROTECTED]'
> msg = "Subject: Hello\n\nThis is the body of the message."
> import smtplib
> server = smtplib.SMTP("hstmsg002",25)
> server.sendmail(fromAddress, toAddress, msg)
>
> error:
>
> Traceback (most recent call last):
>   File
> "C:\sridhar\Beginning_Python\Beginning_Python\Chapter16\tryitout 
> \InitialMailExample.py",
> line 5, in ?
> server = smtplib.SMTP("hstmsg002",25)
>   File "C:\Python24\lib\smtplib.py", line 244, in __init__
> (code, msg) = self.connect(host, port)
>   File "C:\Python24\lib\smtplib.py", line 307, in connect
> (code, msg) = self.getreply()
>   File "C:\Python24\lib\smtplib.py", line 351, in getreply
> raise SMTPServerDisconnected("Connection unexpectedly closed")
> SMTPServerDisconnected: Connection unexpectedly closed
>

I saw a similar error when I was not following the server's  
authentication protocol -- either failing to authenticate when it  
wanted it, or authenticating when it didn't want it. Here's the code  
I use -- tested on both an Exchange server and on Comcast's SMTP  
servers. It assumes some globals (in all caps) which you need to set  
first.

def emailGivenString(host=SMTP_HOST, fromAddr=FROM_ADDR,
  toAddr=TO_ADDR, subject='', body='', auth=False):
 server = smtplib.SMTP(host)
 if auth:
 server.login('username', 'password')
 outMessage = 'From: %s\rTo: %s\rSubject: %s\r%s' %
  (FROM_HEADER, TO_HEADER, subject, body)
 server.sendmail(fromAddr, toAddr, outMessage)

If this doesn't work, I second the previous suggestion of talking to  
the server admin.

B.

--
Brendon Towle, Ph.D.   <[EMAIL PROTECTED]>  +1-412-362-1530
“Debugging is twice as hard as writing the code in the first place.  
Therefore,
if you write the code as cleverly as possible, you are, by  
definition, not
smart enough to debug it.” – Brian W. Kernighan


-- 
http://mail.python.org/mailman/listinfo/python-list


Random Drawing Simulation -- performance issue

2006-09-12 Thread Brendon Towle
I need to simulate scenarios like the following: "You have a deck of  
3 orange cards, 5 yellow cards, and 2 blue cards. You draw a card,  
replace it, and repeat N times."

So, I wrote the following code, which works, but it seems quite slow  
to me. Can anyone point out some obvious thing that I'm doing  
inefficiently? Or, is this more or less as good as it gets?

For reference, my typical numbers look like this:

   2 <= len(population) <= 7
   4 <= len(mapping) <= 50
   10 <= count <= 100

B.


#!/usr/bin/env python

import random

def randomDrawing(count, population):
 """Simulates drawing  items from , with  
replacement.
 population is a list of lists: [[count1, type1], [count2,  
type2], ...]

 Typical examples:
 >>>randomDrawing(100, [[3, 'orange'], [5, 'yellow'], [2, 'blue']])
 [[28, 'orange'], [57, 'yellow'], [15, 'blue']]

 >>>randomDrawing(10, [[3, 'orange'], [5, 'yellow'], [2,  
'blue']])
 [[29923, 'orange'], [50208, 'yellow'], [19869, 'blue']]

 """
 res = [[0, item[1]] for item in population]
 mapping = []
 for i in xrange(len(population)):
 mapping.extend([i]*population[i][0])
 for i in xrange(count):
 index = random.choice(mapping)
 res[index][0] += 1
 return res



-- 
Brendon Towle, PhD
Cognitive Scientist
+1-412-690-2442x127
Carnegie Learning, Inc.
The Cognitive Tutor Company ®
Helping over 375,000 students in 1000 school districts succeed in math.


-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Random Drawing Simulation -- performance issue

2006-09-13 Thread Brendon Towle

On 12 Sep 2006, at 6:33 PM, [EMAIL PROTECTED] wrote:

> Date: 12 Sep 2006 15:23:51 -0700
> From: "Simon Forman" <[EMAIL PROTECTED]>
> Subject: Re: Random Drawing Simulation -- performance issue
>
> Brendon Towle wrote:
>> I need to simulate scenarios like the following: "You have a deck of
>> 3 orange cards, 5 yellow cards, and 2 blue cards. You draw a card,
>> replace it, and repeat N times."
>>  [my original code snipped]
>
> I got nearly a 2x speed up with this variant:
>
> def randomDrawing3(count, population):
> res = [[0, item[1]] for item in population]
> mapping = []
> for i in xrange(len(population)):
> mapping.extend([i]*population[i][0])
>
> n = len(mapping)
> for i in xrange(count):
> index = int(n * random.random())
> res[mapping[index]][0] += 1
>
> return res

Excellent! For some reason, the speedup I get is only ~1.5x, but  
that's still non-trivial.

Thanks much for the pointer-

B.


-- 
Brendon Towle, PhD
Cognitive Scientist
+1-412-690-2442x127
Carnegie Learning, Inc.
The Cognitive Tutor Company ®
Helping over 375,000 students in 1000 school districts succeed in math.


-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Random Drawing Simulation -- performance issue

2006-09-13 Thread Brendon Towle
On 13 Sep 2006, at 1:01 AM, [EMAIL PROTECTED] wrote:

> Date: 12 Sep 2006 20:17:47 -0700
> From: Paul Rubin <http://[EMAIL PROTECTED]>
> Subject: Re: Random Drawing Simulation -- performance issue
> To: python-list@python.org
>
> "Travis E. Oliphant" <[EMAIL PROTECTED]> writes:
>>> I need to simulate scenarios like the following: "You have a deck of
>>> 3 orange cards, 5 yellow cards, and 2 blue cards. You draw a card,
>>> replace it, and repeat N times."
>>>
>> Thinking about the problem as drawing sample froms a discrete
>> distribution defined by the population might help.
>
> Is there some important reason you want to do this as a simulation?
> And is the real problem more complicated?  If you draw from the
> distribution 100,000 times with replacement and sum the results, per
> the Central Limit Theorem you'll get something very close to a normal
> distribution whose parameters you can determine analytically.  There
> is probably also some statistics formula to find the precise error.
> So you can replace the 100,000 draws with a single draw.

The real problem is not substantially more complicated. (The real  
code is, because it's embedded in a bunch of other stuff, but that's  
not the point.)

I guess the essential reason that I want to do it as a simulation,  
and not as a statistics formula, is that I'd like the code to be  
readable (and modifiable) by a programmer who doesn't have a  
statistics background. I could dredge up enough of my college stats  
to do as you suggest (although I might not enjoy it), but I don't  
think I want to make that a requirement.

On the other hand (quote somewhat snipped):

> Date: Tue, 12 Sep 2006 22:46:04 -0500
> From: Robert Kern <[EMAIL PROTECTED]>
> Subject: Re: Random Drawing Simulation -- performance issue
> To: python-list@python.org
>
> Along the lines of what you're trying to get at, the problem that  
> the OP is
> describing is one of sampling from a multinomial distribution.
>
> numpy has a function that will do the sampling for you:
>
> In [4]: numpy.random.multinomial?
> Docstring:
>  Multinomial distribution.
>
>  multinomial(n, pvals, size=None) -> random values
>
>  pvals is a sequence of probabilities that should sum to 1  
> (however, the
>  last element is always assumed to account for the remaining  
> probability
>  as long as sum(pvals[:-1]) <= 1).

Here, I'm torn. I do want the code to be accessible to non-stats  
people, but this just might do the trick. Must ponder.

Thanks, everyone, for your helpful suggestions!

B.

-- 
Brendon Towle, PhD
Cognitive Scientist
+1-412-690-2442x127
Carnegie Learning, Inc.
The Cognitive Tutor Company ®
Helping over 375,000 students in 1000 school districts succeed in math.


-- 
http://mail.python.org/mailman/listinfo/python-list


Python API to OS X Address Book?

2006-09-25 Thread Brendon Towle
Essentially, I'm looking for a Python equivalent to the ObjectiveC stuff that 
can be found at:

  
http://developer.apple.com/documentation/UserExperience/Conceptual/AddressBook/index.html

Google got me that far, but was not particularly helpful past that.

Anyone have any pointers?

B.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Questions on Using Python to Teach Data Structures and Algorithms

2006-09-28 Thread Brendon Towle
Some of your Lisp translations are subtly off...


> Date: 28 Sep 2006 02:49:50 -0700
> From: "sturlamolden" <[EMAIL PROTECTED]>
> Subject: Re: Questions on Using Python to Teach Data Structures and
>   Algorithms
> To: python-list@python.org
>
> If you want to make a chained structure, then perhaps you know LISP?
> This is what the basic machinery of LISP looks like in Python:
>
> def cons(a,b)
>return [a,b]

should be:
 return [a].extend(b)

> def car(structure)
>return structure[0]
>
> def cdr(structure)
>return structure[1]

should be:
 return structure[1:]

B.

--
Brendon Towle, Ph.D.   <[EMAIL PROTECTED]>  +1-412-362-1530
“Debugging is twice as hard as writing the code in the first place.  
Therefore,
if you write the code as cleverly as possible, you are, by  
definition, not
smart enough to debug it.” – Brian W. Kernighan


-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Questions on Using Python to Teach Data Structures and Algorithms

2006-09-28 Thread Brendon Towle
On 28 Sep 2006, at 8:05 AM, [EMAIL PROTECTED] wrote:

> From: Bruno Desthuilliers <[EMAIL PROTECTED]>
> Subject: Re: Questions on Using Python to Teach Data Structures and
>   Algorithms
> To: python-list@python.org
>
> Brendon Towle wrote:
>> Some of your Lisp translations are subtly off...
>
> Seems correct to me. Lisp lists are linked lists, not arrays.
>
>>
>>> Date: 28 Sep 2006 02:49:50 -0700
>>> From: "sturlamolden" <[EMAIL PROTECTED]>
>>> Subject: Re: Questions on Using Python to Teach Data Structures and
>>> Algorithms
>>> To: python-list@python.org
>>>
>>> If you want to make a chained structure, then perhaps you know LISP?
>>> This is what the basic machinery of LISP looks like in Python:
>>>
>>> def cons(a,b)
>>>return [a,b]
>>
>> should be:
>> return [a].extend(b)
>
> A Lisp cons is made of a reference to it's content and a reference to
> the rest of the list, so cons = lambda a, b : [a, b] seems the most
> straightforward translation.

Yes, a lisp cons is a pair of references as you describe. However,  
the following lisp call:

? (cons  )

returns a single level list, with  as its new first item, and  
the original contents of  as the remainder of the list. The  
OP's code doesn't do that; it returns a list of two items, with  
 as the second item.

To put it another way, the following code is always true in Lisp:

? (= (length (cons  )) (1+ (length )))

But the OP's code only allows that to be true when  is of  
length 1.


I suppose, of course, that you could claim that the following Lisp list:

   (1 2 3 4)

should translate into the following Python list:

   [1, [2, [3, [4

But, I think that's a bit silly.


>>> def car(structure)
>>>return structure[0]
>>>
>>> def cdr(structure)
>>>return structure[1]
>>
>> should be:
>> return structure[1:]
>
> idem.

I should have pointed out, of course, that the original definition of  
CDR was correct given the original (incorrect) definition of cons.

B.

-- 
Brendon Towle, PhD
Cognitive Scientist
+1-412-690-2442x127
Carnegie Learning, Inc.
The Cognitive Tutor Company ®
Helping over 375,000 students in 1000 school districts succeed in math.


-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Questions on Using Python to Teach Data Structures and Algorithms

2006-09-28 Thread Brendon Towle
On 28 Sep 2006, at 12:45 PM, [EMAIL PROTECTED] wrote:

> From: "MonkeeSage" <[EMAIL PROTECTED]>
> Subject: Re: Questions on Using Python to Teach Data Structures and
>   Algorithms
> To: python-list@python.org
>
> [snip]
> But Brendon's code also needs a correction: [a].extend(b) is wrong,
> because extend is in-place and returns None, and [a] is anonymous...it
> needs to be something like:
>
> def cons(a, b):
>   b.insert(0, a)
>   return b

Clearly, my Lisp is better than my Python; I stand corrected. (Brings  
back memories of the "Why don't destructive sequence operations  
return the sequence?" thread.)

I think I'd probably prefer:

def cons(a,b):
 res = [a]
 res.extend(b)
 return res

because cons is supposed to leave its second argument untouched.

B.

-- 
Brendon Towle, PhD
Cognitive Scientist
+1-412-690-2442x127
Carnegie Learning, Inc.
The Cognitive Tutor Company ®
Helping over 375,000 students in 1000 school districts succeed in math.


-- 
http://mail.python.org/mailman/listinfo/python-list