How Do I get Know What Attributes/Functions In A Class?
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?
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?
Thank you All ! -- http://mail.python.org/mailman/listinfo/python-list
Source Encoding GBK/GB2312
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
Thank you All ! I am going to update ... -- http://mail.python.org/mailman/listinfo/python-list
Problem When Unit Testing with PMock
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
> 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
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?
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
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?
Thank You All -- http://mail.python.org/mailman/listinfo/python-list
Met Problem with Distutils
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)
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
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
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
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
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
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")
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
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
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
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
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
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?
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?
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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? ]
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? ]
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
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? ]
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
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
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
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
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?
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?
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?
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?
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
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?
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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??
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
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??
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??
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
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??
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??
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
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
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
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
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
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?
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
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
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
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
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
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