How Do I get Know What Attributes/Functions In A Class?

2005-02-19 Thread steven
Hi,

I'm new to python.  Given a class, how can I get know what
attributes/functins in it without dig into the source?

-
narke

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


Re: How Do I get Know What Attributes/Functions In A Class?

2005-02-20 Thread steven
Thank you Hans.   Could you give me a simple sample of using inspect?

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


Re: How Do I get Know What Attributes/Functions In A Class?

2005-02-23 Thread steven
Thank you All !

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


Source Encoding GBK/GB2312

2005-02-23 Thread steven
When I specify an source encoding such as:

# -*- coding: GBK -*-
or
# -*- coding: GB2312 -*-

as the first line of source, I got the following error:

SyntaxError: 'unknown encoding: GBK'


Does this mean Python does not support GBK/GB2312?  What do I do?

-
narke

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


Re: Source Encoding GBK/GB2312

2005-02-25 Thread steven
Thank you All !  I am going to update ...

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


Problem When Unit Testing with PMock

2005-02-26 Thread steven
Hi,

Anyone was using pmock for unit testing with python?  I met a problem
and hope someone to help me.  For short, the pmock seems can not mock a
iterator object.

For example, the tested object is foo, who need to send message to
another object bar.  So, to test the foo, I need mock a mockBar.  But
the bar is a iterator, the foo use the bar in this way:

 foo.method(self, bar):
 for n in bar:
 do somthing
  ...
my purpose is create a mockBar and pass this mock object to
foo.method(), but this ideal simply does not work. Python will complain
that calling on an uniteraterable object.  I'v already set anything
like mockBar.expects(__iter__()) and mockBar.expects(next()).

Does anyone has some clues?

-
narke

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


Re: Problem When Unit Testing with PMock

2005-02-26 Thread steven
> def mockit(): raise StopIteration
> now pass mockit()

but it behaviors differenctly when pass in a mockit()  and pass in an
iterator with empty.  so i think the code emulates nothing.

> def intit(k):
>  for i in range(k): yield i

Now you mean define my own iteration without the help of pmock.   but
there are still so many other methods in the iterator for pass in,  i
have to mock them one by one totally manually, its boring and thats the
reason why i want pmock.

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


Re: Problem When Unit Testing with PMock

2005-02-28 Thread steven
Peter,

for a object foo who need a iterator to do a job,  i write test to make
sure the foo correctlly used the iterator, so a simple empty iterator
is not enough.  because in the case, i need to see if or not the foo
called the iterator to get the proper data from it and do the proper
translating on them.  so, the mock iterator i need should be such an
iterator which can returns be iterated out a lot of test data as i
willed.

i guess you are not familar with unit testing.  we need mock objects
not because they are hard to implemented, we need them to make the
tests easy and fine.

-
narke

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


Hey, How Do I Distribute my New Completed Python Project?

2005-02-28 Thread steven
I'v just completed a small python project, which includes a main py
file and a couple of classes in seperated py files.  I can run it under
the development directory, but how to distribute them?  Is there any
good practice here?

Thanks in advance.

-
narke

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


Re: Problem When Unit Testing with PMock

2005-02-28 Thread steven
Peter,

I'm so sorry, the letter was originally wrote to Terry, not to you!
I guess Terry not very familar to unit testing because he said:

-- cut --
I am not familiar with pmock, but my impression is that mock objects
are
for objects that you may not have available, such as a connection to a
database or file or instance of an umimplemented class ;-).  For such
objects, the mock-ness consists in returning canned rather than actual
fetched or calculated answers.  Iterators, on the other hand, are
almost as
-- end --

and i just want to say, mocking object is a useful testing method , not
was telling a tutorial.  :-)


What you said about the overuse of the generic mock object is very
interesting. I did not think that before.  I believe that use generic
or customized mocks is a problem of balance, so we may call it Art :-)

Below is my code, you may look it to understand my original question
(sorry for the coding for i am totally a python newbie):

---
import unittest

from pmock import *

from mainctr import MainCtr



class MainCtrTest(unittest.TestCase):

def testProcess(self):

filePicker = MockFilePicker()

filePicker.expectedNextCalls = len(MockFilePicker.fns) + 1



rpt0 = "foo"

rpt1 = "bar"

(router0, router1) = (Mock(), Mock())

router0.expects(once()).feedIn(eq(MockFilePicker.fns))

router1.expects(once()).feedIn(eq(MockFilePicker.fns))

router0.expects(once()).deliver()

router1.expects(once()).deliver()


router0.expects(once()).getDeliveredSrcList().will(return_value(["fn0",
"fn2"]))

router1.expects(once()).getDeliveredSrcList().will(return_value([]))


router0.expects(once()).getDeliveryRpt().will(return_value(rpt0))


router1.expects(once()).getDeliveryRpt().will(return_value(rpt1))


routes = [router0, router1]

ctr = MainCtr(filePicker, routes)

ctr.process()

self.assertEquals(ctr.getProcessRpt(), [rpt0, rpt1])

filePicker.verify()

router0.verify()

router1.verify()



class MockFilePicker:

fns = ["f0", "f1", "f2"]

idx = 0

nextCalls = 0

resetCalls = 0

expectedResetCalls = 1

expectedNextCalls = 0

processedSet = set()

expectedProcessedSet = set(["fn0", "fn2"])

rememberProcessedCalls = 0

expectedRememberProcessedCalls = 1



def __iter__(self):

return self



def reset(self):

self.resetCalls += 1


def next(self):

self.nextCalls += 1

if self.idx < len(self.fns):

self.idx += 1

return self.fns[self.idx - 1]

else:

raise StopIteration



def processed(self, fn):

self.processedSet.add(fn)



def rememberProcessed(self):

self.rememberProcessedCalls += 1




def verify(self):

if self.nextCalls != self.expectedNextCalls:

raise Exception("nextCalls: " + str(self.nextCalls))

if self.resetCalls != self.expectedResetCalls:

raise Exception("resetCalls: " + str(self.resetCalls))

if self.processedSet != self.expectedProcessedSet:

 raise Exception("processedSet: " + str(self.processedSet))

if self.rememberProcessedCalls !=
self.expectedRememberProcessedCalls:
raise Exception("rememberProcessedCalls: " +
str(self.rememberProcessedCalls))


if __name__ == "__main__":

unittest.main()

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


Re: Hey, How Do I Distribute my New Completed Python Project?

2005-02-28 Thread steven
Thank You All

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


Met Problem with Distutils

2005-02-28 Thread steven
if i want a main executable py script installed on the /usr/local/bin,
what do i do?  i tried the data_files options in the setup.py, but
nothing happened, no the expected file appeared in the resulted tarbar.

below is the setup.py:

setup(name='foopkg',

  version='1.0',

  author="Steven Woody",

  author_email="[EMAIL PROTECTED]",

  url="http://a.b.c";,

  packages=['foopkg'],

  scripts=['scripts/*.py'],

  data_files=[('/usr/local/bin', ['scripts/myprj.py'])]

  )


can anyone tell me what is wrong?

thanks in advance!

-
narke

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


looking for blocking on read of a real file (not socket or pipe)

2004-12-13 Thread Steven
Hello,
I'm seeking a read method that will block until new data is available. Is
there such a python function that does that?

Thanks,

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


List Splitting

2006-08-21 Thread Steven
Hello everyone,

I'm trying to work through a bit of a logic issue I'm having with a
script I'm writing. Essentially, I have a list that's returned to
me from another command that I need to regroup based on some aribitrary
length.

For the purposes of this question, the list will be:

t = [ "a", "b", "c", "n", "a", "a", "t", "t", "t" ]

Now, I know that every 3rd element of the list belongs together:

Group 1 = 0, 3, 6
Group 2 = 1, 4, 7
Group 3 = 2, 5, 8

I'm trying to sort this list out so that I get a list of lists that
contain the correct elements:

Goal = [ [ "a", "n", "t"], [ "b", "a", "t"],
["c", "a", "t" ] ]

The actual data isn't as simple as this, but if I can get the logic
sorted out, I can handle the other part.

Anyone have any good ideas on how to do this?

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


Re: List splitting

2006-08-21 Thread Steven

Klaus Alexander Seistrup wrote:
> >>> t = [ "a", "b", "c", "n", "a", "a", "t", "t", "t" ]
> >>> [t[i::3] for i in range(3)]
> [['a', 'n', 't'], ['b', 'a', 't'], ['c', 'a', 't']]

Klaus,

Thanks for the fast reply! Had I taken the time to look at the
list-type docs (which I did to understand how you were spliting the
list), I'd probably have seen the slicing with step option. Another
RTFM issue for me.

Thanks again,
Steven

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


Techkicks.com technology links, community driven

2009-04-29 Thread Steven
TechKicks.com is a community based technology site. It specializes in
Hi-Technologies like Robotics, ERP, GPS, Python, Haskell, Lisp, Ruby
On Rails,
and common techs like c#, PHP, Java, Sql and many more. Individual
users of the site submit and review stories, the most popular of which
make it to the homepage. Users are encouraged to 'kick' stories that
they would like to appear on the homepage. If a story receives enough
kicks, it will be promoted.
Individual users of the site submit and review stories, the most
popular of which make it to the homepage. Users are encouraged to
'kick' stories that they would like to appear on the homepage. If a
story receives enough kicks, it will be promoted.

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


Re: Simple question about Queue.Queue and threads

2010-02-08 Thread Steven
On Feb 5, 7:45 am, "Frank Millman"  wrote:
> Hi all
>
> Assume you have a server process running, a pool of worker threads to
> perform tasks, and aQueue.Queue() to pass the tasks to the workers.
>
> In order to shut down the server cleanly, you want to ensure that the
> workers have all finished their tasks. I like the technique of putting a
> None onto thequeue, and have each worker check for None, put None back onto
> thequeue, and terminate itself.
>
> The main program would look something like this -
>
>     q.put(None)
>     for worker in worker_threads:
>         worker.join()
>
> At this point you can be sure that each thread has completed its tasks and
> terminated itself.
>
> However, thequeueis not empty - it still has the final None in it.
>
> Is it advisable to finalise the cleanup like this? -
>
>     while not q.empty():
>         q.get()
>         q.task_done()
>     q.join()
>
> Or is this completely redundant?
>
> Thanks
>
> Frank Millman

Queue objects have support for this signaling baked in with
q.task_done and q.join.

After the server process has put all tasks into the queue, it can join
the queue itself, not the worker threads.

q.join()

This will block until all tasks have been gotten AND completed.  The
worker threads would simply do this:
task_data = q.get()
do_task(task_data)
q.task_done()

Using pairs of get and task_done you no longer need to send a signal.
Just exit the server process and the worker threads will die (assuming
of course, you set .setDaemon(True) before starting each worker
thread).

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


using subprocess.Popen does not suppress terminal window on Windows

2010-06-18 Thread Steven
I am calling a ruby program from a python gui and using
subprocess.Popen in Windows XP using python 2.6.  Unfortunately,
whenever the ruby program is called a blank command window appears on
screen, annoying my users.  Is there a way to suppress this behaviour?

Below is a minimal program that demonstrates the problem.  The problem
does not manifest if the python program is launched via the command
line.  To duplicate launch from Windows Explorer by double-clicking on
the python file.

--- call_double.pyw ---
from subprocess import *
import time

time.sleep(3) # to show that command window is result of call to Popen
p = Popen(['ruby.exe', 'double.rb'], stdin=PIPE, stdout=PIPE,
stderr=PIPE)
results = open('results.txt', 'w')
for n in range(10):
p.stdin.write("%d\n" % n)
result = p.stdout.readline().strip()
results.write('double(%s) => %2s\n' % (n, result))
results.close()

--- end of call_double.pyw ---

--- double.rb ---
while true
puts $stdin.gets().strip!.to_i * 2
STDOUT.flush
end
--- end of double.rb ---

thanks for any help,
Steven Rumbalski
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: The real problem with Python 3 - no business case for conversion (was "I strongly dislike Python 3")

2010-07-06 Thread Steven
On Jul 5, 2:56 am, John Nagle  wrote:
>     The Twisted team has a list of what they need:
>
> "http://stackoverflow.com/questions/172306/how-are-you-planning-on-han...";

Here's what I got from a quick google review of the below four
projects and python 3.
>      * Zope Interface
Here's a blog from a core contributer to Zope, Lennart Regebro
claiming Zope Interface now works with Python 3:
http://regebro.wordpress.com/2010/04/29/zope-interface-3-6-0-released-with-python-3-support/
I have no idea if this is official Zope, but it does indicate strong
progress.

>      * PyCrypto
Couldn't find much.  Found this from an email on Pycrypto mailing
list:
http://lists.dlitz.net/pipermail/pycrypto/2010q2/000244.html
"""
Hi Tobias

 > Does Pycrypto work with Python 3.x now?

To my knowledge PyCrypto doesn't work yet with Python 3.x.
Around 30% of the test cases are still fail. If you want me
to check which of the components are pass, please let me know.

Cheers,
Christoph"""
So someone has been looking at Python 3, but doesn't look like much is
being done.

>      * PyOpenSSL
Couldn't find anything.

>      * PyGTK
This one shows real progress.  There is a bug filed for Python 3
support:
https://bugzilla.gnome.org/show_bug.cgi?id=566641
Key comment on that bug:
"""John Ehresman   [developer]  2010-04-17 16:02:43 UTC

I just pushed to the py3k branch a couple of fixes to bugs that are
independent
of the changes for python3 so all tests pass under both python 2.5 and
python3.1.  It's probably time to think about landing this on the
master
branch; obviously we want to avoid regressions in python2 support.
What needs
to be done before this lands on master?"""
A couple of comments follow about when to merge Python 3 support.  So
it looks like they are almost there.

Conclusion:  2 of 4 dependencies that Twisted needs to port to Python
3 show strong progress towards completing the port.

Steven Rumbalski

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


Re: Why do Perl programmers make more money than Python programmers

2013-05-07 Thread Steven D'Aprano
On Tue, 07 May 2013 15:17:52 +0100, Steve Simmons wrote:

> Good to see jmf finally comparing apples with apples :-)

*groans*

Truly the terrible pun that the terrible hijacking deserves.



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


Re: Making safe file names

2013-05-07 Thread Steven D'Aprano
On Tue, 07 May 2013 19:51:24 -0500, Andrew Berg wrote:

> On 2013.05.07 19:14, Dave Angel wrote:
>> You also need to decide how to handle Unicode characters, since they're
>> different for different OS.  In Windows on NTFS, filenames are in
>> Unicode, while on Unix, filenames are bytes.  So on one of those, you
>> will be encoding/decoding if your code is to be mostly portable.
>
> Characters outside whatever sys.getfilesystemencoding() returns won't be
> allowed. If the user's locale settings don't support Unicode, my program
> will be far from the only one to have issues with it. Any problem
> reports that arise from a user moving between legacy encodings will
> generally be ignored. I haven't yet decided how I will handle artist
> names with characters outside UTF-8, but inside UTF-16/32 (UTF-16 is
> just fine on Windows/NTFS, but on Unix(-ish) systems, many use UTF-8 in
> their locale settings).

There aren't any characters outside of UTF-8 :-) UTF-8 covers the entire 
Unicode range, unlike other encodings like Latin-1 or ASCII.

Well, that is to say, there may be characters that are not (yet) handled 
at all by Unicode, but there are no known legacy encodings that support 
such characters.

To a first approximation, Unicode covers the entire set of characters in 
human use, and for those which it does not, there is always the private 
use area. So for example, if you wish to record the Artist Formerly Known 
As "The Artist Formerly Known As Prince" as Love Symbol, you could pick 
an arbitrary private use code point, declare that for your application 
that code point means Love Symbol, and use that code point as the artist 
name. You could even come up with a custom font that includes a rendition 
of that character glyph.

However, there are byte combinations which are not valid UTF-8, which is 
a different story. If you're receiving bytes from (say) a file name, they 
may not necessarily make up a valid UTF-8 string. But this is not an 
issue if you are receiving data from something guaranteed to be valid 
UTF-8.


>> Don't forget that ls and rm may not use the same encoding you're using.
>> So you may not consider it adequate to make the names legal, but you
>> may also want they easily typeable in the shell.
>
> I don't understand. I have no intention of changing Unicode characters.

Of course you do. You even talk below about Unicode characters like * 
and ? not being allowed on NTFS systems.

Perhaps you are thinking that there are a bunch of characters over here 
called "plain text ASCII characters", and a *different* bunch of 
characters with funny accents and stuff called "Unicode characters". If 
so, then you are labouring under a misapprehension, and you should start 
off by reading this:

http://www.joelonsoftware.com/articles/Unicode.html


then come back with any questions.


> This is not a Unicode issue since (modern) file systems will happily
> accept it. The issue is that certain characters (which are ASCII) are
> not allowed on some file systems:
>  \ / : * ? " < > | @ and the NUL character

These are all Unicode characters too. Unicode is a subset of ASCII, so 
anything which is ASCII is also Unicode.


> The first 9 are not allowed on NTFS, the @ is not allowed on ext3cow,
> and NUL and / are not allowed on pretty much any file system. Locale
> settings and encodings aside, these 11 characters will need to be
> escaped.

If you have an artist with control characters in their name, like newline 
or carriage return or NUL, I think it is fair to just drop the control 
characters and then give the artist a thorough thrashing with a halibut.

Does your mapping really need to be guaranteed reversible? If you have an 
artist called "JoeBlow", and another artist called "Joe\0Blow", and a 
third called "Joe\nBlow", does it *really* matter if your application 
conflates them?


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


Re: Making safe file names

2013-05-07 Thread Steven D'Aprano
On Wed, 08 May 2013 00:13:20 -0400, Dave Angel wrote:

> On 05/07/2013 11:40 PM, Steven D'Aprano wrote:
>>
>>
>>
>> These are all Unicode characters too. Unicode is a subset of ASCII, so
>> anything which is ASCII is also Unicode.
>>
>>
>>
> Typo.  You meant  Unicode is a superset of ASCII.

Damn. Yes, you're right. I was thinking superset, but my fingers typed 
subset.

Thanks for the correction.


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


object.enable() anti-pattern

2013-05-08 Thread Steven D'Aprano
I'm looking for some help in finding a term, it's not Python-specific but 
does apply to some Python code.

This is an anti-pattern to avoid. The idea is that creating a resource 
ought to be the same as "turning it on", or enabling it, or similar. For 
example, we don't do this in Python:


f = file("some_file.txt")
f.open()
data = f.read()


because reading the file can fail if you forget to call open first. 
Instead, Python uses a factory function that creates the file object and 
opens it:

f = open("some_file.txt")  # if this succeeds, f is ready to use
data = f.read()


Basically, any time you have two steps required for using an object, e.g. 
like this:

obj = someobject(arg1, arg2)
obj.enable()

you should move the make-it-work functionality out of the enable method 
and into __init__ so that creating the object creates it in a state ready 
to work.

I read a blog some time ago (a year ago?) that discusses this anti-
pattern, and I'm pretty sure gave it a specific name, but I cannot find 
it again. Can anyone find any references to this anti-pattern? My google-
fu is letting me down.



(For what it's worth, I'm refactoring some of my own code that falls into 
this anti-pattern. Die, enable method, die die die!)


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


Re: object.enable() anti-pattern

2013-05-08 Thread Steven D'Aprano
On Wed, 08 May 2013 11:13:33 +0100, Robert Kern wrote:

> On 2013-05-08 09:52, Steven D'Aprano wrote:
>> I'm looking for some help in finding a term, it's not Python-specific
>> but does apply to some Python code.
>>
>> This is an anti-pattern to avoid. The idea is that creating a resource
>> ought to be the same as "turning it on", or enabling it, or similar.
> 
> I don't think the anti-pattern has a name, but it's opposite pattern is
> named:
> 
> http://en.wikipedia.org/wiki/Resource_Acquisition_Is_Initialization

That sounds like it should be related, but it actually isn't since RAII 
actually has little to do with *acquiring* the resource and everything to 
do with *releasing* it. See, for example:

http://stackoverflow.com/questions/2321511/what-is-meant-by-resource-
acquisition-is-initialization-raii

where it is pointed out that the resource may be acquired outside of the 
object constructor and passed in as an argument. RAII is actually about 
deterministic destruction of objects and the release of their resources.

But thanks for the attempt :-)


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


Re: Style question -- plural of class name?

2013-05-08 Thread Steven D'Aprano
On Wed, 08 May 2013 16:20:48 -0400, Roy Smith wrote:

> FooEntry is a class.  How would you describe a list of these in a
> docstring?


Which language are you writing your docstrings in? Obey the normal rules 
of spelling, grammar and punctuation for your language, which I assume is 
English.


> "A list of FooEntries"

Perfectly acceptable.


> "A list of FooEntrys"

There is no standard variant or dialect of English (British English, 
American English, etc.) that pluralises Entry as Entrys, so that would be 
"absolutely not".


> "A list of FooEntry's"

"Here come's an S! Quick, jam on an apostrophe!"

This is called the grocer's apostrophe, and is universally held in 
contempt no matter what variant of English you write in. Don't do this.

The only acceptable use of an apostrophe to make a plural is if the thing 
being pluralised is a single letter. E.g. one a, two a's.

 
> "A list of FooEntry instances"

This is also acceptable, although a little wordy. Do you write "a list of 
strings" or "a list of str instances"?


> The first one certainly sounds the best, but it seems wierd to change
> the spelling of the class name to make it plural.

No weirder (note spelling) than changing any other noun. Whether you 
change "int" to "ints" or FooEntry" to "FooEntries", you're still 
changing it. That's how you make it plural.


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


Re: Style question -- plural of class name?

2013-05-08 Thread Steven D'Aprano
On Wed, 08 May 2013 15:33:07 -0500, Skip Montanaro wrote:

> This one:
> 
>> "A list of FooEntry instances"
> 
> Besides the obvious spelling issues in the others, it's not immediately
> clear if the list contains just FooEntry instances, FooEntry classes
> (perhaps subclasses) or a mix of the two.  #4 makes it clear.


I don't think this is a real issue. There isn't normally any ambiguity 
between instances and subclasses. When you read "a list of ints", do you 
assume that the list looks like [int, MyInt, AnotherInt, FooInt] or do 
you expect it to look like [2, 7, 6, 1]?

The normal interpretation of "one or more Foo" is that we're talking 
about Foo *instances*, not subclasses of Foo. If that is not that case, 
then the onus is on the author of the documentation to make it clear that 
they are talking about subclasses.


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


Re: Making safe file names

2013-05-08 Thread Steven D'Aprano
On Wed, 08 May 2013 20:16:25 -0400, Roy Smith wrote:

> Yup.  At Songza, we deal with this crap every day.  It usually bites us
> the worst when trying to do keyword searches.  When somebody types in
> "Blue Oyster Cult", they really mean "Blue Oyster Cult", 

Surely they really mean Blue Öyster Cult.


> and our search
> results need to reflect that.  Likewise for Ke$ha, Beyonce, and I don't
> even want to think about the artist formerly known as an unpronounceable
> glyph.

Dropped or incorrect accents are no different from any other misspelling, 
and good search engines (whether online or in a desktop application) 
should be able to deal with a tolerable number of misspellings.

Googling for "Blue Oyster Cult" brings up four of the top ten hits 
spelled correctly with the accent, "Blue Öyster Cult". Even misspelled as 
"blew oytser cult", Google does the right thing.

Even Bing manages to find Ke$ha's wikipedia page, her official website, 
youtube channel, facebook and myspace pages from the misspelling "kehsha".



> Pro-tip, guys.  If you want to form a band, and expect people to be able
> to find your stuff in a search engine some day, don't play cute with
> your name.

Googling for "the the" (including quotes) brings up 145 million hits, 
nine of the first ten hits being relevant to the band. 

On the other hand, I wouldn't want to be in a band called "The Beetles".


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


Re: Making safe file names

2013-05-08 Thread Steven D'Aprano
On Wed, 08 May 2013 21:11:28 -0500, Andrew Berg wrote:

> It's a thing (especially in witch house) to make names with odd glyphs
> in order to be harder to find and be more "underground". Very silly. Try
> doing searches for these artists with names like these:

Challenge accepted.

> http://www.last.fm/music/%E2%96%BC%E2%96%A1%E2%96%A0%E2%96%A1%E2%96%A0%
E2%96%A1%E2%96%A0
> http://www.last.fm/music/ki%E2%80%A0%E2%80%A0y+c%E2%96%B2t


The second one is trivial. Googling for "kitty cat" "witch 
house" (including quotes) gives at least 3 relevant links out of the top 
4 hits are relevant. (I'm not sure about the Youtube page.) That gets you 
the correct spelling, "ki††y c△t", and googling for that brings up many 
more hits.

The first one is a tad trickier, since googling for "▼□■□■□■" brings up 
nothing at all, and "mourning star" doesn't give any relevant hits on the 
first page. But "mourning star" "witch house" (inc. quotes) is successful.

I suspect that the only way to be completely ungoogleable would be to 
name yourself something common, not something obscure. Say, if you called 
yourself "Hard Rock Band", and did hard rock. But then, googling for 
"Heavy Metal" alone brings up the magazine as the fourth hit, so if you 
get famous enough, even that won't work.



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


Re: object.enable() anti-pattern

2013-05-08 Thread Steven D'Aprano
On Wed, 08 May 2013 14:27:53 +, Duncan Booth wrote:

> Steven D'Aprano  wrote:
> 
>> I'm looking for some help in finding a term, it's not Python-specific
>> but does apply to some Python code.
>> 
>> This is an anti-pattern to avoid. The idea is that creating a resource
>> ought to be the same as "turning it on", or enabling it, or similar
> 
> I've come across this under the name 'two-phase construction', but as a
> desirable(!?) pattern rathern than as an anti-pattern.
> 
> In particular Symbian used it throughout as originally their C++
> implementation didn't support exceptions. Instead they had a separate
> cleanup stack and objects that require cleanup were pushed onto that
> stack after being fully constructed but before calling the
> initialisation that required cleanup. See
> http://www.developer.nokia.com/Community/Wiki/Two-phase_construction



Thanks for the link. It's obviously not the blog post I was looking for, 
but it is interesting.



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


Re: object.enable() anti-pattern

2013-05-08 Thread Steven D'Aprano
On Thu, 09 May 2013 02:42:01 +, Dan Sommers wrote:

> On Wed, 08 May 2013 08:52:12 +0000, Steven D'Aprano wrote:
> 
>> This is an anti-pattern to avoid. The idea is that creating a resource
>> ought to be the same as "turning it on", or enabling it, or similar.
>> For example, we don't do this in Python:
>> 
>> f = file("some_file.txt")
>> f.open()
>> data = f.read()
> 
> So why don't we do this?
> 
> data = read("some_file.txt")

Because there is a lot more that you might want to do to a file than just 
read from it.

py> f = open('/tmp/x')
py> dir(f)
['_CHUNK_SIZE', '__class__', '__delattr__', '__dict__', '__dir__', 
'__doc__', '__enter__', '__eq__', '__exit__', '__format__', '__ge__', 
'__getattribute__', '__getstate__', '__gt__', '__hash__', '__init__', 
'__iter__', '__le__', '__lt__', '__ne__', '__new__', '__next__', 
'__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', 
'__str__', '__subclasshook__', '_checkClosed', '_checkReadable', 
'_checkSeekable', '_checkWritable', 'buffer', 'close', 'closed', 
'detach', 'encoding', 'errors', 'fileno', 'flush', 'isatty', 
'line_buffering', 'mode', 'name', 'newlines', 'read', 'readable', 
'readline', 'readlines', 'seek', 'seekable', 'tell', 'truncate', 
'writable', 'write', 'writelines']


That's 24 public methods and attributes, excluding private and dunder 
attributes.

There is no sensible use-case for creating a file without opening it. 
What would be the point? Any subsequent calls to just about any method 
will fail. Since you have to open the file after creating the file object 
anyway, why make them two different calls?

Besides, this is not to denigrate the idea of a read() function that 
takes a filename and returns its contents. But that is not an object 
constructor. It may construct a file object internally, but it doesn't 
return the file object, so it is completely unrelated to the scenario I 
described.



>> because reading the file can fail if you forget to call open first.
>> Instead, Python uses a factory function that creates the file object
>> and opens it:
>> 
>> f = open("some_file.txt")  # if this succeeds, f is ready to use 
>> data = f.read()
> 
> That's just the "enable" paradigm in a socially acceptable and
> traditional wrapper.

Well duh. That's like saying that for loops, while loops and co-routines 
are just GOTO in a socially acceptable and traditional wrapper. Of course 
they are. That's the whole point.



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


Re: object.enable() anti-pattern

2013-05-08 Thread Steven D'Aprano
On Thu, 09 May 2013 02:38:36 +, Dan Sommers wrote:

> Think of spinning off a thread:  initialize it synchronously, and then
> let it execute asynchronously.  We tend towards that pattern even when
> we know that execution will be synchronous, because we also that it
> could be asynchronous one day.

Whether it is synchronous or asynchronous is irrelevant.

I can see use-cases for separating "make it go" from initialisation. It 
all depends on what you might want to do to the object before making it 
go. If the answer is "Nothing", then there is no reason not to have the 
constructor make it go. If the answer is, "Well, sometimes we need to do 
things to the object before making it go", then it makes sense to 
separate the two:

blob = MyBlob(arg1, arg2, agr3)
blob.poke("with a stick")
blob.append(data)
blob.foo = "spam"
blob.make_it_go()


I'm not talking about this case. I'm talking about the case where there's 
nothing you can do with the blob before making it go.


> Yes, we could wrap that up in a neat
> bundle, but explicit is better than implicit.

"And that is why we always write code like this:

n = int(int(len(something)) + int(1))

just to be sure that the result is explicitly an int and not just 
implicitly an int. Suppose some Javascript programmer was reading the 
code, and they thought that 1 was a floating point value. That would be 
bad!"


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


Re: Message passing syntax for objects | OOPv2

2013-05-08 Thread Steven D'Aprano
On Wed, 08 May 2013 19:35:58 -0700, Mark Janssen wrote:

> Long story short: the lambda
> calculus folks have to split from the Turing machine folks.
>  These models of computation should not use the same language.  Their
> computation models are too radically different.  

Their computation models are exactly equivalent.

This is like saying that Cartesian coordinates and polar coordinates are 
so radically different that they cannot possibly both describe the same 
space.


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


Re: Append to python List

2013-05-09 Thread Steven D'Aprano
On Thu, 09 May 2013 01:18:51 -0700, RAHUL RAJ wrote:

> Then what about this code part?


What about it? 


> [(x, y) for x in [1,2,3] for y in [3,1,4] if x != y]
> 
> and the following code part:
> 
> for x in [1,2,3]:
>   for y in [3,1,4]:
> if x != y:
>   combs.append((x, y))

Apart from not defined combs, those two pieces of code are equivalent.

So what is your question?


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


Re: object.enable() anti-pattern

2013-05-09 Thread Steven D'Aprano
On Thu, 09 May 2013 18:23:31 +1000, Cameron Simpson wrote:

> On 09May2013 19:54, Greg Ewing  wrote:
> | Steven D'Aprano wrote:
> | > There is no sensible use-case for creating a file WITHOUT OPENING
> | > it. What would be the point?
> |
> | Early unix systems often used this as a form of locking.
> 
> Not just early systems: it's a nice lightweight method of making a
> lockfile even today if you expect to work over NFS, where not that many
> things are synchronous. You OPEN A FILE with "0" modes

[emphasis added]

This is all very well and good, but for the life of me, I cannot see how 
opening a file is a good example of not opening a file. Perhaps it is a 
Zen thing, like the sound no spoon makes when you don't tap it against a 
glass that isn't there.


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


Re: object.enable() anti-pattern

2013-05-09 Thread Steven D'Aprano
On Thu, 09 May 2013 06:08:25 -0500, Wayne Werner wrote:

> Ah, that's it - the problem is that it introduces /Temporal Coupling/ to
> one's code: http://blog.ploeh.dk/2011/05/24/DesignSmellTemporalCoupling/

Good catch!

That's not the blog post I read, but that's the same concept. "Temporal 
Coupling" -- yes, that is an excellent description of the problem.


> You don't ever want a class that has functions that need to be called in
> a certain order to *not* crash. That's fine if you have to call them in
> a certain sequence in order to get the correct data - that's what
> programming is all about, after all. But if you provide me a class with
> a constructor you better make sure that when I do this:
> 
>  thing = YourSuperAwesomeClass()
>  thing.do_stuff()
> 
> that I don't get some horrid stack trace ending with
> 
>  InvalidStateError: initialize() needs to be called before
>  do_stuff()
> 
> Or something worse.

Exactly.


Thank you Wayne, that's a great help.



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


Re: object.enable() anti-pattern

2013-05-09 Thread Steven D'Aprano
On Thu, 09 May 2013 09:07:42 -0400, Roy Smith wrote:

> In article <518b32ef$0$11120$c3e8...@news.astraweb.com>,
>  Steven D'Aprano  wrote:
>  
>> There is no sensible use-case for creating a file without opening it.
> 
> Sure there is.  Sometimes just creating the name in the file system is
> all you want to do.  That's why, for example, the unix "touch" command
> exists.

Since I neglected to make it clear above that I was still talking about 
file objects, rather than files on disk, I take responsibility for this 
misunderstanding. I thought that since I kept talking about file 
*objects* and *constructors*, people would understand that I was talking 
about in-memory objects rather than on-disk files. Mea culpa.

So, let me rephrase that sentence, and hopefully clear up any further 
misunderstandings.

There is no sensible use-case for creating a file OBJECT unless it 
initially wraps an open file pointer.

This principle doesn't just apply to OOP languages. The standard C I/O 
library doesn't support creating a file descriptor unless it is a file 
descriptor to an open file. open() has the semantics:

"It shall create an open file description that refers to a file and a 
file descriptor that refers to that open file description."

http://pubs.opengroup.org/onlinepubs/9699919799/functions/open.html

and there is no corresponding function to create a *closed* file 
description. (Because such a thing would be pointless.)

Of course language designers are free to design their language to work 
under whatever anti-patterns they desire. I quote from the Pascal 
Language Reference:

"open associates the permanent file file [sic] with a file variable for 
reading or writing. open does not actually open the file; you must call 
reset or rewrite before reading or writing to that file."

http://www.amath.unc.edu/sysadmin/DOC4.0/pascal/lang_ref/
ref_builtin.doc.html


but since that's not a part of standard Pascal, other Pascals may behave 
differently.



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


Re: object.enable() anti-pattern

2013-05-09 Thread Steven D'Aprano
On Thu, 09 May 2013 19:34:25 +0100, MRAB wrote:

>> There is no sensible use-case for creating a file OBJECT unless it
>> initially wraps an open file pointer.
>>
> You might want to do this:
> 
> f = File(path)
> if f.exists():
>  ...
> 
> This would be an alternative to:
> 
> if os.path.exists(path):
>  ...

Sure, but your made-up File object does not represent a file, it 
represents a pathname which *may or may not* exist. Pathnames are not 
files. Not all files have a pathname that refers to them, and not all 
pathnames point to an actual file. Since it has an exists() method that 
can return False, there are so-called "File" objects that aren't files 
and the name is a misnomer. A much better name for the class would be 
"Path", not "File".

I'm not saying that there is never a use-case for some objects to have an 
"enable" or "start" or "open" method. That would clearly be a silly thing 
to say. In the real world, we design many objects to have a start switch. 
It would be pretty horrible if your car was running all the time. But 
that's because there are actual use-cases for having cars *not* run, and 
"make it stop" is the safe default behaviour.

Your fridge, on the other hand, doesn't have a "make it go" button. So 
long as power is applied to it, your fridge automatically runs. Likewise, 
your watch is an "always on" device, provided it hasn't wound down or 
have a flat battery. Your fire alarm is "always on". 

I must admit I am astonished at how controversial the opinion "if your 
object is useless until you call 'start', you should automatically call 
'start' when the object is created" has turned out to be.



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


Re: object.enable() anti-pattern

2013-05-09 Thread Steven D'Aprano
On Thu, 09 May 2013 23:09:55 -0400, Roy Smith wrote:

> In article <518c5bbc$0$29997$c3e8da3$54964...@news.astraweb.com>,
>  Steven D'Aprano  wrote:
> 
>> I must admit I am astonished at how controversial the opinion "if your
>> object is useless until you call 'start', you should automatically call
>> 'start' when the object is created" has turned out to be.
> 
> I'm sorry.  I thought you were here for an argument.

No, I'm here for the abuse.


> I think where things went pear shaped is when you made the statement:
> 
>>> There is no sensible use-case for creating a file OBJECT unless it
>>> initially wraps an open file pointer.
> 
> That's a pretty absolute point of view.  Life is rarely so absolute.

So far the only counter-examples given aren't counter-examples. One 
involves opening the file. The other involves something which isn't a 
file, but a string instead. If there are any counter-examples, they are 
impossible in Python and C: you cannot create a file object in Python 
without opening it, and you cannot create a file descriptor in C without 
opening it. But not in Pascal, which actually supports my claim that this 
is an anti-pattern: while some Pascal implementations do allow you to 
create a non-open file, you cannot do *anything* with it until you open 
it, except generate bugs.



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


Re: object.enable() anti-pattern

2013-05-09 Thread Steven D'Aprano
On Fri, 10 May 2013 09:36:43 +1000, Cameron Simpson wrote:

> On 09May2013 11:30, Steven D'Aprano
>  wrote: 
> | On Thu, 09 May 2013 18:23:31 +1000, Cameron Simpson wrote: 
> |
> | > On 09May2013 19:54, Greg Ewing  wrote:
> | > | Steven D'Aprano wrote:
> | > | > There is no sensible use-case for creating a file WITHOUT
> | > | > OPENING it. What would be the point?
> | > |
> | > | Early unix systems often used this as a form of locking. 
> | >
> | > Not just early systems: it's a nice lightweight method of making a
> | > lockfile even today if you expect to work over NFS, where not that
> | > many things are synchronous. You OPEN A FILE with "0" modes 
> | [emphasis added]
>
> | This is all very well and good, but for the life of me, I cannot see
> | how opening a file is a good example of not opening a file. Perhaps it
> | is a Zen thing, like the sound no spoon makes when you don't tap it
> | against a glass that isn't there.
> 
> Because a file usually does not exist in isolation (yes sometimes we
> want an isolated file). Files usually exist in the filesystem, which is
> a namespace. And this is effectively a namespace operation, not a data
> storage operation.
>
> Of course, I can take this the other way: just because I opened it with
> a 0 mode field doesn't mean _I_, the opener, cannot read/write it. I've
> got an open file handle... A race free way to make a scratch file in a
> shared area, for example.


But you are opening the file. Therefore, it cannot possibly be an example 
of not opening the file.

Unlike Pascal, there is no way to create a C file descriptor in a closed 
state. Such a thing does not exist. If you have a file descriptor, the 
file is open. Once you close it, the file descriptor is no longer valid.

But even if C allowed you to do so, doesn't mean that it is a good idea. 
At least some variants of Pascal force you to do the following:

# Pseudo-code.
f = open(filename)
really_open(f)
data = read(f)  # or write, or *any other operation at all*

Surely we can agree that having to call both open() and really_open() 
before you get an actually opened file that you can use is one call too 
many? There is *nothing* you can do with f before calling really_open(). 
So why require it?

(For the record, "really_open" is spelled "reset" or "rewrite" depending 
on whether you want to read or write to the file.)


> The point is probably that a file isn't merely a feature free byte
> storage container; in the real world they usually come with all sorts of
> features like names and permissions. Those features will always imply
> creative uses.

There are at least three related but separate things here.

* file objects, or their low-level equivalent, file descriptors;

* pathnames;

* files on disk, which are an abstraction for data in a particular kind 
of data structure.

They are obviously related, but they are also obviously independent. You 
can have a pathname that doesn't refer to any file on disk; you can have 
a file on disk that has been lost, and therefore is no longer accessible 
via a file name. (If you run fsck or equivalent, the file may be 
recoverable, but the name will be lost.) You can open a file object, then 
unlink it so it no longer points to a file on disk, but does still accept 
read or write calls.

The counter-examples given so far apply to pathnames or files on disk. 
They don't apply to file objects and file descriptors. I have tried 
really hard to be clear that I am talking about file objects. To the 
extent that I have failed, I am sorry.


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


Re: object.enable() anti-pattern

2013-05-10 Thread Steven D'Aprano
On Fri, 10 May 2013 01:50:09 -0400, Roy Smith wrote:

> In article <518c7f05$0$29997$c3e8da3$54964...@news.astraweb.com>,
>  Steven D'Aprano  wrote:
> 
>> there is no way to create a C file descriptor in a closed state. Such a
>> thing does not exist. If you have a file descriptor, the file is open.
>> Once you close it, the file descriptor is no longer valid.
> 
> Of course there is.
> 
> int fd = 37;
> 
> I've just created a file descriptor.  There is not enough information
> given to know if it corresponds to an open file or not.

No, you haven't created a file descriptor. You've made up a number which 
C will allow you to use as an index into the file descriptor table, 
because C is a high-level assembler with very little in the way of type 
safety, and what little there is you can normally bypass. What you 
haven't done is create the record in the file descriptor table. You can't 
expect that read(fd) or write(fd) will work, although both should fail 
safe rather than segfault if 37 happens to not be an actual file 
descriptor.

What you've done is the moral equivalent of choosing an integer at 
random, coercing it to a pointer, then dereferencing it to peek or poke 
at some memory address. (Although fortunately much safer.)

It's a nice hack, but not one that takes away from what I'm saying.


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


Re: object.enable() anti-pattern

2013-05-10 Thread Steven D'Aprano
On Fri, 10 May 2013 06:22:31 +, Dan Sommers wrote:

> On Fri, 10 May 2013 05:03:10 +0000, Steven D'Aprano wrote:
> 
>>>>> There is no sensible use-case for creating a file OBJECT unless it
>>>>> initially wraps an open file pointer.
> 
>> So far the only counter-examples given aren't counter-examples ...
> 
> Well, sure, if you discount operations like "create this file" and
> queries like "could I delete this file if I wanted to?" [0] as methods
> of the file system rather than of a hypothetical file object.
> 
> What about a distributed system?  Suppose I want to create a file object
> in one place, and send that object to the another place for the file to
> be read from or written to [1]?  Suppose that for security reasons, I
> have to do it that way, because the first place can only create the
> objects, and the second place can only access the underly file contents
> through an existing object?

Unless you have re-implemented the file I/O system, it doesn't matter. If 
your file objects are based on C I/O, then even if the first server 
cannot read or write to the files it still creates file objects in an 
open state, because that is how C works.

Or maybe the first server only creates some sort of proxy to the real 
underlying file object. Or maybe you're re-implemented the I/O system, 
and aren't following C's design. Since you're just making this up as a 
thought experiment, anything is possible.

But either way, that's fine. You've found an object where it does make 
sense to have an explicit "make it go" method: first one entity has 
permission to construct the object, but not to open the underlying file. 
Another entity has permission to open the underlying file, but not to 
create the object. I have no idea whether this is a reasonable security 
design or not, it actually sounds a bit rubbish to me but what do I know? 
So let's treat it as a reasonable design. 

As I've said, repeatedly, that's not what I'm talking about.

When you DON'T have useful things that can be done with the object before 
calling "enable", then it is an anti-pattern to require a separate call 
to "enable" method, and the enable functionality should be moved into the 
object constructor. If you DO have useful things that can be done, like 
pass the object to another entity, for security, then that's a whole 
'nuther story.

Really, what I'm describing is *normal* behaviour for most objects. We 
don't usually design APIs like this:

n = int("42")
n.enable()
m = n + 1
m.enable()
x = m*2 + n*3
print x - 1  # oops, raises because I forgot to call x.enable()

That's a rubbish API, and for simple data-like objects, we all agree it 
is a rubbish API. So why accept the same rubbish API just because the 
object is more complicated? If you don't have a good, reasonable, non-
contrived use-case for a separate "make it go" method, don't use one.


For my next controversial opinion, I'm going to argue that we should do 
arithmetic using numbers rather than by inserting lists inside other 
lists:

# Do this:

count = 0
count += 1

# Not this:

count = []
count.insert(0, [])


*wink*


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


Re: Unicode humor

2013-05-11 Thread Steven D'Aprano
On Sat, 11 May 2013 01:16:36 +1000, Chris Angelico wrote:

> On Sat, May 11, 2013 at 1:06 AM, jmfauth  wrote:
>> On 8 mai, 15:19, Roy Smith  wrote:
>>> Apropos to any of the myriad unicode threads that have been going on
>>> recently:
>>>
>>> http://xkcd.com/1209/
>>
>> --
>>
>>
>> This reflects a lack of understanding of Unicode.
> 
> By the skywriter, or by the two on the ground, or by Randall Munroe?

Obviously by all three. It takes *hours* to execute

'è'*1000.replace('è', 'ã')

using a skywriting plane, so obviously it isn't Unicode compliant.



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


Re: object.enable() anti-pattern

2013-05-11 Thread Steven D'Aprano
On Fri, 10 May 2013 17:59:26 +0100, Nobody wrote:

> On Thu, 09 May 2013 05:23:59 +0000, Steven D'Aprano wrote:
> 
>> There is no sensible use-case for creating a file without opening it.
>> What would be the point? Any subsequent calls to just about any method
>> will fail. Since you have to open the file after creating the file
>> object anyway, why make them two different calls?
> 
> As a counterpoint, some OSes (e.g. Plan 9) allow you to get a "handle"
> to a file without opening it. This can then be used for deleting,
> renaming or stat()-type operations without either the risk of race
> conditions (if another process renames files between operations, the
> operations may be performed on different files) or the side-effects of
> actually opening the file (particularly for device files, e.g. opening a
> tape drive may rewind the tape).

Ah, now that's a fantastic counter-example. But I think that says more 
about the primitiveness of the Unix file model than of the idea of 
temporal coupling.


> Python's file model doesn't allow for this, so there isn't really
> anything meaningful that you can do on a file object which isn't open
> (although these actually exist; any file object on which the .close()
> method has been called will be in this state).

Absolutely correct, and I'm amazed it's taken this long for anyone to 
point this out :-)



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


Re: object.enable() anti-pattern

2013-05-11 Thread Steven D'Aprano
On Fri, 10 May 2013 18:20:34 +0100, Robert Kern wrote:

> According to Steven's criteria, neither of these are instances of the
> anti-pattern because there are good reasons they are this way. He is
> reducing the anti-pattern to just those cases where there is no reason
> for doing so. 

But isn't that the case for all anti-patterns?

We agree that GOTO is an anti-pattern. That doesn't mean that there 
aren't valid reasons for using GOTO. Sometimes there are good use-cases 
for GOTO that outweigh the harm. By calling it an anti-pattern, though, 
we shift the onus onto the person wanting to use GOTO: justify why you 
need it, or use something else.

Would you object less if I called it a "code smell" than an "anti-
pattern"? If so, I accept your criticism, and call it a code smell: the 
less temporal coupling your API has, the better.


> That is why I asked for in-the-wild instances. 

How about this?

http://legacy.thecodewhisperer.com/post/366626867/improving-clarity-by-removing-temporal-coupling


Another example of temporal coupling is json_decode in PHP: you must 
follow it by a call to json_last_error, otherwise you have no way of 
telling whether the json_decode function succeeded or not.

http://php.net/manual/en/function.json-last-error.php


> I should
> have qualified my sentence to include "according to your criteria"
> because people seem to be answering my query out of that context.

Now you know how I feel :-)

I started this thread asking for help tracking down a blog post 
describing this code smell, or at least the name of such. Thanks again to 
Wayne Werner, who came through with the name of the anti-pattern, 
temporal coupling, and a blog post describing it, although not the one I 
read all those many moons ago.

I never intended to give the impression that *any* use of a separate 
"enable" method call was bad. I certainly didn't intend to be bogged 
down into a long discussion about the minutia of file descriptors in 
C, but it was educational :-)



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


Re: Python for philosophers

2013-05-11 Thread Steven D'Aprano
On Sat, 11 May 2013 21:45:12 -0700, rusi wrote:

> I have on occasion expressed that newcomers to this list should be
> treated with more gentleness than others. And since my own joking may be
> taken amiss, let me hasten to add (to the OP -- Citizen Kant)

A noble aim, but I have a feeling that "Citizen Kant" is version 2.0 of 
8 Dihedral.

Of course, I could be wrong.


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


Re: Python for philosophers

2013-05-12 Thread Steven D'Aprano
On Sun, 12 May 2013 16:17:02 +0200, Citizen Kant wrote:

> Any clue about this would be highly appreciated.

If you are interested in the intersection of programming and philosophy, 
I strongly recommend that you read "Gödel, Escher, Bach: An Eternal 
Golden Braid" by Douglas R. Hofstadter.



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


Re: Python for philosophers

2013-05-12 Thread Steven D'Aprano
On Sun, 12 May 2013 04:15:30 -0400, Devin Jeanpierre wrote:

> On Sun, May 12, 2013 at 1:17 AM, Steven D'Aprano
>  wrote:
>> On Sat, 11 May 2013 21:45:12 -0700, rusi wrote:
>>
>>> I have on occasion expressed that newcomers to this list should be
>>> treated with more gentleness than others. And since my own joking may
>>> be taken amiss, let me hasten to add (to the OP -- Citizen Kant)
>>
>> A noble aim, but I have a feeling that "Citizen Kant" is version 2.0 of
>> 8 Dihedral.
>>
>> Of course, I could be wrong.
> 
> Without benefit of the doubt, kindness is impossible.

That is a logical non sequitor. One can choose to be kind to someone even 
if you have no doubt that they do not deserve it.

Besides, kindness is hard to define. Is it kinder to give somebody what 
they want, or what they need?

> I would suggest giving newcomers at least that much.

I'm happy to say that, based on Citizen Kant's second post, I'm now 
reasonably confident that (s)he is not a bot. No mere artificial 
intelligence could have written that second post.



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


Re: Python for philosophers

2013-05-12 Thread Steven D'Aprano
On Sat, 11 May 2013 22:03:15 +0200, Citizen Kant wrote:

> Hi,
> this could be seen as an extravagant subject but that is not my original
> purpose. I still don't know if I want to become a programmer or not. At
> this moment I'm just inspecting the environment.

Towards what purpose?

Do you want to learn to program? If not, then why do you care about 
Python programming? What do you aim to get out of this exercise?


> I'm making my way to
> Python (and OOP in general) from a philosophical perspective or point of
> view and try to set the more global definition of Python's core as an
> "entity". 

What do you think "Python's core" means? What do you mean by "global 
definition"? What is an "entity"?


> In order to do that, and following Wittgenstein's indication
> about that the true meaning of words doesn't reside on dictionaries but
> in the use that we make of them, the starting question I make to myself
> about Python is: which is the single and most basic use of Python as the
> entity it is? 

Programming.

A programming language is an abstract system for performing computations. 
Or, if you prefer simple English, programming. Programming is what 
programming languages are for. That is *all* they are for.


> I mean, beside programming, 

Your question pre-supposes a counter-factual. Namely that there exists 
something *more fundamental* to programming that Python is for. One might 
as well ask:

"Aside from driving screws, what is the single and most basic use of a 
screwdriver?"

Just because you can pound a small nail into soft wood using the handle 
of a screwdriver, does not mean that pounding nails is more fundamental 
to the screwdriver than driving screws.


> what's the single and most
> basic result one can expect from "interacting" with it directly
> (interactive mode)? 

For your purposes, what is so special about interactive mode that you 
single it out in this way? Interactive mode is just like non-interactive 
mode, only the user interacts directly with the compiler, instead of 
indirectly.


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


Re: Python for philosophers

2013-05-12 Thread Steven D'Aprano
On Mon, 13 May 2013 12:34:13 +1200, Gregory Ewing wrote:

> In the most general terms, the Python interpeter (or any other computer
> system, for that matter) can be thought of as something with an internal
> state, and a transition function that takes the state together with some
> input and produces another state together with some output:
> 
> F(S1, I) --> (S2, O)
> 
> (Computer scientists call this a "finite state machine", because there
> is a limited number of possible internal states -- the computer only has
> so much RAM, disk space, etc.)

That's not what finite state machine means. A finite state machine 
doesn't refer to the number of physical states of the underlying hardware 
implementing the device, it refers to the number of external states of 
the computation being performed. For example, a traffic light may be 
modelled by a Finite State Machine with three states: Red, Amber, Green. 
It may actually be implemented by a general purpose computer with 
trillions of internal states, or by a specialised electrical circuit, or 
by clockwork. The implementation doesn't matter. What matters is the 
three external states, any input to the device, plus the transition rules 
between them.

Python is not well-modelled as a Finite State Machine. Python is 
equivalent in computing power to a Turing Machine, while Finite State 
Machines are much weaker, so there are things that Python can do that a 
FSM cannot.


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


Re: Python for philosophers

2013-05-12 Thread Steven D'Aprano
On Sun, 12 May 2013 16:17:02 +0200, Citizen Kant wrote:

> Thank you very much for your answers.
> 
> I'm afraid that, at this stage, I must prevent myself from "knowing too
> much" about the subject. My idea here is trying to fill the gaps,
> mostly, using intuition.

Then you are doomed to failure.

Intuition is greatly over-rated. Most of the time, it's just an excuse 
for prejudice, and a way to avoid understanding.


> What I do here is to try to "understand".
> That's different from just knowing. Knowledge growth must be consequence
> of understanding's increasing. As the scope of my understanding
> increases, the more I look for increasing my knowledge. Never vice
> versa, because, knowing isn't like to be right, it's just knowing.

Define your terms. What do you think "to know" means? What do you think 
"to understand" means?

[...]
> But take in account that with "shortening" I
> refer to "according to Python's axiomatic parameters". 

You cannot hypothesis about Python's behaviour in terms of its "axiomatic 
parameters" unless they know what those axiomatic parameters are. So what 
do you think Python's "axiomatic parameters" are, and how did you come to 
that conclusion given that you know virtually nothing about Python?


> What's "shorten"
> if expressed in Python? For example: I'm plainly aware that the word
> "python" looks shorten than "0111 0001 01110100 01101000
> 0110 01101110". But it's shorten just for me and you and maybe for
> every single human, not for the computer. You type "python", and the
> language (so to speak) thinks "in my opinion you're not being economical
> enough coz with this you mean 0111 0001 01110100 01101000
> 0110 01101110", 


Sheer nonsense, and I don't mean the part where you anthropomorphise 
Python. (The "intentional stance" is often an excellent way of reasoning 
about complex systems.)

Your premise that Python tries to be "economical" is incorrect. If 
anything, Python is the opposite: it is often profligate with resources 
(memory mostly) in order to save the human programmer time and effort. 
For example, Python dicts and lists may easily be four times as large as 
they could be (sometimes even bigger), *by design*. A list with 10 items 
may easily have space for 40 items. This is hardly economical, but it is 
a good trade-off in order to get better, and more predictable, 
performance.

[...]
> Maybe It'd be good if I explain myself a bit more. What I'm trying here
> is to grasp Python from the game's abstraction point of view, as if it
> were, for example, chess.

A lousy analogy. Python is nothing like chess. You might as well try to 
understand Python as if it were a toothbrush.



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


Re: Python for philosophers

2013-05-13 Thread Steven D'Aprano
Some further details on something mentioned about Python being 
"economical".

On Sun, 12 May 2013 16:17:02 +0200, Citizen Kant wrote:

> For example: I'm plainly aware that the word "python" looks shorten than
> "0111 0001 01110100 01101000 0110 01101110". But it's
> shorten just for me and you and maybe for every single human, not for
> the computer. You type "python", and the language (so to speak) thinks
> "in my opinion you're not being economical enough coz with this you mean
> 0111 0001 01110100 01101000 0110 01101110", and then mirrors
> the supposedly result in its particular context. My "shorten" points to
> what's shorten during and inside Python's runtime.

In fact, the string "python" is implemented differently in different 
versions of Python. Picking Python 2.7, it may be implemented something 
like this binary string:

      
      
0111  0001  01110100  01101000
 0110  01101110  

where the spaces are purely for the convenience of the reader, and the 
question marks are internal values that I don't know enough to give the 
correct value. (Although I can predict that at least two sets of eight 
question marks is probably " 0110", the length of the string.)

To be precise, this is with a "narrow build", a "wide build" is even more 
profligate with memory. 

I'm not trying to beat the original Poster up for making an error, but 
demonstrating just how badly off track you can get by trying to reason 
from first principles (as Plato may have done) instead of empirical study 
(as Aristotle or Bacon may have done). Knowledge of how things actually 
are beats understanding of how they ought to be every time.


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


[Off topic] Software epigrams

2013-05-13 Thread Steven D'Aprano
My, it's been a long time since I've seen these:

http://pu.inf.uni-tuebingen.de/users/klaeren/epigrams.html

They pre-date the Zen of Python by at least a decade, and quite frankly I 
think many of them miss the mark. But whether you agree or disagree with 
them, they're worth reading.



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


Re: Python's sad, unimaginative Enum

2013-05-13 Thread Steven D'Aprano
On Mon, 13 May 2013 10:24:40 +0100, Mark Lawrence wrote:

> That's the title of this little beast
> http://www.acooke.org/cute/Pythonssad0.html if anybody's interested.



Well, that's one way of looking at it. And I can't exactly *disagree*.

But... but... 

  In many ways, it's a dull language, borrowing solid old concepts
  from many other languages & styles:  boring syntax, unsurprising
  semantics, few  automatic coercions, etc etc.  But that's one of
  the things I like about it. -- Tim Peters, 16 Sep 93


Being "sad and unimaginative" is a *good thing* when it comes to syntax. 
Which would you rather read?

Python:

try:
int(astring)
except ValueError:
print(False)



APL:

⊃⎕VFI{w←⍵⋄((w='-')/w)←'¯'⋄w}


[pedant: okay, so the two code snippets are not *exactly* equivalent. So 
sue me.]


Let's look at his major criticisms:

1) values aren't automatically generated.

True. So what? That is the *least* important part of enums. The most 
important things about enums are:

- they aren't strings, but look like symbolic values;

- or they are ints (for compatibility with C libraries) that look like 
symbolic values.

Probably half the use-cases for enums are for compatibility with C 
libraries, where you *need* to specify the value. There's no point you 
defining an enum SOCK_RAW, having Python decide to set it to 7, when the 
rest of the world agrees it should have the value 3.


2) The enum implementation allows duplicates.

Yes, this *is* a feature. In the real world, enums are not unique. There 
are aliases (maybe you want FAMILY_NAME and SURNAME to be the same enum), 
and misspelled enums need to be corrected:


class Insects(Enum):
bee = 2
ant = 3
wasp = 4  # Preferred spelling.
wsap = 4  # Oops, keep this for backward compatibility!


I'm sorry for all those who can't avoid duplicating values, but really, 
Python doesn't protect them from other silly typos, why are Enums so 
special that they need to be treated differently?


3) the functional API for creating auto-numbered Enums "suffers from the 
same problems" as namedtuples:

[quote]
  - you need to repeat the class name (in a string, which your IDE is
unlikely to check)
  - the parameters are themselves in a string, which your IDE is 
unlikely to parse and provide in auto-complete (they can be separate
strings, in a sequence, but that doesn't really help).
[end quote]


Then maybe you shouldn't be relying on such a lousy IDE then.

Well, perhaps I'm being a tad harsh. After all, it's not like it is a 
*feature* that namedtuple *requires* you to include the class name. But 
really, it's a trivial inconvenience. Python has much worse, e.g.:

- why aren't my CONSTANTS actually constant?


and yet somehow we survive.


4) Auto-generated enums aren't strings:

[quote]
That would makes sense (red = 'red'), in that it would display
nicely and is going to provide easy to debug values.  So nope.
[end quote]

Missing the point entirely. The *whole point* of enum red is that it WILL 
display as 'red', even though it wraps an underlying value of . So this is a non-issue.



I think Enums will be good addition to the standard library, and I look 
forward to dropping support for Python 3.3 so I can rely on them :-)


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


Re: Python's sad, unimaginative Enum

2013-05-13 Thread Steven D'Aprano
On Mon, 13 May 2013 13:00:36 +0200, Jean-Michel Pichavant wrote:

> - Original Message -
>> That's the title of this little beast
>> http://www.acooke.org/cute/Pythonssad0.html if anybody's interested.
>> 
>> --
>> If you're using GoogleCrap™ please read this
>> http://wiki.python.org/moin/GoogleGroupsPython.
>> 
>> Mark Lawrence
>> 
>> --
>> http://mail.python.org/mailman/listinfo/python-list
>> 
>> 
> python 2.5
> 
> class Enum:
>   class __metaclass__(type):
> def __iter__(self):
>   for attr in sorted(dir(self)):
> if not attr.startswith("__"):
>   yield getattr(self, attr)
> 
> class Colours(Enum):
>   RED = "red"
>   GREEN = "green"

py> class Experience(Enum):
... NOVICE = 'novice'
... GREEN = 'green'
... EXPERIENCED = 'experienced'
... MASTER = 'master'
...
py>
py> Colours.GREEN == Experience.GREEN
True


Oops.


It's very easy to make something which does a few things that enums 
should do, and call it an Enum. It's much harder to do a lot of things 
that enums should do.



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


Re: Differences of "!=" operator behavior in python3 and python2 [ bug? ]

2013-05-13 Thread Steven D'Aprano
On Mon, 13 May 2013 19:22:24 -0400, Dave Angel wrote:

> So which special methods should the <> operator call?  By rights it
> ought to call both __gt__ and __lt__ and return True if either of them
> is True.

The <> operator comes from Pascal, where it was used as "not equal" since 
ASCII doesn't include the ≠ operator. Algol 60, by contrast, used ≠ since 
it was invented before ASCII.

The use of ! as "not" is a C-ism and isn't universal.

Given the data types Pascal had as standard back when it was invented, I 
think it is fair to say that "less than, or greater than" was logically 
equivalent to "not equal to". That's no longer the case though.

Interestingly, later versions of Apple's "Standard Apple Numeric 
Environment" (SANE) included separate relational operations for "less 
than or greater than" and "not equal to". So if x was a NAN, then you 
could have pseudo-code like this:

x != y  # true

x <> y  # false



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


Re: Differences of "!=" operator behavior in python3 and python2 [ bug? ]

2013-05-13 Thread Steven D'Aprano
On Mon, 13 May 2013 21:17:41 +, Alister wrote:

> I would then still write it as not (x == y) to make it clear to myself &
> avoid any possible confusion although I think that X != Y is much
> cleaner.

I think that is sad. If I read "not (x == y)" I would assume that the 
person writing the code didn't understand Python syntax or know its 
standard operators.

The exception is if x or y was some unusual type where the __ne__ method 
does something different to the logical reverse of the __eq__ method. But 
if that is the case, I would expect a comment warning about it. If x and 
y were standard objects like floats, strings, etc. then writing out 
not (x == y) in full is as sensible as writing out these in full:

x + -y  # instead of x - y

alist.insert(len(alist), 99)  # instead of alist.append(99)

# instead of adict.clear()
for key in list(adict.keys()):
del adict[key]

x+x+x+x+x+x  # instead of x*6


I'm sure any experienced Python programmer can come up with a 
hypothetical scenario where you would need to write things out "the long 
way", but that doesn't mean that we should do so all the time.


> 2 lines from the zen stand out here:-
> 
> Explicit is better than implicit.
> in the face of ambiguity refuse the temptation to guess.

!= is explicit.

There is no ambiguity that needs to be guessed.



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


Re: Python for philosophers

2013-05-13 Thread Steven D'Aprano
On Tue, 14 May 2013 01:32:43 +0200, Citizen Kant wrote:

> An entity named Python must be somehow as a serpent. Don't forget that
> I'm with the freeing up of my memory, now I'm not trying to follow the
> path of what's told but acting like the monkey and pushing with my
> finger against the skin of the snake.

Python is not named after the snake, but after Monty Python the British 
comedy troupe. And they picked their name because it sounded funny.

http://en.wikipedia.org/wiki/Monty_Python




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


Re: Differences of "!=" operator behavior in python3 and python2 [ bug? ]

2013-05-14 Thread Steven D'Aprano
On Tue, 14 May 2013 19:01:38 -0400, Dennis Lee Bieber wrote:

> On 14 May 2013 05:09:48 GMT, Steven D'Aprano
>  declaimed the following in
> gmane.comp.python.general:

>> The <> operator comes from Pascal, where it was used as "not equal"
>> since
> 
>   I thought it came from BASIC...
> http://en.wikipedia.org/wiki/Dartmouth_BASIC


Ah, well apparently BASIC used it earlier, but I don't know whether it 
was an influence on Pascal (except as "what not to do").


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


Re: Python 2.7.x - problem with obejct.__init__() not accepting *args and **kwargs

2013-05-15 Thread Steven D'Aprano
On Wed, 15 May 2013 13:16:09 +0100, Oscar Benjamin wrote:


> I don't generally use super() 

Then you should, especially in Python 3.

If you're not using super in single-inheritance classes, then you're 
merely making your own code harder to read and write, and unnecessarily 
difficult for others to use with multiple-inheritance.

If you're not using super in multiple-inheritance[1] classes, then your 
code is probably buggy.

There really is no good reason to avoid super in Python 3.


> but I did see some advice about it in this article:
> https://fuhm.net/super-harmful/

It's not a good article. The article started off claiming that super was 
harmful, hence the URL. He's had to back-pedal, and *hard*. The problem 
isn't that super is harmful, it is that the problem being solved -- 
generalized multiple inheritance -- is inherently a fiendishly difficult 
problem to solve. Using super and cooperative multiple inheritance makes 
it a merely difficult but tractable problem.

The above article is useful to see the sorts of issues that can come up 
in multiple inheritance, and perhaps as an argument for avoiding MI 
(except in the tamed versions provided by mixins or straits). But as an 
argument against super? No.

A much better article about super is:

http://rhettinger.wordpress.com/2011/05/26/super-considered-super/


> From the conclusion:
> "Never use positional arguments in __init__ or __new__. Always use
> keyword args, and always call them as keywords, and always pass all
> keywords on to super."

Even that advice is wrong. See Super Considered Super above.




[1] To be precise: one can write mixin classes without super, and 
strictly speaking mixins are a form of multiple inheritance, but it is a 
simplified version of multiple inheritance that avoids most of the 
complications.


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


Generating multi-part emails

2013-05-15 Thread Steven D'Aprano
I wish to generate some test data for a program that deals with emails. I 
need something that can produce multi-part emails, including "broken" 
emails that violate email standards, especially when it comes to Unicode.

Does anyone know of something like this that already exists? It's not 
necessary for the package to actually send the emails, dumping them into 
an mbox is sufficient.


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


Re: executing python scripts that are symlinked

2013-05-16 Thread Steven D'Aprano
On Thu, 16 May 2013 00:48:45 -0700, Charles Smith wrote:

> Hi.
> 
> How can I say, from the cmd line, that python should take my CWD as my
> CWD, and not the directory where the script actually is?

*scratches head*

Python does use your current working directory as your current working 
directory. I think you are misdiagnosing the problem.

Here's a demonstration:

steve@runes:~$ cat test.py
import os
print os.getcwd()


steve@runes:~$ ln -s ~/test.py /tmp/test
steve@runes:~$ ls -l /tmp/test 
lrwxrwxrwx 1 steve steve 19 May 16 18:58 /tmp/test -> /home/steve/test.py
steve@runes:~$ cd /etc/
steve@runes:/etc$ python /tmp/test 
/etc


> I have a python script that works fine when it sits in directory WC, but
> if I move it out of WC to H and put a symlink from H/script to WC, it
> doesn't find the packages that are in WC.  Also, if I use the absolute
> path to H, it won't find them, but I guess I can understand that.

The obvious solution is to make sure that WC is in the Python path. You 
can do that by adding it the environment variable PYTHONPATH, or by 
adding it to sys.path at the start of your script. I think you can also 
use a .pth file as well.

Another solution may be to add this to the beginning of your script:

os.setcwd('path/to/WC')

but that's a crappy solution, you generally don't want to be changing the 
working directory from inside scripts if you can avoid it.



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


Re: How to use relative Import

2013-05-16 Thread Steven D'Aprano
On Fri, 17 May 2013 01:35:49 +0530, Chitrank Dixit wrote:

> I want to know how relative imports are different than import. I have
> found lots of examples on internet explaining about the relative import
> but I want to know about the basic aspects of relative import that make 
> it different than import.

Relative imports search the directory containing the current package, 
absolute imports search the entire contents of sys.path. That is the only 
difference.

The purpose of relative imports is to make it easy for modules inside a 
package to import each other without worrying about other modules 
*outside* the package being imported by mistake. You can read the PEP 
here:

http://www.python.org/dev/peps/pep-0328/

to learn about the motivation for absolute and relative imports.

Optional in Python 2.5 and 2.6, and compulsory in 2.7, when you write:

import moduleX

Python looks at sys.path for a list of directories to search for 
"moduleX.py". This is an absolute import.

But consider a package with this structure:

package/
  +--  __init__.py
  +--  moduleA.py
  +--  moduleB.py
  +--  moduleX.py
  +--  subpackage/
   +--  __init__.py
   +--  moduleY.py
   +--  moduleZ.py


Inside moduleA, if you write "import moduleX" it will be an absolute 
import, the entire sys.path will be searched, and the "top level" 
module.X will be found.

But if you write this instead:

from . import moduleX

you have a relative import, and Python will only search the current 
package directory, so it will find the moduleX inside the package.

You can also write:

from .subpackage import moduleZ

to find the moduleZ inside the subpackage, again without searching the 
entire sys.path.

Inside moduleY in the subpackage, all of these will find the same moduleZ:

# Relative to the current module:
from . import moduleZ

# Relative to the parent of the current module:
from ..subpackage import moduleZ
from .. import subpackage.moduleZ

# Absolute:
import package.subpackage.moduleZ



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


Re: How to write fast into a file in python?

2013-05-16 Thread Steven D'Aprano
On Thu, 16 May 2013 20:20:26 -0700, lokeshkoppaka wrote:

> I need to write numbers into a file upto 50mb and it should be fast can
> any one help me how to do that?
> i had written the following code..
> --
> def create_file_numbers_old(filename, size): start = time.clock()
> 
> value = 0
> with open(filename, "w") as f:
> while f.tell()< size:
> f.write("{0}\n".format(value))
> value += 1
> 
> end = time.clock()
> 
> print "time taken to write a file of size", size, " is ", (end -start),
> "seconds \n"
> 
> it takes about 20sec i need 5 to 10 times less than that.


20 seconds to write how many numbers? If you are doing

create_file_numbers_old(filename, 5)

then 20 seconds is really slow. But if you are doing:

create_file_numbers_old(filename, 50)

then 20 seconds is amazingly fast.


Try this instead, it may be a little faster:


def create_file_numbers_old(filename, size):
count = value = 0
with open(filename, 'w') as f:
while count < size:
s = '%d\n' % value
f.write(s)
count += len(s)
value += 1


If this is still too slow, you can try three other tactics:

1) pre-calculate the largest integer that will fit in `size` bytes, then 
use a for-loop instead of a while loop:

maxn = calculation(...)
with open(filename, 'w') as f:
for i in xrange(maxn):
f.write('%d\n' % i)


2) Write an extension module in C that writes to the file.

3) Get a faster hard drive, and avoid writing over a network.


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


Re: How to write fast into a file in python?

2013-05-17 Thread Steven D'Aprano
On Fri, 17 May 2013 18:20:33 +0300, Carlos Nepomuceno wrote:

> I've got the following results on my desktop PC (Win7/Python2.7.5):
> 
> C:\src\Python>python -m timeit -cvn3 -r3 "execfile('fastwrite2.py')" raw
> times: 123 126 125
> 3 loops, best of 3: 41 sec per loop

Your times here are increased significantly by using execfile. Using 
execfile means that instead of compiling the code once, then executing 
many times, it gets compiled over and over and over and over again. In my 
experience, using exec, execfile or eval makes your code ten or twenty 
times slower:

[steve@ando ~]$ python -m timeit 'x = 100; y = x/3'
100 loops, best of 3: 0.175 usec per loop
[steve@ando ~]$ python -m timeit 'exec("x = 100; y = x/3")'
1 loops, best of 3: 37.8 usec per loop


> Strangely I just realised that the time it takes to complete such
> scripts is the same no matter what hard drive I choose to run them. The
> results are the same for an SSD (main drive) and a HDD.

There's nothing strange here. The time you measure is dominated by three 
things, in reducing order of importance:

* the poor choice of execfile dominates the time taken; 

* followed by choice of algorithm;

* followed by the time it actually takes to write to the disk, which is 
probably insignificant compared to the other two, regardless of whether 
you are using a HDD or SSD.

Until you optimize the code, optimizing the media is a waste of time. 


> I think it's very strange to take 11.3s to write 50MB (4.4MB/s)
> sequentially on a SSD which is capable of 140MB/s.

It doesn't. It takes 11.3 seconds to open a file, read it into memory, 
parse it, compile it into byte-code, and only then execute it. My 
prediction is that the call to f.write() and f.close() probably take a 
fraction of a second, and nearly all of the rest of the time is taken by 
other calculations.



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


Re: How to write fast into a file in python?

2013-05-17 Thread Steven D'Aprano
On Fri, 17 May 2013 18:20:33 +0300, Carlos Nepomuceno wrote:

> ### fastwrite5.py ###
> import cStringIO
> size = 50*1024*1024
> value = 0
> filename = 'fastwrite5.dat'
> x = 0
> b = cStringIO.StringIO()
> while x < size:
>     line = '{0}\n'.format(value)
>     b.write(line)
>     value += 1
>     x += len(line)+1

Oh, I forgot to mention: you have a bug in this function. You're already 
including the newline in the len(line), so there is no need to add one. 
The result is that you only generate 44MB instead of 50MB.

> f = open(filename, 'w')
> f.write(b.getvalue())
> f.close()
> b.close()

Here are the results of profiling the above on my computer. Including the 
overhead of the profiler, it takes just over 50 seconds to run your file
on my computer.

[steve@ando ~]$ python -m cProfile fastwrite5.py
 17846645 function calls in 53.575 seconds

   Ordered by: standard name

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
1   30.561   30.561   53.575   53.575 fastwrite5.py:1()
10.0000.0000.0000.000 {cStringIO.StringIO}
  59488795.5820.0005.5820.000 {len}
10.0040.0040.0040.004 {method 'close' of 
'cStringIO.StringO' objects}
10.0000.0000.0000.000 {method 'close' of 'file' objects}
10.0000.0000.0000.000 {method 'disable' of 
'_lsprof.Profiler' objects}
  59488799.9790.0009.9790.000 {method 'format' of 'str' objects}
10.1030.1030.1030.103 {method 'getvalue' of 
'cStringIO.StringO' objects}
  59488797.1350.0007.1350.000 {method 'write' of 
'cStringIO.StringO' objects}
10.2110.2110.2110.211 {method 'write' of 'file' objects}
10.0000.0000.0000.000 {open}


As you can see, the time is dominated by repeatedly calling len(), 
str.format() and StringIO.write() methods. Actually writing the data to 
the file is quite a small percentage of the cumulative time.

So, here's another version, this time using a pre-calculated limit. I 
cheated and just copied the result from the fastwrite5 output :-)

# fasterwrite.py
filename = 'fasterwrite.dat'
with open(filename, 'w') as f:
for i in xrange(5948879):  # Actually only 44MB, not 50MB.
f.write('%d\n' % i)


And the profile results are about twice as fast as fastwrite5 above, with 
only 8 seconds in total writing to my HDD.

[steve@ando ~]$ python -m cProfile fasterwrite.py
 5948882 function calls in 28.840 seconds

   Ordered by: standard name

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
1   20.592   20.592   28.840   28.840 fasterwrite.py:1()
10.0000.0000.0000.000 {method 'disable' of 
'_lsprof.Profiler' objects}
  59488798.2290.0008.2290.000 {method 'write' of 'file' objects}
10.0190.0190.0190.019 {open}


Without the overhead of the profiler, it is a little faster:

[steve@ando ~]$ time python fasterwrite.py

real0m16.187s
user0m13.553s
sys 0m0.508s


Although it is still slower than the heavily optimized dd command, 
but not unreasonably slow for a high-level language:

[steve@ando ~]$ time dd if=fasterwrite.dat of=copy.dat
90781+1 records in
90781+1 records out
46479922 bytes (46 MB) copied, 0.737009 seconds, 63.1 MB/s

real0m0.786s
user0m0.071s
sys 0m0.595s




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


Re: How to write fast into a file in python?

2013-05-17 Thread Steven D'Aprano
On Fri, 17 May 2013 21:18:15 +0300, Carlos Nepomuceno wrote:

> I thought there would be a call to format method by "'%d\n' % i". It
> seems the % operator is a lot faster than format. I just stopped using
> it because I read it was going to be deprecated. :( Why replace such a
> great and fast operator by a slow method? I mean, why format is been
> preferred over %?

That is one of the most annoying, pernicious myths about Python, probably 
second only to "the GIL makes Python slow" (it actually makes it fast). 

String formatting with % is not deprecated. It will not be deprecated, at 
least not until Python 4000.

The string format() method has a few advantages: it is more powerful, 
consistent and flexible, but it is significantly slower.

Probably the biggest disadvantage to % formatting, and probably the main 
reason why it is "discouraged", is that it treats tuples specially. 
Consider if x is an arbitrary object, and you call "%s" % x:

py> "%s" % 23  # works
'23'
py> "%s" % [23, 42]  # works
'[23, 42]'

and so on for *almost* any object. But if x is a tuple, strange things 
happen:

py> "%s" % (23,)  # tuple with one item looks like an int
'23'
py> "%s" % (23, 42)  # tuple with two items fails
Traceback (most recent call last):
  File "", line 1, in 
TypeError: not all arguments converted during string formatting


So when dealing with arbitrary objects that you cannot predict what they 
are, it is better to use format.



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


Re: Future standard GUI library

2013-05-18 Thread Steven D'Aprano
On Sat, 18 May 2013 10:03:02 -0400, Beinan Li wrote:

> Do you think tkinter is going to be the standard python built-in gui
> solution as long as python exists?

Probably.

> I couldn't help but wonder if wx or PySide receives better py2 and py3
> support, or anything else that prevent them from getting into the
> standard python distributions, whether or not this scene could start to
> shift ...

One of the major issues preventing projects being added to the standard 
library is the maintenance schedule. Python's schedule for new releases 
is quite conservative and slow. If, say, wxPython was added to the std 
lib, it would have to follow Python's schedule:

* most backwards incompatible changes would be forbidden;

* those that are allowed would require a minimum of two major releases 
(three years) before removing functionality;

* about four bug-fix releases (I think?) per year.

If a project is used to (say) weekly releases, dropping down to Python's 
schedule can be rather painful.

Once something has been added to the standard library, it more or less 
has to have a stable API, become conservative about changes, and care 
more about backwards-compatibility than new features. Stability and 
consistency become paramount. Many excellent, popular packages cannot 
live under those restrictions, and so will never be part of the standard 
library.

Tkinter is good in this regard, because it is a wrapper around Tk/Tcl, 
which is equally stable and conservative as Python. Possibly even more so.



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


Re: How to write fast into a file in python?

2013-05-18 Thread Steven D'Aprano
On Sat, 18 May 2013 15:14:31 -0400, Dennis Lee Bieber wrote:

> tOn Sat, 18 May 2013 08:49:55 +0100, Fábio Santos
>  declaimed the following in
> gmane.comp.python.general:
> 
> 
>> You mentioned "\n" translating to two lines, but this won't happen.
>> Windows will not mess with what you write to your file. 

Windows certainly may mess with what you write to your file, if it is 
opened in Text mode instead of Binary mode. In text mode, Windows will:

- interpret Ctrl-Z characters as End Of File when reading;

- convert \r\n to \n when reading;

- convert \n to \r\n when writing.

http://msdn.microsoft.com/en-us/library/z5hh6ee9(v=vs.80).aspx


>> It's just that
>> traditionally windows and windows programs use \r\n instead of just \n.
>> I think it was for compatibility with os/2 or macintosh (I don't
>> remember which), which used \r for newlines.
>>
>   Neither... It goes back to Teletype machines where one sent a
> carriage return to move the printhead back to the left, then sent a line
> feed to advance the paper (while the head was still moving left), and in
> some cases also provided a rub-out character (a do-nothing) to add an
> additional character time delay.

Yes, if you go back far enough, you get to teletype machines. But Windows 
inherits its text-mode behaviour from DOS, which inherits it from CP/M. 


>   TRS-80 Mod 1-4 used  for "new line", I believe Apple used 
> for "new line"... 

I can't comment about TRS, but classic Apple Macs (up to System 9) used 
carriage return \r as the line separator.



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


Re: Question about ast.literal_eval

2013-05-20 Thread Steven D'Aprano
On Mon, 20 May 2013 10:55:35 +0300, Carlos Nepomuceno wrote:

> I understand your motivation but I don't know what protection
> ast.literal_eval() is offering that eval() doesn't.

eval will evaluate any legal Python expression:


py> eval("__import__('os').system('echo Mwahaha! Now you are pwned!') or 42")
Mwahaha! And now you are pwned!
42


ast.literal_eval() does exactly what the name says: it will evaluate any 
legal Python LITERAL, including ints, floats, lists, dicts and strings,
but not arbitrary expressions.


py> ast.literal_eval('123')
123
py> ast.literal_eval('[123, None, "spam"]')
[123, None, 'spam']



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


Re: Question about ast.literal_eval

2013-05-20 Thread Steven D'Aprano
On Mon, 20 May 2013 15:26:02 +0200, Frank Millman wrote:

> Can anyone see anything wrong with the following approach. I have not
> definitely decided to do it this way, but I have been experimenting and
> it seems to work.
> 
> I store the boolean test as a json'd list of 6-part tuples. Each element
> of the tuple is a string, defined as follows -
> 
> 0 - for the first entry in the list, the word 'check' (a placeholder -
> it is discarded at evaluation time), for any subsequent entries the word
> 'and' or 'or'.
> 
> 1 - left bracket - either '(' or ''.
> 
> 2 - column name to check - it will be validated on entry.
> 
> 3 - operator - must be one of '=', '!=', '<', '>', '<=', '>=', 'in',
> 'is', 'is not'. At evaluation time, '=' is changed to '=='.
> 
> 4 - value to compare - at evaluation time I call
> str(literal_eval(value)) to ensure that it is safe.
> 
> 5 - right bracket - either ')' or ''.
> 
> At evaluation time I loop through the list, construct the boolean test
> as a string, and call eval() on it.
[...]
> It seems safe to me. Can anyone see a problem with it?


It seems safe to me too, but then any fool can come up with a system 
which they themselves cannot break :-)

I think the real worry is validating the column name. That will be 
critical. Personally, I would strongly suggest writing your own mini-
evaluator that walks the list and evaluates it by hand. It isn't as 
convenient as just calling eval, but *definitely* safer.

If you do call eval, make sure you supply the globals and locals 
arguments. The usual way is:

eval(expression, {'__builtins__': None}, {})

which gives you an empty locals() and a minimal, (mostly) safe globals.

Finally, as a "belt-and-braces" approach, I wouldn't even call eval 
directly, but call a thin wrapper that raises an exception if the 
expression contains an underscore. Underscores are usually the key to 
breaking eval, so refusing to evaluate anything with an underscore raises 
the barrier very high.

And even with all those defences, I wouldn't allow untrusted data from 
the Internet anywhere near this. Just because I can't break it, doesn't 
mean it's safe.


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


Re: Please help with Threading

2013-05-20 Thread Steven D'Aprano
On Tue, 21 May 2013 05:53:46 +0300, Carlos Nepomuceno wrote:

> BTW, why I didn't find the source code to the sys module in the 'Lib'
> directory?

Because sys is a built-in module. It is embedded in the Python 
interpreter.

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


Re: Question about ast.literal_eval

2013-05-21 Thread Steven D'Aprano
On Tue, 21 May 2013 08:30:03 +0200, Frank Millman wrote:

> On 20/05/2013 18:12, Steven D'Aprano wrote:

>> Personally, I would strongly suggest writing your own mini- evaluator
>> that walks the list and evaluates it by hand. It isn't as convenient as
>> just calling eval, but *definitely* safer.
>>
>>
> I am not sure I can wrap my mind around mixed 'and's, 'or's, and
> brackets.


Parsers are a solved problem in computer science, he says as if he had a 
clue what he was talking about *wink*

Here's a sketch of a solution... suppose you have a sequence of records, 
looking like this:

(bool_op, column_name, comparison_op, literal)

with appropriate validation on each field. The very first record has 
bool_op set to "or". Then, you do something like this:


import operator
OPERATORS = {
'=': operator.eq,
'is': operator.is_,
'<': operator.lt,
# etc.
}


def eval_op(column_name, op, literal):
value = lookup(column_name)  # whatever...
return OPERATORS[op](value, literal)

result = False

for (bool_op, column_name, comparison_op, literal) in sequence:
flag = eval_op(column_name, comparison_op, literal)
if bool_op == 'and':
result = result and flag
else: 
assert bool_op == 'or'
    result = result or flag
# Lazy processing?
if result:
break


and in theory it should all Just Work.




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


sympy.nsimplify

2013-05-21 Thread Steven D'Aprano
For maths nerds like me, this is too cool for words:

http://www.johndcook.com/blog/2013/04/30/recognizing-numbers/



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


Re: PEP 378: Format Specifier for Thousands Separator

2013-05-21 Thread Steven D'Aprano
On Tue, 21 May 2013 23:22:24 +0300, Carlos Nepomuceno wrote:

> Anyway, is it possible to overload str.__mod__() without deriving a
> class? I mean to have something like:

No, not in Python. If you want to monkey-patch built-in classes on the 
fly, with all the troubles that causes, use Ruby.


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


Re: PEP 378: Format Specifier for Thousands Separator

2013-05-21 Thread Steven D'Aprano
On Tue, 21 May 2013 14:53:54 -0500, Andrew Berg wrote:

> On 2013.05.21 14:26, Mark Lawrence wrote:

>> Please stop perpetuating this myth, see
>> http://mail.python.org/pipermail/python-dev/2012-February/116789.html
>> and http://bugs.python.org/issue14123
>> 
> What myth? 

The myth that % string formatting is deprecated. It is not deprecated.

> People should indeed be using .format(), 

If it is useful to them, and not too slow, or indeed if they merely want 
to. And if not, then not.

This is a good case where the original poster *should* use str.format, 
since it does exactly what he wants, and % does not. Python gives you 
many tools, and the wise man uses the right tool for the job. Sometimes 
that is % and sometimes it is str.format and sometimes it is 
string.Template.

That str.format looks like Java is irrelevant. Method call syntax is 
common in Python, and is not original to Java. Besides, Python looks like 
many languages: some parts look like Java, some parts look like C, some 
parts remind me of functional languages like Lisp and Haskell, and some 
parts look like Algol or Pascal.


> but no one said % formatting was going away soon.

True, but only for the definition "no one = all the people who insist 
that % is deprecated, or soon to be deprecated".


> Also, the suggested change to the docs
> wasn't made and the issue is closed. The current docs do not say that %
> formatting isn't going to be deprecated, but it does mention its caveats
> and suggests .format(). If you are trying to say that % formatting will
> never ever go away, then you are wrong. It is highly unlikely to go away
> in a 3.x release, but /may/ get phased out in Python 4.0.

What happens in Python 4000 is irrelevant. If somebody is trying to 
"future proof" their code for a version that *may never exist*, and if it 
does exist is likely to be six or eight years away from even starting the 
design phase, they are wasting their time. It is hard enough to track a 
moving target, it is impossible to track a target that isn't even a gleam 
in GvR's eye yet.



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


Re: PEP 378: Format Specifier for Thousands Separator

2013-05-21 Thread Steven D'Aprano
On Wed, 22 May 2013 05:56:53 +0300, Carlos Nepomuceno wrote:

> 
>> From: steve+comp.lang.pyt...@pearwood.info Subject: Re: PEP 378: Format
>> Specifier for Thousands Separator Date: Wed, 22 May 2013 02:42:56 +
>> To: python-list@python.org
>>
>> On Tue, 21 May 2013 23:22:24 +0300, Carlos Nepomuceno wrote:
>>
>>> Anyway, is it possible to overload str.__mod__() without deriving a
>>> class? I mean to have something like:
>>
>> No, not in Python. If you want to monkey-patch built-in classes on the
>> fly, with all the troubles that causes, use Ruby.
>>
>>
> So, the only alternative to have "'%,d' % x" rendering the thousands
> separator output would a C source code modification?

That's one alternative. But the language you would be then running will 
no longer be Python.

Another alternative would be to write a pre-processor that parses your 
Python source code, extracts any reference to the above, and replaces it 
with a call to the appropriate format call. But not only is that a lot of 
work for very little gain, but it's also more or less impossible to do in 
full generality. And again, what you are running will be something 
different than Python, it will be Python plus a pre-processor.


Don't fight the language. You will lose.



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


Re: Case insensitive dict

2013-05-21 Thread Steven D'Aprano
On Wed, 22 May 2013 03:59:55 +, Joseph L. Casale wrote:

> I was doing some work with the ldap module and required a ci dict that
> was case insensitive but case preserving. It turned out the cidict class
> they implemented was broken with respect to pop, it is inherited and not
> re implemented to work. Before I set about re-inventing the wheel,
> anyone know of a working implementation?

class my_cidict(ldap.cidict):
"""Fix problems with pop."""
def pop(self):
# insert code here


You don't have to re-invent the entire wheel just to fix one broken 
spoke :-)

Other than that, no, I don't know of any case-insensitive but preserving 
dicts. If you do decide to write one from scratch, please consider 
releasing it as Open Source (I recommend GPL or MIT licences), either as 
a module on PyPI or as a recipe on ActiveState.

https://pypi.python.org/pypi
http://code.activestate.com/recipes/langs/python/



Thank you.






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


Re: PEP 378: Format Specifier for Thousands Separator

2013-05-22 Thread Steven D'Aprano
On Wed, 22 May 2013 05:45:12 -0500, Skip Montanaro wrote:

> I didn't mean to create a tempest in a teapot.  I was away from
> comp.lang.python, python-bugs, and python-dev for a few years.  In
> particular, I didn't ever see the aforementioned thread from Feb 2012.
>  Had I known of that thread I would have worded the sentence which
> shall not be repeated differently.
> 
> My apologies...

No problem, it's not about you specifically, it's just that some of us 
fans of % formatting can be a tad sensitive about it, especially since 
the idea that it has been deprecated (or soon will be deprecated, or one 
day will be deprecated, and therefore code using it is bad) is relatively 
widespread on the Internet.

Glad to have you back here!



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


Re: Newbie question about evaluating raw_input() responses

2013-05-22 Thread Steven D'Aprano
On Wed, 22 May 2013 22:31:04 +, Alister wrote:

> Please write out 1000 time (without using any form of loop)
> 
> "NEVER use input in python <3.0 it is EVIL"*
> 
> as Chris A point out it executes user input an can cause major damage
> (reformatting the hard disk is not impossible!)

Is he allowed to use eval instead of a loop?

print (eval("NEVER use input in python <3.0 it is EVIL\n"*1000))

*wink*


But all joking aside, eval is dangerous, yes, but it is not "evil". It 
needs to be handled with caution, but there are good uses for it. In 
fact, there are a few -- a very few -- things which can *only* be done 
with eval or exec. That's why it is part of the language! 

(I just wish that eval and exec where in a module, rather than built-in, 
to help discourage casual usage by beginners who don't know what they're 
doing.)

For example, collections.namedtuple uses eval to dynamically generate new 
classes on the fly from arguments given. But it is safe to use, because 
it has been designed by experts to be safe and tested in great detail.

So while it is right and proper to treat eval with great respect as a 
powerful (and therefore dangerous) tool, and avoid it whenever you don't 
*need* it, there is no reason to be irrational about it :-)



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


Re: Simple algorithm question - how to reorder a sequence economically

2013-05-24 Thread Steven D'Aprano
On Fri, 24 May 2013 01:14:45 -0700, Peter Brooks wrote:

> What is the easiest way to reorder a sequence pseudo-randomly?

import random
random.shuffle(sequence)


The sequence is modified in place, so it must be mutable. Lists are okay, 
tuples are not.


> That is, for a sequence 1,2,3,4 to produce an arbitrary ordering (eg
> 2,1,4,3) that is different each time.

You can't *guarantee* that it will be different each time. With a four-
item list, there are only 4! = 24 combinations, so on average you'll get 
the original order one time in 24. For a ten-item list, that is once 
every 3628800 times, and for a twenty-item list, once in 
243290200817664 times. But of course these are *random*, and there's 
always a chance of this:

http://dilbert.com/strips/comic/2001-10-25


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


Re: Polymoprhism question

2013-05-24 Thread Steven D'Aprano
On Fri, 24 May 2013 04:40:22 -0700, RVic wrote:

> I'm trying to figure out (or find an example) of polymorphism whereby I
> pass a commandline argument (a string) which comports to a class (in
> java, you would say that it comports to a given interface bu I don't
> know if there is such a thing in Python) then that class of that name,
> somehow gets intantiated from that string. This way, I can have similar
> classes, but have my program use various ones by simply changing the
> commandline argument.
> 
> Can anyone show me how this might be done in Python? Thanks.


I'm not 100% sure I understand what you want, but my guess is you want 
something like this:


# A toy class.
class AClass(object):
def __init__(self, astring):
self.astring = astring
def __repr__(self):
return "%s(%r)" % (self.__class__.__name__, self.astring)

# And some variations.
class BClass(AClass):
pass

class CClass(AClass):
pass


# Build a dispatch table, mapping the class name to the class itself.
TABLE = {}
for cls in (AClass, BClass, CClass):
TABLE[cls.__name__] = cls


# Get the name of the class, and an argument, from the command line.
# Or from the user. Any source of two strings will do.
# Data validation is left as an exercise.
import sys
argv = sys.argv[1:]
if not argv:
name = raw_input("Name of the class to use? ")
arg = raw_input("And the argument to use? ")
argv = [name, arg]


# Instantiate.
instance = TABLE[argv[0]](argv[1])
print instance


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


Re: Simple algorithm question - how to reorder a sequence economically

2013-05-24 Thread Steven D'Aprano
On Fri, 24 May 2013 06:23:14 -0700, Peter Brooks wrote:


> Thanks for the warnings about random numbers too - I hope my lists will
> be short enough for the permutations of the function to be irrelevant. I
> don't need every single sequence to be unique, only that the same
> sequence only occurs occasionally. My lists might get up to the ~2k
> length one day, and I'll keep in mind the need, at that stage, to use a
> different pseudo-random generator. Actually, thinking about it, there is
> probably a source of non-algorithmically-derived 'random' numbers
> somewhere on the net that would do the job nicely.

That's massive overkill.

Take a closer look at what Ned wrote:

"The default random number generator has a period of 2**19937-1"

and consider the numbers.

For a list with 3000 items, there are 3000! possible permutations. That 
is approximately 10**21024. That is, a number with 21024 digits, or 
somewhere around a trillion trillion trillion ... trillion trillion, 
where there are 1752 "trillions".

If you could generate a million permutations a second, it would take you 
on average 10**210988 centuries before getting the original permutation 
again. That's the expected result you would get with a source of true 
randomness.

Instead, with Python's default pseudo-random number generator, you cannot 
get the full 3000! permutations, but only 2**19937-1 of them. Using the 
same calculation as above, that means that you will have to generate a 
million permutations per second for "only" 10**13783 centuries before 
getting the original permutation again.

There are uses where being able to generate any possible permutation is 
important, and the default PRNG is not sufficient. But merely shuffling 
your data around to avoid spurious correlations is not one of them. Save 
yourself a lot of development effort, and debugging, and just use 
random.shuffle.


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


Re: help how to sort a list in order of 'n' in python without using inbuilt functions??

2013-05-24 Thread Steven D'Aprano
On Fri, 24 May 2013 22:39:06 -0700, lokeshkoppaka wrote:

> On Saturday, May 25, 2013 10:54:01 AM UTC+5:30, Chris Angelico wrote:

>> In that case, you're not really ordering them, you're counting them.
>> Look at the collections module; you can very easily figure out how
>> many of each there are, and then reconstruct the list afterward.
> 
> but i need to do it with out using builtin functions


How would you, an intelligent human being count them?

Describe how you would count them in English, or whatever your native 
language is.

"First I would start a tally for the number of zeroes, tally = 0. Then I 
look at each item in turn, and if it is 0, I add one to the tally. When I 
get to the end, I the number of zeroes is equal to the tally.

Then I do the same for the number of ones, and the number of twos."

Now turn that into Python code. 

tally = 0
for item in list_of_items:
if item == 0:
tally = tally + 1

print "The number of zeroes equals", tally



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


Re: Python Magazine

2013-05-25 Thread Steven D'Aprano
On Sat, 25 May 2013 16:41:58 +1000, Chris Angelico wrote:

> On Sat, May 25, 2013 at 4:38 PM, zoom  wrote:
>> But why would anyone want to use IPv6?
> 
> I hope you're not serious :)

He's planning to drop off the Internet once the IP address run out.


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


Re: help how to sort a list in order of 'n' in python without using inbuilt functions??

2013-05-25 Thread Steven D'Aprano
On Sat, 25 May 2013 19:14:57 +1000, Chris Angelico wrote:

> def random_number():
> return 7

I call shenanigans! That value isn't generated randomly, you just made it 
up! I rolled a die *hundreds* of times and not once did it come up seven!



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


Re: help how to sort a list in order of 'n' in python without using inbuilt functions??

2013-05-25 Thread Steven D'Aprano
On Fri, 24 May 2013 23:05:17 -0700, lokeshkoppaka wrote:

> On Saturday, May 25, 2013 11:27:38 AM UTC+5:30, Steven D'Aprano wrote:

>> tally = 0
>> for item in list_of_items:
>> if item == 0:
>> tally = tally + 1
>> 
>> print "The number of zeroes equals", tally
> 
>
> ya steven i had done the similar logic but thats not satisfying my
> professor he had given the following constrains
>  1. No in-built functions should be used 

The above does not use any built-in functions.

> 2. we are expecting a O(n) solution

The above is O(n).

>  3. Don't use count method

The above does not use the count method.



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


Re: Learning Python

2013-05-25 Thread Steven D'Aprano
On Sat, 25 May 2013 18:11:11 +0530, Asad Hasan wrote:

> I have started leaning Python through web . Would like to know
> if I should follow any book so that basics become clear with examples 

Reading books is a good thing to do.


> also
> want to know like in perl i use to invoke perl -d to get a debugged
> output is there any option in python.

Yes. Instead of calling your script like this:

python myscript.py

call it like this:

python -m pdb myscript.py



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


Re: help how to sort a list in order of 'n' in python without using inbuilt functions??

2013-05-25 Thread Steven D'Aprano
On Sun, 26 May 2013 01:41:58 +1000, Chris Angelico wrote:

> On Sun, May 26, 2013 at 12:28 AM, Steven D'Aprano
>  wrote:
>> On Sat, 25 May 2013 19:14:57 +1000, Chris Angelico wrote:
>>
>>> def random_number():
>>> return 7
>>
>> I call shenanigans! That value isn't generated randomly, you just made
>> it up! I rolled a die *hundreds* of times and not once did it come up
>> seven!
> 
> You've obviously never used a REAL set of dice.

You're right, all my dice are eight-sided and complex:

1+0i
1+1i
1-1i
-1+0i
-1+1i
-1-1i


:-)


But seriously, I have various D&D style gaming dice, d4, d6, d8, d12, d20 
and d30. But I thought the opportunity for a joke was more important than 
pedantic correctness :-)


> Now, I have here with me
> a set used for maths drill (to be entirely accurate, what I have here is
> the company's stock of them, so there are multiples of each of these -
> anyone need to buy dice?) 

Are you serious? What's the cost, posted to Melbourne?


> with everything except the classic 1 through 6 that everyone knows:
> 
> * Six sides, faces marked 7 through 12 
> * Six sides, faces marked "+x-\xf7+" and a "wild" marker 
>   (yes, two of +)

Oh, you mean ÷ (division sign)! Why didn't you say so? :-P

And another thing, shame on you, you mean × not x. It's easy to find too:

py> from unicodedata import lookup
py> print(lookup("MULTIPLICATION SIGN"))
×


> * Ten sides, numbered 0 through 9
> * Eight sides, numbered 1 through 8
> * Twelve sides, as above
> * Twenty sides, as above
> 
> Now, tabletop roleplayers will recognize the latter four as the ones
> notated as d10, d8, d12, and d20, but these are NOT for gameplay, they
> are for serious educational purposes! Honest!
> 
> Anyway, all of those can roll a 7... well, one of them has to roll a
> \xf7, but close enough right? 

I don't think so...

> Plus, if you roll 2d6 (that is, two
> regular six-sided dice and add them up), 7 is statistically the most
> likely number to come up with. Therefore it IS random.

Yes, but if you subtract them the most common is 0, if you multiply the 
most common are 6 or 12, and if you divide the most common is 1. If you 
decide on the operation randomly, using the +-×÷+ die above (ignoring 
wildcards), the most common result is 6. The probability of getting a 7 
is just 1/15.

from collections import Counter
from operator import add, sub, mul, truediv as div
ops = (add, sub, mul, div, add)
Counter(op(i, j) for op in ops for i in range(1, 7) for j in range(1, 7))


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


Re: help how to sort a list in order of 'n' in python without using inbuilt functions??

2013-05-25 Thread Steven D'Aprano
On Sun, 26 May 2013 03:23:44 +1000, Chris Angelico wrote:

> Does adding 1 to a random
> number make it less random? It adds determinism to the number; can a
> number be more deterministic while still no less random?
> 
> Ah! I know. The answer comes from common sense:
[snip spurious answer]

I know you're being funny, but in fact adding a constant to a random 
variable still leaves it equally random. Adding, multiplying, dividing or 
subtracting a constant from a random variable X just shifts the possible 
values X can take, it doesn't change the shape of the distribution. 
However, adding two random variables X and Y does change the 
distribution. In fact, a very cheap way of simulating an almost normally 
distributed random variable is to add up a whole lot of uniformly 
distributed random variables. Adding up 12 calls to random.random(), and 
subtracting 6, gives you a close approximation to a Gaussian random 
variable with mean 0 and standard deviation 1.



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


Re: Python Magazine

2013-05-25 Thread Steven D'Aprano
On Sat, 25 May 2013 21:54:43 -0400, Roy Smith wrote:

> Of course not every IPv6 endpoint will be able to talk to every other
> IPv6 endpoint, even if the both have globally unique addresses.  But,
> the access controls will be implemented in firewalls with appropriately
> coded security policies.

Or, more likely, *not* implemented in firewalls with *inappropriately* 
coded security policies.



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


Re: Python Magazine

2013-05-25 Thread Steven D'Aprano
On Sun, 26 May 2013 11:58:09 +1000, Chris Angelico wrote:

> On Sun, May 26, 2013 at 11:54 AM, Roy Smith  wrote:

>> Of course not every IPv6 endpoint will be able to talk to every other
>> IPv6 endpoint, even if the both have globally unique addresses.  But,
>> the access controls will be implemented in firewalls with appropriately
>> coded security policies.  Not as an accident of being behind a NAT box.
> 
> To be more specific: The control of who can talk to whom is in the hands
> of the admins of the two endpoints and the nodes in between, rather than
> being arbitrarily in the hands of the technology. So I would be able to
> talk to the file server across the street, but only IF its admin lets
> me.

Or when (not if) you find a vulnerability in the particular firewall. 
Make no mistake: the most secure entry point is the one that isn't there.



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


Re: Short-circuit Logic

2013-05-26 Thread Steven D'Aprano
On Sun, 26 May 2013 04:11:56 -0700, Ahmed Abdulshafy wrote:

> Hi,
> I'm having a hard time wrapping my head around short-circuit logic
> that's used by Python, coming from a C/C++ background; so I don't
> understand why the following condition is written this way!
> 
>  if not allow_zero and abs(x) < sys.float_info.epsilon:
> print("zero is not allowed")

Follow the logic.

If allow_zero is a true value, then "not allow_zero" is False, and the 
"and" clause cannot evaluate to true. (False and X is always False.) So 
print is not called.

If allow_zero is a false value, then "not allow_zero" is True, and the 
"and" clause depends on the second argument. (True and X is always X.) So
abs(x) < sys.float_info.epsilon is tested, and if that is True, print is 
called.

By the way, I don't think much of this logic. Values smaller than epsilon 
are not necessarily zero:

py> import sys
py> epsilon = sys.float_info.epsilon
py> x = epsilon/1
py> x == 0
False
py> x * 3 == 0
False
py> x + epsilon == 0
False
py> x + epsilon == epsilon
False

The above logic throws away many perfectly good numbers and treats them 
as zero even though they aren't.


> The purpose of this snippet is to print the given line when allow_zero
> is False and x is 0.

Then the snippet utterly fails at that, since it prints the line for many 
values of x which can be distinguished from zero. The way to test whether 
x equals zero is:

x == 0

What the above actually tests for is whether x is so small that (1.0+x) 
cannot be distinguished from 1.0, which is not the same thing. It is also 
quite arbitrary. Why 1.0? Why not (0.0001+x)? Or (0.0001+x)? Or 
(1.0+x)?



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


Re: Short-circuit Logic

2013-05-26 Thread Steven D'Aprano
On Sun, 26 May 2013 16:22:26 -0400, Roy Smith wrote:

> In article ,
>  Terry Jan Reedy  wrote:
> 
>> On 5/26/2013 7:11 AM, Ahmed Abdulshafy wrote:
>> 
>> >   if not allow_zero and abs(x) < sys.float_info.epsilon:
>> >  print("zero is not allowed")
>> 
>> The reason for the order is to do the easy calculation first and the
>> harder one only if the first passes.
> 
> This is a particularly egregious case of premature optimization.  You're
> worried about how long it takes to execute abs(x)?  That's silly.

I don't think it's a matter of premature optimization so much as the 
general principle "run code only if it needs to run". Hence, first you 
check the flag to decide whether or not you care whether x is near zero, 
and *only if you care* do you then check whether x is near zero.

# This is silly:
if x is near zero:
if we care:
handle near zero condition()

# This is better:
if we care:
if x is near zero
handle near zero condition()


Not only is this easier to understand because it matches how we do things 
in the real life, but it has the benefit that if the "near zero" 
condition ever changes to become much more expensive, you don't have to 
worry about reordering the tests because they're already in the right 
order.



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


Re: Python error codes and messages location

2013-05-26 Thread Steven D'Aprano
On Mon, 27 May 2013 02:13:54 +0300, Carlos Nepomuceno wrote:

> Where can I find all error codes and messages that Python throws (actual
> codes and messages from exceptions raised by stdlib)?

There is no list. It is subject to change from version to version, 
including point releases.

Many functions and methods document which exceptions they can be expected 
to raise, or at least the *usual* exceptions, but many more do not. And 
the error messages themselves are implementation details and are subject 
to change without notice, even if the exception type is a documented part 
of the API.

You can see a full list of built-in exception types in the docs:

http://docs.python.org/3/library/exceptions.html

but of course since they are classes, they can be subclassed, and in 
principle a function that raises (say) ValueError might sometimes raise a 
subclass of ValueError without documenting it.

So the actual answer to your question is:

"Read the source code."


Sorry :-(


> I've already found the module 'errno' and got a dictionary
> (errno.errorcode) and some system error messages
> (os.strerror(errno.ENAMETOOLONG)) but there's more I couldn't find.

These are the standard C operating system and file system error codes, 
not Python exceptions.


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


Re: how to compare two json file line by line using python?

2013-05-26 Thread Steven D'Aprano
On Sun, 26 May 2013 21:32:40 -0700, Avnesh Shakya wrote:

> But I want to compare line by line and value by value. but i found that
> json data is unordered data, so how can i compare them without sorting
> it. please give me some idea about it. I am new for it. I want to check
> every value line by line.

Why do you care about checking every value line by line? As you say 
yourself, JSON data is unordered, so "line by line" is the wrong way to 
compare it.


The right way is to decode the JSON data, and then compare whether it 
gives you the result you expect:

a = json.load("file-a")
b = json.load("file-b")
if a == b:
print("file-a and file-b contain the same JSON data")

If what you care about is the *data* stored in the JSON file, this is the 
correct way to check it.

On the other hand, if you don't care about the data, but you want to 
detect changes to whitespace, blank lines, or other changes that make no 
difference to the JSON data, then there is no need to care that this is 
JSON data. Just treat it as text, and use the difflib library.

http://docs.python.org/2/library/difflib.html


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


Re: help?? on functions

2013-05-26 Thread Steven D'Aprano
On Sun, 26 May 2013 21:48:34 -0700, lokeshkoppaka wrote:

> def shuffle(input, i, j):
> pass
> input = input[i:j+1] +input[0:i] + input[j+1:]

"pass" does nothing. Take it out.



> def test_shuffle():
> input = [1, 2, 3, 4, 5, 6]
> shuffle(input, 1, 2)
> assert [2, 3, 1, 4, 5, 6] == input
> 
> 
> i had done the above code but the problem is i had manipulated the
> "input" in function shuffle(input, i, j) but once i get back to the
> test_shuffle() function again the variable "input" does not reflect the
> changes made in shuffle(input, i, j) why ,please can any one describe
> why . and help how to reflect that change to the variable "input".

The line of code:

input = input[i:j+1] +input[0:i] + input[j+1:]


takes the input list, makes three slices from that list, creates a new 
list, and then reassigns the LOCAL variable "input". This does not touch 
the variable on the outside of the function.

This will be more clear if you use different names:

# Outside the function.
mylist = [1, 2, 3, 4, 5, 6]
shuffle(mylist, 1, 2)


Inside the function "shuffle", "input" is a local variable, and when you 
reassign to it, the variable "mylist" on the outside is not changed. Try 
this small function to see what I mean:

def demo(input):
print('local variable, before:', input)
input = 100
print('local variable, after:', input)
print('non-local variable', mylist)


mylist = [1, 2, 3, 4, 5, 6]
demo(mylist)



So, what can you do to fix this? You have two choices:


1) You can return the shuffled list. Add this line to the end of your 
shuffle function:

return input


and then inside the test function, do this:

def test_shuffle():
input = [1, 2, 3, 4, 5, 6]
input = shuffle(input, 1, 2)
assert [2, 3, 1, 4, 5, 6] == input


2) You can modify the input list in place.

In this case, instead of reassigning the local variable "input" with the 
new list, you simply tell Python to stuff the new list inside the 
original list. You do that with a slice:


input[:] = input[i:j+1] + input[0:i] + input[j+1:]


That's a small difference from what you wrote, just three characters [:], 
but it makes a big difference in the effect. Instead of reassigning the 
local variable to the new list, it takes the existing list, and replaces 
each value inside it with the values taken from the new list. For example:


py> mylist = [100, 200, 300, 400, 500, 600]
py> mylist[3:5] = ['A', 'B', 'C']
py> mylist
[100, 200, 300, 'A', 'B', 'C', 600]

py> mylist[1:] = [99, 98, 97]
py> mylist
[100, 99, 98, 97]


Any questions?


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


Re: Python error codes and messages location

2013-05-27 Thread Steven D'Aprano
On Mon, 27 May 2013 13:46:50 +0100, Fábio Santos wrote:

> Speaking of PEPs and exceptions. When do we get localized exceptions? 


We're waiting for you to volunteer. When can you start?


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


Re: How to get an integer from a sequence of bytes

2013-05-27 Thread Steven D'Aprano
On Mon, 27 May 2013 16:45:05 +0200, Mok-Kong Shen wrote:

> From an int one can use to_bytes to get its individual bytes, but how
> can one reconstruct the int from the sequence of bytes?

Here's one way:

py> n = 11999102937234
py> m = 0
py> for b in n.to_bytes(6, 'big'):
... m = 256*m + b
...
py> m == n
True


-- 
Steven

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


Re: How to get an integer from a sequence of bytes

2013-05-27 Thread Steven D'Aprano
On Mon, 27 May 2013 11:30:18 -0400, Ned Batchelder wrote:

> On 5/27/2013 10:45 AM, Mok-Kong Shen wrote:
>> From an int one can use to_bytes to get its individual bytes, but how
>> can one reconstruct the int from the sequence of bytes?
>>
>>
> The next thing in the docs after int.to_bytes is int.from_bytes:

And I can't believe I missed that too :-(


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


Re: Python error codes and messages location

2013-05-28 Thread Steven D'Aprano
On Tue, 28 May 2013 17:15:51 +1000, Chris Angelico wrote:

> Can we internationalize English instead of localizing Python?

We have. English is the primary international language for programmers. 
(For which I am profoundly grateful.)

Japanese is also a pretty important language, but mostly in Japan. And 
China would like Chinese to be, in fact there is even a version of Python 
localised to Chinese:

http://www.chinesepython.org/


I have no objection to people creating their own, localised, 
implementation or fork of Python, in which case good luck to them but 
they're on their own. But I don't think that exceptions should otherwise 
be localised.



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


  1   2   3   4   5   6   7   8   9   10   >