Can I run a python program from within emacs?
I have also just started with both Aquamacs and Python so I ask for your patience as well. When I evaluate the buffer (C-c C-C) I don't see any response or output from my python program. Should another buffer open automatically? Should a terminal window open? thanks for your patience. Rugbeia Floreat Ubique On Mar 20, 3:09 pm, jmDesktop wrote: > Hi, I'm trying to learn Python. I using Aquamac an emac > implementation with mac os x. I have a program. If I go to the > command prompt and type pythong myprog.py, it works. Can the program > be run from within the editor or is that not how development is done? > I ask because I was using Visual Studio with C# and, if you're > familiar, you just hit run and it works. On Python do I use the > editor for editing only and then run the program from the command > line? Thank you. Aquamacs, just like any variant of GNU Emacs, will show a Python menu. There's a "Start Interpreter" function, and one to evaluate the buffer (C-c C-c). It's pretty straightforward (a euphemism for obvious). If the Python menu doesn't show, then something is going wrong. M-x python-mode RET would switch it on. -- http://aquamacs.org -- Aquamacs: Emacs on Mac OS X http://aquamacs.org/donate -- Could we help you? Return the favor and support the Aquamacs Project! -- http://mail.python.org/mailman/listinfo/python-list
Re: Can I run a python program from within emacs?
Jason, Thanks, but I have already tried your suggestions (which seem like logical cause/effect actions) and nothing. There must be a python preference or something I haven't set correctly. There is no Aquamacs list, but I'll check further. Thanks again for the quick reply. On Nov 1, 2009, at 9:15 AM, Jason Sewall wrote: On Sun, Nov 1, 2009 at 9:20 AM, Robinson wrote: I have also just started with both Aquamacs and Python so I ask for your patience as well. When I evaluate the buffer (C-c C-C) I don't see any response or output from my python program. Should another buffer open automatically? Should a terminal window open? I don't know much about Aquamacs or the version of Emacs the Aquamacs you are using is based on, but the C-c C-c command runs py-execute-buffer. Try M-x py-execute-buffer and see what happens. It should pop up a *Python Output* buffer, unless you're actually running the python interpreter in Emacs, in which case the code is run in that buffer. If you're still having trouble, probably an Emacs or Aquamacs list is a better place to look. Jason -- http://mail.python.org/mailman/listinfo/python-list
Re: Negative array indicies and slice()
Ok, hopefully this is better. I love my own e-mail editor... I can see that the slice() function can pass in arbitrary arguments. I'm not sure for lists, which is what the range is applied to, why an argument like "a" would be part of a slice. I *really* don't see what the advantage of a slice class is over a mere list in the order of start, stop, step eg: [ 1,4,9 ] In a dictionary, where "a" could be a key -- I wasn't aware that there was a defined order that the idea of slice could apply to. When I look at the documentation, http://www.python.org/doc//current/c-api/slice The only thing that slice has which is special, is that the the length of the sequence can be given -- and the start and stop index are either trimmed or an error (exception???) is thrown. Where is the information on the more general case of slice()? :-\ I am thinking, can one use the 'super' type of access, to override -- within the list object itself -- the __getitem__ method, and after pre-processing -- call the shadowed method with the modified parameters? That would allow me to use the normal a[-4:6] notation, without having to write a wrapper class that must be explicitly called. I'm thinking something like, PyListObject.__getitem__= lambda self, slice: --Andrew. -- http://mail.python.org/mailman/listinfo/python-list
Re: Negative array indicies and slice()
On 10/29/2012 04:32 AM, Chris Angelico wrote: I wonder if what the OP is looking for is not slicing, but something more akin to map. Start with a large object and an iterator that produces keys, and create an iterator/list of their corresponding values. Something like: a=[1,2,3,4,5,6,7,8,9,10] b=[a[i] for i in xrange(-4,3)] It's not strictly a slice operation, but it's a similar sort of thing, and it can do the wraparound quite happily. ChrisA A list comprehension ? That does do what I am interested in, *very* much so. Quite a gem, Chris! :-\ I am curious as to how quickly it constructs the result compared to a slice operation. Eg: a[1:5] vs. [ a[i] for i in xrange[1:5] ] But, unless it were grossly slower -- so that if/then logic and slices were generally faster -- I will use it. Thanks. --Andrew. -- http://mail.python.org/mailman/listinfo/python-list
Re: Negative array indicies and slice()
On 10/29/2012 04:19 AM, Steven D'Aprano wrote: On Mon, 29 Oct 2012 00:54:29 -0700, Andrew wrote: Slices and iterators have different purposes and therefore have not been made interchangeable. Yes, there are certain similarities between a slice and xrange, but there are also significant differences. Aha, now were getting to the actual subject. [snip] In 'C', where Python is written, That's a popular misapprehension. Python is written in Java, or Lisp, or Haskell, or CLR (dot Net), or RPython, or Ocaml, or Parrot. Each of those languages have, or had, at least one Python implementation. Oh, there's also a version written in C, or so I have heard. :-P I didn't say it was only written in "C", but in "C" where it is implemented. I will be porting Python 3.xx to a super low power embedded processor (MSP430), both space and speed are at a premium. Running Python on top of Java would be a *SERIOUS* mistake. .NET won't even run on this system. etc. Thank you for the code snippet; I don't think it likely that existing programs depend on nor use a negative index and a positive index expecting to take a small chunk in the center... On the contrary. That is the most straightforward and useful idea of slicing, to grab a contiguous slice of items. Show me an example where someone would write a slice with a negative and a positive index (both in the same slice); and have that slice grab a contiguous slice in the *middle* of the list with orientation of lower index to greater index. I have asked before; It's not that I don't think it possible -- it's that I can't imagine a common situation. Why would you want to grab a slice from the end of the list, and a slice from the start of the list, and swap them around? Apart from simulating card shuffles and cuts, who does that? Advanced statistics programmers using lookup tables that are symmetrical. Try Physicists too -- but they're notably weird. My intended inferences about the iterator vs. slice question was perhaps not obvious to you; Notice: an iterator is not *allowed* in __getitem__(). Actually, you can write __getitem__ for your own classes to accept anything you like. Yes, I realize that. But, why can't I just overload the existing __getitem__ for lists and not bother writing an entire class? Everything in Python is supposed to be an object and one of the big supposed "selling" points is the ability to overload "any" object's methods. The lists aren't special -- they're just a bunch of constant decimal numbers, typically given as a large tuple. py> class Test: ... def __getitem__(self, index): ... return index ... Better: >>> class Test: ... def __getitem__( self, *index ): ... return index No extra curlies required... You say that as if it were a bad thing. hmmm... and you as if sarcastic? :-) It is a bad thing to have any strictly un-necessary and non-code saving objects where memory is restricted. What existing class is that? It certainly isn't xrange. Because xrange represents a concrete sequence of numbers, all three of start, end and stride must be concrete, known, integers: Let's up the ante. I'll admit xrange() won't do "later" fill in the blank -- BUT -- xrange() is a subclass of an *existing* class called iterator. Iterators are very general. They can even be made random. The philosophy of Python is to have exactly one way to do something when possible; so, why create a stand alone class that does nothing an existing class could already do, and do it better ? py> xrange(4, None, 2) Traceback (most recent call last): File "", line 1, in TypeError: an integer is required Hmmm.. Let's try your example exactly as shown... "hello world"[aslice] Traceback (most recent call last): File "", line 1, in NameError: name 'aslice' is not defined WOW. Cool. Where did the blanks *actually* get filled in? Or HOW WILL they in your next post? On the contrary, a simple list of three values not only could not do everything a slice does, but it's over twice the size! Yeah, There is a definite issue there. But the case isn't decided by that number alone. A slice is storing three integers -- and an integer is size is 12. So, slices don't use integers. If the type that *IS* used happens to be a real Python type, we may merely typecast integers to that type -- insert them in a tuple and by definition, they must be the same size. Looking at some of the online programming notes -- a slice apparently doesn't use an integer storage variable that is capable of arbitrary expansion. =-O -- and hence, won't work for very large sized lists. That actually explains some crashes I have noted in the past when working with 20 million element lists that I wanted a slice of. I had *plenty* of ram on that system. Besides: The program code to implement slice() is undoubtedly larger than 12 bytes of savings! How many slices() are typically found in memory simultaneously? Yo
Re: I need help installing pypng in Python 3.3
On 10/29/2012 05:23 AM, icgwh wrote: Hello all, I am very new to python. I am currently porting a little project of mine from java to python and I need to be able to construct and write png images. I naturally turned myself toward pypng to accomplish this. I don't know if this will help, but: There is a package called image magic; which can convert any image to any other type of image. If that would not be a burden to install (most OS's have pre-compiled working binaries) -- you could easily write a portable bitmap file to disk using python (even without a library) -- and then convert it to png. I have a little script I wrote in python to create a canvas, and allow you to draw on it using very simple line drawing primitives, and then save it to PBM. It's simple enough (only draws lines with different pens) that you could examine it and write your own script to do the same or better. If this interests you, I will see if I can post the py script; or email it to you. --Andrew. -- http://mail.python.org/mailman/listinfo/python-list
Re: I need help installing pypng in Python 3.3
On 10/29/2012 06:39 AM, ic...@tagyourself.com wrote: That's very kind of you but I don't think it would be particularly fitted to my needs. The program I'm trying to code creates an image as an 2D array of "pixels" which is defined by RGBA value. My program needs to access and modifies every component of every pixels in the image following a set of rules, kind of like the game of life, only more complex. In fact I only need a library to "push" this array of pixels in a displayable format for the GUI and in PNG format to write the image to disk. I don't need to do any fancy stuff with the image, just being able to display and write it. Then, actually, what I am suggesting was *almost* perfect. To do transparency, you need to write the portable any map (PAM) formation. Simply print a text header to a file which says: P7 WIDTH 10 HEIGHT 10 DEPTH 4 MAXVAL 255 TUPLTYPE RGB_ALPHA ENDHDR And then dump your 2D array to that same file. A very quick example in 17 lines of code: io = open( "anyname.pam","w") x,y = 10,10 gray=(128,128,128,255) # R,G,B,A value picture = [ [ gray ] * x ] * y # Make a blank gray canvas 2D array # Do whatever you want to the 2D picture array here! io.write( "P7\nWIDTH %d\nHEIGHT %d\nDEPTH 4\nMAXVAL 255\nTUPLTYPE RGB_ALPHA\nENDHDR\n" % (x,y) ) for yi in xrange( y ): for xi in xrange( x ): pixel = picture[yi][xi] io.write( chr(pixel[0]) ) # R value io.write( chr(pixel[1]) ) # G value io.write( chr(pixel[2]) ) # B value io.write( chr(pixel[3]) ) # A value io.flush() io.close() And that's it. You may of course make this more efficient -- I'm just showing it this way for clarity. Many programs can read PAM directly; but for those that can't you can use nettools, or imagemagick, to convert it to PNG. -- http://mail.python.org/mailman/listinfo/python-list
Re: Negative array indicies and slice()
On 10/29/2012 06:52 AM, Roy Smith wrote: Show me an example where someone would write a slice with a negative and a positive index (both in the same slice); and have that slice grab a contiguous slice in the *middle* of the list with orientation of lower index to greater index. It's possible in bioinformatics. ... eq[100:-100]. I decided to go to bed... I was starting to write very badly worded responses. :) Thanks, Roy, what you have just shown is another example that agrees with what I am trying to do. FYI: I was asking for a reason why Python's present implementation is desirable... I wonder, for example: Given an arbitrary list: a=[1,2,3,4,5,6,7,8,9,10,11,12] Why would someone *want* to do: a[-7,10] Instead of saying a[5:10] or a[-7:-2] ? eg: What algorithm would naturally *desire* the default behavior of slicing when using *mixed* negative and positive indexes? In the case of a bacterial circular DNA/RNA ring, asking for codons[ -10: 10 ] would logically desire codon[-10:] + codon[:10] not an empty list, right? I think your example is a very reasonable thing the scientific community would want to do with Python. :) -- http://mail.python.org/mailman/listinfo/python-list
Re: Negative array indicies and slice()
On 10/29/2012 10:09 AM, Ian Kelly wrote: On Oct 29, 2012 7:10 AM, "Andrew Robinson" wrote: I will be porting Python 3.xx to a super low power embedded processor (MSP430), both space and speed are at a premium. Running Python on top of Java would be a *SERIOUS* mistake. .NET won't even run on this system. etc. If that's the case, then running Python at all is probably a mistake. You know the interpreter alone has an overhead of nearly 6 MB? There's already a version of the python interpreter which fits in under 100K: http://code.google.com/p/python-on-a-chip/ It's not the 3.x series, though; and I don't want to redo this once 2.7 really does become obsolete. Yes, I realize that. But, why can't I just overload the existing __getitem__ for lists and not bother writing an entire class? You can just overload that one method in a subclass of list. Being able to monkey-patch __getitem__ for the list class itself would not be advisable, as it would affect all list slicing anywhere in your program and possibly lead to some unexpected behaviors. That's what I am curious about. What unexpected behaviors would a "monkey patch" typically cause? If no one really uses negative and positive indexes in the same slice operation, because there is no reason to do so... It will only break the occasional esoteric application. 20 million is nothing. On a 32-bit system, sys.maxsize == 2 ** 31 - 1. If the error you were seeing was MemoryError, then more likely you were running into dynamic allocation issues due to fragmentation of virtual memory. No, there was no error at all. Pthon just crashed & exited; not even an exception that I can recall. It was if it exited normally! The list was generated in a single pass by many .append() 's, and then copied once -- the original was left in place; and then I attempted to slice it. I am able to routinely to 5 million length lists, copy, slice, cut, append, and delete from them without this ever happening. If fragmentation were the issue, I'd think the shorter lists would cause the problem after many manipulations... It may not be a bug in python itself, though, of course. There are libraries it uses which might have a bug. -- http://mail.python.org/mailman/listinfo/python-list
Re: Negative array indicies and slice()
On 10/29/2012 06:53 AM, Chris Angelico wrote: Can you provide links to these notes? I'm looking at cpython/Include/sliceobject.h that has this comment: /* A slice object containing start, stop, and step data members (the names are from range). After much talk with Guido, it was decided to let these be any arbitrary python type. Py_None stands for omitted values. */ Also, the code for slice objects in CPython works with Py_ssize_t (a signed quantity of the same length as size_t), which will allow at least 2**31 for an index. I would guess that your crashes were nothing to do with 20 million elements and slices. ChrisA Let's look at the source code rather than the web notes -- the source must be the true answer anyhow. I downloaded the source code for python 3.3.0, as the tbz; In the directory "Python-3.3.0/Python", look at Python-ast.c, line 2089 & ff. Clearly a slice is malloced for a slice_ty type. It has four elements: kind, lower, upper, and step. So, tracing it back to the struct definition... "Include/Python-ast.h" has "typedef struct _slice *slice_ty;" And, here's the answer!: enum _slice_kind {Slice_kind=1, ExtSlice_kind=2, Index_kind=3}; struct _slice { enum _slice_kind kind; union { struct { expr_ty lower; expr_ty upper; expr_ty step; } Slice; struct { asdl_seq *dims; } ExtSlice; struct { expr_ty value; } Index; } v; }; So, slice() does indeed have arbitrary python types included in it; contrary to what I read elsewhere. expr_ty is a pointer to an arbitrary expression, so the actual structure is 4 pointers, at 32 bits each = 16 bytes. The size of the structure itself, given in an earlier post, is 20 bytes -- which means one more pointer is involved, perhaps the one pointing to the slice structure itself. Hmm...! An empty tuple gives sys.getsizeof( () ) = 24. But, I would expect a tuple to be merely a list of object pointers; hence I would expect 4 bytes for len(), and then a head pointer 4 bytes, and then a pointer for each object. 3 objects gives 12 bytes, + 8 = 16 bytes. Then we need one more pointer so Python knows where the struct is... So a Tuple of 3 objects ought to fit nicely into 20 bytes; the same size as slice() -- but it's 24, even when empty... And 36 when initialized... What are the extra 16 bytes for? All I see is: typedef struct { object** whatever } PyTupleObject; -- http://mail.python.org/mailman/listinfo/python-list
Re: Negative array indicies and slice()
On 10/29/2012 05:02 PM, Steven D'Aprano wrote: On Mon, 29 Oct 2012 08:42:39 -0700, Andrew Robinson wrote: But, why can't I just overload the existing __getitem__ for lists and not bother writing an entire class? You say that as if writing "an entire class" was a big complicated effort. It isn't. It is trivially simple, a single line: class MyList(list): ... No, I don't think it big and complicated. I do think it has timing implications which are undesirable because of how *much* slices are used. In an embedded target -- I have to optimize; and I will have to reject certain parts of Python to make it fit and run fast enough to be useful. You can just overload that one method in a subclass of list. Being able to monkey-patch __getitem__ for the list class itself would not be advisable, as it would affect all list slicing anywhere in your program and possibly lead to some unexpected behaviors. That's what I am curious about. What unexpected behaviors would a "monkey patch" typically cause? What part of "unexpected" is unclear? Ahh -- The I don't know approach! It's only unexpected if one is a bad programmer...! Let me see if I can illustrate a flavour of the sort of things that can happen if monkey-patching built-ins were allowed. You create a list and print it: # simulated output py> x = [5, 2, 4, 1] py> print(x) [1, 2, 4, 5] Finally you search deep into the libraries used in your code, and *five days later* discover that your code uses library A which uses library B which uses library C which uses library D which installs a harmless monkey-patch to print, but only if library E is installed, and you just happen to have E installed even though your code never uses it, AND that monkey-patch clashes with a harmless monkey-patch to list.__getitem__ installed by library F. And even though each monkey-patch alone is harmless, the combination breaks your code's output. Right, which means that people developing the libraries made contradictory assumptions. Python allows, but does not encourage, monkey-patching of code written in pure Python, because it sometimes can be useful. It flat out prohibits monkey-patching of builtins, because it is just too dangerous. Ruby allows monkey-patching of everything. And the result was predictable: http://devblog.avdi.org/2008/02/23/why-monkeypatching-is-destroying-ruby/ I read that post carefully; and the author purposely notes that he is exaggerating. BUT Your point is still well taken. What you are talking about is namespace preservation; and I am thinking about it. I can preserve it -- but only if I disallow true Python primitives in my own interpreter; I can't provide two sets in the memory footprint I am using. From my perspective, the version of Python that I compile will not be supported by the normal python help; The predecessor which first forged this path, Pymite, has the same problems -- however, the benefits ought-weigh the disadvantages; and the experiment yielded useful information on what is redundant in Python (eg: range is not supported) and when that redundancy is important for some reason. If someone had a clear explanation of the disadvantages of allowing an iterator, or a tuple -- in place of a slice() -- I would have no qualms dropping the subject. However, I am not finding that yet. I am finding very small optimization issues... The size of an object is at least 8 bytes. Hence, three numbers is going to be at least 24 bytes; and that's 24 bytes in *excess* of the size of slice() or tuple () which are merely containers. So -- There *ARE* savings in memory when using slice(), but it isn't really 2x memory -- its more like 20% -- once the actual objects are considered. The actual *need* for a slice() object still hasn't been demonsrated. I am thinking that the implementation of __getitem__() is very poor probably because of legacy issues. A tuple can also hold None, so ( 1, None, 2 ) is still a valid Tuple. Alternately: An iterator, like xrange(), could be made which takes None as a parameter, or a special value like 'inf'. Since these two values would never be passed to xrange by already developed code, allowing them would not break working code. I am only aware of one possible reason that slice() was once thought to be necessary; and that is because accessing the element of a tuple would recursively call __getitem__ on the tuple. But, even that is easily dismissed once the fixed integer indexes are considered. Your thoughts? Do you have any show stopper insights? -- http://mail.python.org/mailman/listinfo/python-list
Re: Negative array indicies and slice()
On 10/29/2012 06:49 PM, Chris Kaynor wrote: Every Python object requires two pieces of data, both of which are pointer-sized (one is a pointer, one is an int the size of a pointer). These are: a pointer to the object's type, and the object's reference count. A tuple actually does not need a head pointer: the head pointer is merely an offset from the tuple's pointer. It merely has a ref count, type, an item count, and pointers to its contents. A slice has the same type pointer and reference count, then three pointers to the start, stop, and step objects. This means a slice object should be the same size as a two-item tuple: the tuple needs a count, while that is fixed at 3 for a slice (though some items may be unset). NOTE: The above is taken from reading the source code for Python 2.6. For some odd reason, I am getting that an empty tuple consists of 6 pointer-sized objects (48 bytes on x64), rather than the expected 3 pointer-sized (24 bytes on x64). Slices are showing up as the expected 5 pointer-sized (40 bytes on x64), and tuples grow at the expected 1 pointer (8 bytes on x64) per item. I imagine I am missing something, but cannot figure out what that would be. All I see is: typedef struct { object** whatever } PyTupleObject; It's fairly straight forward in 3.2.0. I debugged the code with GDB and watched. Perhaps it is the same in 2.6 ? In addition to those items you mention, of which the reference count is not even *inside* the struct -- there is additional debugging information not mentioned. Built in objects contain a "line number", a "column number", and a "context" pointer. These each require a full word of storage. Also, built in types appear to have a "kind" field which indicates the object "type" but is not a pointer. That suggests two "object" type indicators, a generic pointer (probably pointing to "builtin"? somewhere outside the struct) and a specific one (an enum) inside the "C" struct. Inside the tuple struct, I count 4 undocumented words of information. Over all, there is a length, the list of pointers, a "kind", "line", "col" and "context"; making 6 pieces in total. Although your comment says the head pointer is not required; I found in 3.3.0 that it is a true head pointer; The Tuple() function on line 2069 of Python-ast.c, (3.3 version) -- is passed in a pointer called *elts. That pointer is copied into the Tuple struct. How ironic, slices don't have debugging info, that's the main reason they are smaller. When I do slice(3,0,2), suprisingly "Slice()" is NOT called. But when I do a[1:2:3] it *IS* called. -- http://mail.python.org/mailman/listinfo/python-list
Re: Negative array indicies and slice()
Hi Ian, There are several interesting/thoughtful things you have written. I like the way you consider a problem before knee jerk answering. The copying you mention (or realloc) doesn't re-copy the objects on the list. It merely re-copies the pointer list to those objects. So lets see what it would do... I have seen doubling as the supposed re-alloc method, but I'll assume 1.25 -- so, 1.25**x = 20million, is 76 copies (max). The final memory copy would leave about a 30MB hole. And my version of Python operates initially with a 7MB virtual footprint. Sooo If the garbage collection didn't operate at all, the copying would waste around: >>> z,w = 30e6,0 >>> while (z>1): w,z = w+z, z/1.25 ... >>> print(w) 14995.8589521 eg: 150MB cummulative. The doubles would amount to 320Megs max. Not enough to fill virtual memory up; nor even cause a swap on a 2GB memory machine. It can hold everything in memory at once. So, I don't think Python's memory management is the heart of the problem, although memory wise-- it does require copying around 50% of the data. As an implementation issue, though, the large linear array may cause wasteful caching/swapping loops, esp, on smaller machines. On 10/29/2012 10:27 AM, Ian Kelly wrote: Yes, I misconstrued your question. I thought you wanted to change the behavior of slicing to wrap around the end when start> stop instead of returning an empty sequence. ... Chris has already given ... You could also use map for this: new_seq = list(map(old_seq.__getitem__, iterable)) MMM... interesting. I am not against changing the behavior, but I do want solutions like you are offering. As I am going to implement a python interpreter, in C, being able to do things differently could significantly reduce the interpreter's size. However, I want to break existing scripts very seldom... I'm aware of what is possible in C with pointer arithmetic. This is Python, though, and Python by design has neither pointers nor pointer arithmetic. In any case, initializing the pointer to the end of the array would still not do what you want, since the positive indices would then extend past the end of the array. Yes, *and* if you have done assembly language programming -- you know that testing for sign is a trivial operation. It doesn't even require a subtraction. Hence, at the most basic machine level -- changing the base pointer *once* during a slice operation is going to be far more efficient than performing multiple subtractions from the end of an array, as the Python API defines. I'll leave out further gory details... but it is a Python interpreter built in "C" issue. -- http://mail.python.org/mailman/listinfo/python-list
Re: Negative array indicies and slice()
On 10/29/2012 04:01 PM, Ian Kelly wrote: On Mon, Oct 29, 2012 at 9:20 AM, Andrew Robinson wrote: FYI: I was asking for a reason why Python's present implementation is desirable... I wonder, for example: Given an arbitrary list: a=[1,2,3,4,5,6,7,8,9,10,11,12] Why would someone *want* to do: a[-7,10] Instead of saying a[5:10] or a[-7:-2] ? A quick search of local code turns up examples like this: if name.startswith('{') and name.endswith('}'): name = name[1:-1] Which is done to avoid explicitly calling the len() operator. If slices worked like ranges, then the result of that would be empty, which is obviously not desirable. Yes, and that's an excellent point -- but note what I am showing in the example. It is that example, which I am specifying. There are only two cases where I think the default behavior of Python gives undesirable results: The step is positive, and the pair of indexes goes from negative to positive. Likewise, If the pair went from positive to negative, and the step was negative. In all other combinations, the default behavior of python ought to remain intact. I apologize for not making this crystal clear -- I thought you would focus on the specific example I gave. I don't know of a reason why one might need to use a negative start with a positive stop, though. I've already given several examples; and another poster did too -- eg: Gene sequences for bacteria. It's not uncommon to need this. If I do some digging, I can also show some common graphics operations that benefit greatly from this ability -- NOTE: in another thread I just showed someone how to operate on RGBA values... Slicing becomes THE major operation done when converting, or blitting, graphics data. etc. Another example -- Jpeg, for example, uses discrete cosines -- which are a naturally cyclic data type. They repeat with a fixed period. I know there are "C" libraries already made for Jpeg -- but that doesn't mean many other applications with no "C" library aren't plagued by this problem. I don't know how to make this point more clear. There really *ARE* applications that uses cyclic lists of data; or which can avoid extra logic to fix problems encountered from linear arrays which *end* at a particular point. sometimes it is desirable for a truncation to occur, sometimes it's NOT. The sign convention test I outlined, I believe, clearly detects when a cyclic data set is desired. If there are normal examples where my tests fail -- that's what's important to me. -- http://mail.python.org/mailman/listinfo/python-list
Re: Negative array indicies and slice()
On 10/29/2012 10:53 PM, Michael Torrie wrote: On 10/29/2012 01:34 PM, Andrew Robinson wrote: No, I don't think it big and complicated. I do think it has timing implications which are undesirable because of how *much* slices are used. In an embedded target -- I have to optimize; and I will have to reject certain parts of Python to make it fit and run fast enough to be useful. Since you can't port the full Python system to your embedded machine anyway, why not just port a subset of python and modify it to suit your needs right there in the C code. It would be a fork, yes, You're exactly right; That's what I *know* I am faced with. Without a libc, an MMU on the CPU, and a kernel, it's not going to just compile and run. I have libc. The MMU is a problem; but the compiler implements the standard "C" math library; floats, though, instead of doubles. That's the only problem -- there. What you want with slicing behavior changes has no place in the normal cPython implementation, for a lot of reasons. The main one is that it is already possible to implement what you are talking about in your own python class, which is a fine solution for a normal computer with memory and CPU power available. If the tests I outlined in the previous post inaccurately describe a major performance improvement and at least a modest code size reduction; or will *often* introduce bugs -- I *AGREE* with you. Otherwise, I don't. I don't think wasting extra CPU power is a good thing -- Extra CPU power can always be used by something else I won't belabor the point further. I'd love to see a counter example to the specific criteria I just provided to IAN -- it would end my quest; and be a good reference to point others to. -- http://mail.python.org/mailman/listinfo/python-list
Re: Negative array indicies and slice()
On 10/29/2012 11:51 PM, Ian Kelly wrote: On Mon, Oct 29, 2012 at 4:39 PM, Andrew Robinson As above, you're looking at the compiler code, which is why you're finding things like "line" and "column". The tuple struct is defined in tupleobject.h and stores tuple elements in a tail array. If you re-check my post to chris, I listed the struct you mention. The C code is what is actually run (by GDB breakpoint test) when a tuple is instantiated. If the tuple were stripped of the extra data -- then it ought to be as small as slice(). But it's not as small -- so either the sys.getsizeof() is lying -- or the struct you mention is not complete. Which? --Andrew. -- http://mail.python.org/mailman/listinfo/python-list
Re: Negative array indicies and slice()
On 10/30/2012 11:02 AM, Ian Kelly wrote: On Tue, Oct 30, 2012 at 10:14 AM, Ethan Furman wrote: File a bug report? Looks like it's already been wontfixed back in 2006: http://bugs.python.org/issue1501180 Thanks, IAN, you've answered the first of my questions and have been a great help. (And yes, I was debugging interactive mode... I took a nap after writing that post, as I realized I had reached my 1 really bad post for the day... ) I at least I finally know why Python chooses to implement slice() as a separate object from tuple; even if I don't like the implications. I think there are three main consequences of the present implementation of slice(): 1) The interpreter code size is made larger with no substantial improvement in functionality, which increases debugging effort. 2) No protection against perverted and surprising (are you surprised?! I am) memory operation exists. 3) There is memory savings associated with not having garbage collection overhead. D'Apriano mentioned the named values, start, stop, step in a slice() which are an API and legacy issue; These three names must also be stored in the interpreter someplace. Since slice is defined at the "C" level as a struct, have you already found these names in the source code (hard-coded), or are they part of a .py file associated with the interface to the "C" code? -- http://mail.python.org/mailman/listinfo/python-list
Re: Negative array indicies and slice()
On 10/30/2012 01:17 AM, Steven D'Aprano wrote: By the way Andrew, the timestamps on your emails appear to be off, or possibly the time zone. Your posts are allegedly arriving before the posts you reply to, at least according to my news client. :D -- yes, I know about that problem. Every time I reboot it shows up again... It's a distribution issue, my hardware clock is in local time -- but when the clock is read by different scripts in my distribution, some refuse to accept that the system clock is not UTC. I'll be upgrading in a few weeks -- so I'm just limping along until then. My apology. Then I look forward to seeing your profiling results that show that the overhead of subclassing list is the bottleneck in your application. Until then, you are making the classic blunder of the premature optimizer: "More computing sins are committed in the name of efficiency (without necessarily achieving it) than for any other single reason — including blind stupidity." — W.A. Wulf I'm sure that's true. Optimization, though, is a very general word. On a highway in my neighborhood -- the government keeps trying to put more safety restrictions on it, because it statistically registers as the "highest accident rate road" in the *entire* region. Naturally, the government assumes that people in my neighborhood are worse drivers than usual and need to be policed more -- but the truth is, that highway is the *ONLY* access road in the region for dozens of miles in any direction for a densely populated area, so if there is going to be an accident it will happen there; the extra safety precautions are not necessary when the accident rate is looked at from a per-capita perspective of those driving the highway. I haven't made *the* blunder of the premature optimizer because I haven't implemented anything yet. Premature optimizers don't bother to hold public conversation and take correction. OTOH: people who don't ever optimize out of fear, pay an increasing bloat price with time. I am not impressed by performance arguments when you have (apparently) neither identified the bottlenecks in your code, nor even measured the performance. Someone else already did a benchmark between a discrete loop and a slice operation. The difference in speed was an order of magnitude different. I bench-marked a map operation, which was *much* better -- but also still very slow in comparison. Let's not confound an issue here -- I am going to implement the python interpreter; and am not bound by optimization considerations of the present python interpreter -- There are things I can do which as a python programmer -- you can't. I have no choice but to re-implement and optimize the interpreter -- the question is merely how to go about it. You are essentially *guessing* where the bottlenecks are, and *hoping* that some suggested change will be an optimization rather than a pessimization. Of course I may be wrong, and you have profiled your code and determined that the overhead of inheritance is a problem. If so, that's a different ball game. But your posts so far suggest to me that you're trying to predict performance optimizations rather than measure them. Not really; Inheritance itself and it's timing aren't my main concern. Even if the time was *0* that wouldn't change my mind. There are man hours in debugging time caused by not being able to wrap around in a slice. (I am not ignoring the contrary man hours of an API change's bugs). Human psychology is important; and it's a double edged sword. I would refer you to a book written by Steve Maguire, Writing Solid Code; Chapter 5; Candy machine interfaces. He uses the "C" function "realloc()" as an excellent example of a bad API; but still comments on one need that it *does* fulfill -- "I've found it better to have one function that both shrinks and expands blocks so that I don't have to write *ifs* constructs every time I need to resize memory. True, I give up some extra argument checking, but this is offset by the *ifs* that I no longer need to write (*and possibly mess up*). * Extra steps that a programmer must take to achieve a task are places where bugs get introduced. * API's which must be debugged to see what particular operation it is performing rather than knowing what that operation is from looking at the un-compiled code are places where bugs get introduced. These two points are not friendly with each other -- they are in fact, generally in conflict. Right, which means that people developing the libraries made contradictory assumptions. Not necessarily. Not only can monkey-patches conflict, but they can combine in bad ways. It isn't just that Fred assumes X and Barney assumes not-X, but also that Fred assumes X and Barney assumes Y and *nobody* imagined that there was some interaction between X and Y. They *STILL* made contradictory assumptions; each of them assumed the interaction mechanism would not be applied i
Re: Negative array indicies and slice()
On 10/30/2012 04:48 PM, Mark Lawrence wrote: On 30/10/2012 15:47, Andrew Robinson wrote: I would refer you to a book written by Steve Maguire, Writing Solid Code; Chapter 5; Candy machine interfaces. The book that took a right hammering here http://accu.org/index.php?module=bookreviews&func=search&rid=467 ? Yes, although Chapter 5 is the one where the realloc() issue is discussed. If you have a library, see if you can check the book out -- rather than spend $$$ on it. But, in good humor -- Consider the only criticism the poster mentioned about chapter 5's contents. Occasionally, he presents a code fragment with a subtle bug, such as: p = realloc(p,n); _I have to admit that I didn't spot the bug_, but then I never use realloc, knowing it to have pitfalls. What is the bug? If realloc cannot allocate the memory, it returns NULL and the assignment means you lose your original pointer. What are the pitfalls? Realloc may or may not copy the data to a new, larger, area of memory and return the address of that: many programmers forget this and end up with pointers into the old, deallocated, area. Even those programmers who remember will likely fall into the trap that Maguire shows. _Back to 'clever' code though, he prefers_: His critique is a bit like the scene in Monty Python's the Life of Br..an... Where the aliens come, and crash, and leave -- and is totally irrelevant to what the plot-line is in the movie. What does this comment have to do with a critique??? McGuire didn't fail to notice the bug! But the critic doesn't even notice the main *pointS* the author was trying to make in that chapter. There are, to be sure, recommendations that I don't agree with in the book; He doesn't seem to do much Unit testing, postmortems, etc. are all topics that I studied in a formal class on Software Engineering. It was a wider perspective than McGuire brings to his book; But that doesn't mean McGuire has nothing valuable to say! A short Python Homage for readers of the linked Critique! : I've had to follow GPL project style rules where the rule for a weird situation would be: while (*condition) /* nothing */ ; // and yes, this will sometimes generate a warning... But, I have enough brains to take McGuire's *suggestion* to an improved Python conclusion. #define PASS(x) {(void)NULL;} while (*condition) PASS( Gas ); // There will be no warning -- http://mail.python.org/mailman/listinfo/python-list
RE: Negative array indicies and slice()
Ian, > Looks like it's already been wontfixed back in 2006: > http://bugs.python.org/issue1501180 Absolutely bloody typical, turned down because of an idiot. Who the hell is Tim Peters anyway? > I don't really disagree with him, anyway. It is a rather obscure bug > -- is it worth increasing the memory footprint of slice objects by 80% > in order to fix it? :D In either event, a *bug* does exist (at *least* 20% of the time.) Tim Peters could have opened the *appropriate* bug complaint if he rejected the inappropriate one. The API ought to have either 1) included the garbage collection, or 2) raised an exception anytime dangerous/leaky data was supplied to slice(). If it is worth getting rid of the 4 words of extra memory required for the GC -- on account of slice() refusing to support data with sub-objects; then I'd also point out that a very large percentage of the time, tuples also contain data (typically integers or floats,) which do not further sub-reference objects. Hence, it would be worth it there too. OTOH, if the GC is considered acceptable in non-sub-referenced tuples, GC ought to be acceptable in slice() as well. Inconsistency is the mother of surprises; and code bloat through exceptions Note that the slice API also includes the slice.indices method. They also implement rich comparisons, but this appears to be done by copying the data to tuples and comparing the tuples, which is actually a bit ironic considering this discussion. Yes, indeed! I didn't mention the slice.indicies method -- as it's purpose is traditionally to *directly* feed the parameters of xrange or range. ( I thought that might start a WAR! ). :D http://docs.python.org/release/2.3.5/whatsnew/section-slices.html class FakeSeq: ... return FakeSeq([self.calc_item(i) for i in_range(*indices)_]) else: return self.calc_item(i) And here I'm wondering why we can't just pass range into it directly... :( I came across some unexpected behavior in Python 3.2 when experimenting with ranges and replacement Consider, xrange is missing, BUT: >>> a=range(1,5,2) >>> a[1] 3 >>> a[2] 5 >>> a[1:2] range(3, 5, 2) Now, I wondered if it would still print the array or not; eg: if this was a __str__ issue vs. __repr__. >>> print( a[1:2] ) # Boy, I have to get used to the print's parenthesis range(3, 5, 2) So, the answer is *NOPE*. I guess I need to read the doc's all over again... it's ... well, quite different. --Andrew. -- http://mail.python.org/mailman/listinfo/python-list
Re: Negative array indicies and slice()
On 10/30/2012 10:29 PM, Michael Torrie wrote: As this is the case, why this long discussion? If you are arguing for a change in Python to make it compatible with what this fork you are going to create will do, this has already been fairly thoroughly addressed earl on, and reasons why the semantics will not change anytime soon have been given. I'm not arguing for a change in the present release of Python; and I have never done so. Historically, if a fork happens to produce something surprisingly _useful_; the main code bank eventually accepts it on their own. If a fork is a mistake, it dies on its own. That really is the way things ought to be done. include this The Zen of Python, by _Tim Peters_ Special cases aren't special enough to break the rules. Although _practicality beats purity_. Now, I have seen several coded projects where the idea of cyclic lists is PRACTICAL; and the idea of iterating slices may be practical if they could be made *FASTER*. These warrant looking into -- and carefully; and that means making an experimental fork; preferably before I attempt to micro-port the python. Regarding the continuing discussion: The more I learn, the more informed decisions I can make regarding implementation. I am almost fully understanding the questions I originally asked, now. What remains are mostly questions about compatibility wrappers, and how to allow them to be used -- or selectively deleted when not necessary; and perhaps a demonstration or two about how slices and named tuples can (or can't) perform nearly the same function in slice processing. -- http://mail.python.org/mailman/listinfo/python-list
Re: Negative array indicies and slice()
On 10/31/2012 02:20 PM, Ian Kelly wrote: On Wed, Oct 31, 2012 at 7:42 AM, Andrew Robinson wrote: Then; I'd note: The non-goofy purpose of slice is to hold three data values; They are either numbers or None. These *normally* encountered values can't create a memory loop. So, FOR AS LONG, as the object representing slice does not contain an explicit GC pair; I move that we mandate (yes, in the current python implementation, even as a *fix*) that its named members may not be assigned any objects other than None or numbers eg: Lists would be forbidden Since functions, and subclasses, can be test evaluated by int( the_thing_to_try ) and *[] can too, generality need not be lost for generating nothing or numbers. PEP 357 requires that anything implementing the __index__ special method be allowed for slicing sequences (and also that __index__ be used for the conversion). For the most part, that includes ints and numpy integer types, but other code could be doing esoteric things with it. I missed something... (but then that's why we're still talking about it...) Reading the PEP, it notes that *only* integers (or longs) are permitted in slice syntax. (Overlooking None, of course... which is strange...) The PEP gives the only exceptions as objects with method "__index__". Automatically, then, an empty list is forbidden (in slice syntax). However, What you did, was circumvent the PEP by passing an empty list directly to slice(), and avoiding running it through slice syntax processing. So... Is there documentation suggesting that a slice object is meant to be used to hold anything other than what comes from processing a valid slice syntax [::]??. (we know it can be done, but that's a different Q.) The change would be backward-incompatible in any case, since there is certainly code out there that uses non-numeric slices -- one example has already been given in this thread. Hmmm. Now, I'm thinking -- The purpose of index(), specifically, is to notify when something which is not an integer may be used as an index; You've helpfully noted that index() also *converts* those objects into numbers. Ethan Fullman mentioned that he used the names of fields, "instead of having to remember the _offsets_"; Which means that his values _do convert_ to offset numbers His example was actually given in slice syntax notation [::]. Hence, his objects must have an index() method, correct?. Therefore, I still see no reason why it is permissible to assign non-numerical (non None) items as an element of slice(). Or, let me re-word that more clearly -- I see no reason that slice named members when used as originally intended would ever need to be assigned a value which is not *already* converted to a number by index(). By definition, if it can't be coerced, it isn't a number. A side note: At 80% less overhead, and three slots -- slice is rather attractive to store RGB values in for a picture! But, I don't think anyone would have a problem saying "No, we won't support that, even if you do do it! So, what's the psychology behind allowing slice() to hold objects which are not converted to ints/longs in the first place? -- http://mail.python.org/mailman/listinfo/python-list
Re: Negative array indicies and slice()
On 11/01/2012 07:12 AM, Ethan Furman wrote: Andrew Robinson wrote: On 10/31/2012 02:20 PM, Ian Kelly wrote: On Wed, Oct 31, 2012 at 7:42 AM, Andrew Robinson wrote: Then; I'd note: The non-goofy purpose of slice is to hold three data values; They are either numbers or None. These *normally* encountered values can't create a memory loop. So, FOR AS LONG, as the object representing slice does not contain an explicit GC pair; A little review... The premise of my statement here, is that Tim Peter's closed the Bug report; http://bugs.python.org/issue1501180 With the *reason* being that using GC was *goofy* on account of what slice() was intended to hold, None and a number. So, My first attempt at bug fix was simply to take Tim Peter's at his word... since we all assume he *isn't* a "Bloody Idiot". Hey isn't that a swear-word somewhere in the world? Its not where I live, but I seem to recall... oh, well... whatever. I missed something... (but then that's why we're still talking about it...) Reading the PEP, it notes that *only* integers (or longs) are permitted in slice syntax. Keep in mind that PEPs represent Python /at that time/ -- as Python moves forward, PEPs are not updated (this has gotten me a couple times). And, since I am reading them in the order written (but in 3.0) trying to get the whole of Python into my mind on the journey to prep for porting it into a tiny chip -- I'm frustrated by not being finished yet... Furman, actually. :) :-! And my values do *not* convert to indices (at least, not automatically). Ahhh (Rhetorical & sarcastic) I was wondering how you added index() method to strings, not access it, and still be following the special PEP we are talking about,when you gave that example using unwrapped strings. -- H was that PEP the active state of Python, when Tim rejected the bug report? eg: have we "moved on" into a place where the bug report ought to be re-issued since that PEP is now *effectively* passe, and Tim could thus be vindicated from being a "b... Idiot?" (Or has he been given the 1st place, Python Twit award -- and his *man* the bug list been stripped?) In other words, the slice contains the strings, and my code calculates the offsets -- Python doesn't do it for me. ~Ethan~ I see, so the problem is that PEP wants you to implement the index(), but that is going to cause you to subclass string, and add a wrapper interface every time you need to index something. eg: doing something llke --- mydbclass[ MyString( 'fromColumn' ) : MyString( 'toColum' ) ] and the code becomes a candy machine interface issue (Chapter 5, Writing Solid Code). My favorite line there uses no swearing "If they had just taken an extra *30* seconds thinking about their design, they could have saved me, and I'm sure countless others, from getting something they didn't want." I laugh, if they didn't get it already -- an extra *30* seconds is WY to optimistic. Try minutes at least, will a policeman glaring over their shoulder. But anyhow --- The problem lies in *when* the conversion to an integer is to take place, not so much if it is going to happen. Your indexes, no matter how disguised, eventually will become numbers; and you have a way that minimizes coding cruft (The very reason I started the thread, actually... subclassing trivially to fix candy machine interfaces leads to perpetual code increases -- In cPython source-code, "realloc" wrappers and "malloc" wrappers are found I've seen these wrappers *re*-invented in nearly every C program I've every looked at! Talk about MAN-hours, wasted space, and cruft.) So; is this a reasonable summary of salient features (status quo) ? * Enforcing strict numerical indexes (in the slice [::] operator) causes much psychological angst when attempting to write clear code without lots of wrapper cruft. * Pep 357 merely added cruft with index(), but really solved nothing. Everything index() does could be implemented in __getitem__ and usually is. * slice().xxxs are merely a container for *whatever* was passed to [::] * slice() is * slice is also a full blown object, which implements a trivial method to dump the contents of itself to a tuple. * presently slice() allows memory leaks through GC loops. * Slice(), even though an object with a constructor, does no error checking to deny construction of memory leaks. If people would take 30 seconds to think about this the more details added -- the more comprehensive can be my understanding -- and perhaps a consensus reached about the problem. These are a list of relevant options, without respect to feasability. * Don't bother to fix the bug; allow Python to crash with a subtle bug that often ta
Re: Negative array indicies and slice()
On 11/01/2012 12:07 PM, Ian Kelly wrote: On Thu, Nov 1, 2012 at 5:32 AM, Andrew Robinson wrote: H was that PEP the active state of Python, when Tim rejected the bug report? Yes. The PEP was accepted and committed in March 2006 for release in Python 2.5. The bug report is from June 2006 has a version classification of Python 2.5, although 2.5 was not actually released until September 2006. That explain's Peter's remark. Thank you. He looks *much* smarter now. Pep 357 merely added cruft with index(), but really solved nothing. Everything index() does could be implemented in __getitem__ and usually is. No. There is a significant difference between implementing this on the container versus implementing it on the indexes. Ethan implemented his string-based slicing on the container, because the behavior he wanted was specific to the container type, not the index type. Custom index types like numpy integers on the other hand implement __index__ on the index type, because they apply to all sequences, not specific containers. Hmmm... D'Aprano didn't like the monkey patch;and sub-classing was his fix-all. Part of my summary is based on that conversation with him,and you touched on one of the unfinished points; I responded to him that I thought __getitem__ was under-developed. The object slice() has no knowledge of the size of the sequence; nor can it get that size on it's own, but must passively wait for it to be given to it. The bottom line is: __getitem__ must always *PASS* len( seq ) to slice() each *time* the slice() object is-used. Since this is the case, it would have been better to have list, itself, have a default member which takes the raw slice indicies and does the conversion itself. The size would not need to be duplicated or passed -- memory savings, & speed savings... I'm just clay pidgeoning an idea out here Let's apply D'Aprano 's logic to numpy; Numpy could just have subclassed *list*; so let's ignore pure python as a reason to do anything on the behalf on Numpy: Then, lets' consider all thrid party classes; These are where subclassing becomes a pain -- BUT: I think those could all have been injected. >>> class ThirdParty( list ): # Pretend this is someone else's... ... def __init__(self): return ... def __getitem__(self,aSlice): return aSlice ... We know it will default work like this: >>> a=ThirdParty() >>> a[1:2] slice(1, 2, None) # So, here's an injection... >>> ThirdParty.superOnlyOfNumpy__getitem__ = MyClass.__getitem__ >>> ThirdParty.__getitem__ = lambda self,aSlice: ( 1, 3, self.superOnlyOfNumpy__getitem__(aSlice ).step ) >>> a[5:6] (1, 3, None) Numpy could have exported a (workable) function that would modify other list functions to affect ONLY numpy data types (eg: a filter). This allows user's creating their own classes to inject them with Numpy's filter only when they desire; Recall Tim Peter's "explicit is better than implicit" Zen? Most importantly normal programs not using Numpy wouldn't have had to carry around an extra API check for index() *every* single time the heavily used [::] happened. Memory & speed both. It's also a monkey patch, in that index() allows *conflicting* assumptions in violation of the unexpected monkey patch interaction worry. eg: Numpy *CAN* release an index() function on their floats -- at which point a basic no touch class (list itself) will now accept float as an index in direct contradiction of PEP 357's comment on floats... see? My point isn't that this particular implementation I have shown is the best (or even really safe, I'd have to think about that for a while). Go ahead and shoot it down... My point is that, the methods found in slice(), and index() now have moved all the code regarding a sequence *out* of the object which has information on that sequence. It smacks of legacy. The Python parser takes values from many other syntactical constructions and passes them directly to their respective objects -- but in the case of list(), we have a complicated relationship; and not for any reason that can't be handled in a simpler way. Don't consider the present API legacy for a moment, I'm asking hypothetical design questions: How many users actually keep slice() around from every instance of [::] they use? If it is rare, why create the slice() object in the first place and constantly be allocating and de-allocating memory, twice over? (once for the original, and once for the repetitive method which computes dynamic values?) Would a single mutable have less overhead, since it is destroyed anyway? -- http://mail.python.org/mailman/listinfo/python-list
Re: Negative array indicies and slice()
Hi Ian, I apologize for trying your patience with the badly written code example. All objects were meant to be ThirdParty(), the demo was only to show how a slice() filter could have been applied for the reasons PEP357 made index() to exist. eg: because numpy items passed to __getitems__ via slice syntax [::] were illegal values. PEP 357 is the one who specifically mentioned Numpy types -- which is the only reason I used the name in the example; I could have just as well used a string. I am fully aware of what numpy does -- I have used it; modified the fortran interfaces underneath, etc. The index() method, however, affects *all* list objects in Python, not just Numpy's -- correct? I'll write a working piece of code tomorrow to demonstrate the filter very clearly rather than a skeleton, and test it before posting. -- http://mail.python.org/mailman/listinfo/python-list
Memory profiling: Python 3.2
When Python3.2 is running, is there an easy way within Python to capture the *total* amount of heap space the program is actually using (eg:real memory)? And how much of that heap space is allocated to variables ( including re-capturable data not yet GC'd ) ? -- http://mail.python.org/mailman/listinfo/python-list
Fwd: Re: Negative array indicies and slice()
Forwarded to python list: Original Message Subject:Re: Negative array indicies and slice() Date: Sat, 03 Nov 2012 15:32:04 -0700 From: Andrew Robinson Reply-To: andr...@r3dsolutions.com To: Ian Kelly <> On 11/01/2012 05:32 PM, Ian Kelly wrote: On Thu, Nov 1, 2012 at 4:25 PM, Andrew Robinson The bottom line is: __getitem__ must always *PASS* len( seq ) to slice() each *time* the slice() object is-used. Since this is the case, it would have been better to have list, itself, have a default member which takes the raw slice indicies and does the conversion itself. The size would not need to be duplicated or passed -- memory savings,& speed savings... And then tuple would need to duplicate the same code. As would deque. And str. And numpy.array, and anything else that can be sliced, including custom sequence classes. I don't think that's true. A generic function can be shared among different objects without being embedded in an external index data structure to boot! If *self* were passed to an index conversion function (as would naturally happen anyway if it were a method), then the method could take len( self ) without knowing what the object is; Should the object be sliceable -- the len() will definitely return the required piece of information. Numpy arrays are very different internally from lists. Of course! (Although, lists do allow nested lists.) I'm not understanding what this is meant to demonstrate. Is "MyClass" a find-replace error of "ThirdParty"? Why do you have __getitem__ returning slice objects instead of items or subsequences? What does this example have to do with numpy? Here's a very cleaned up example file, cut and pastable: #!/bin/env python # File: sliceIt.py --- a pre PEP357 hypothesis test skeleton class Float16(): """ Numpy creates a float type, with very limited precision -- float16 Rather than force you to install np for this test, I'm just making a faux object. normally we'd just "import np" """ def __init__(self,value): self.value = value def AltPEP357Solution(self): """ This is doing exactly what __index__ would be doing. """ return None if self.value is None else int( self.value ) class ThirdParty( list ): """ A simple class to implement a list wrapper, having all the properties of a normal list -- but explicitly showing portions of the interface. """ def __init__(self, aList): self.aList = aList def __getitem__(self, aSlice): print( "__getitems__", aSlice ) temp=[] edges = aSlice.indices( len( self.aList ) ) # *unavoidable* call for i in range( *edges ): temp.append( self.aList[ i ] ) return temp def Inject_FloatSliceFilter( theClass ): """ This is a courtesy function to allow injecting (duck punching) a float index filter into a user object. """ def Filter_FloatSlice( self, aSlice ): # Single index retrieval filter try: start=aSlice.AltPEP357Solution() except AttributeError: pass else: return self.aList[ start ] # slice retrieval filter try: start=aSlice.start.AltPEP357Solution() except AttributeError: start=aSlice.start try: stop=aSlice.stop.AltPEP357Solution() except AttributeError: stop=aSlice.stop try: step=aSlice.step.AltPEP357Solution() except AttributeError: step=aSlice.step print( "Filter To",start,stop,step ) return self.super_FloatSlice__getitem__( slice(start,stop,step) ) theClass.super_FloatSlice__getitem__ = theClass.__getitem__ theClass.__getitem__ = Filter_FloatSlice # EOF: sliceIt.py Example run: from sliceIt import * test = ThirdParty( [1,2,3,4,5,6,7,8,9] ) test[0:6:3] ('__getitems__', slice(0, 6, 3)) [1, 4] f16=Float16(8.3) test[0:f16:2] ('__getitems__', slice(0,, 2)) Traceback (most recent call last): File "", line 1, in File "sliceIt.py", line 26, in __getitem__ edges = aSlice.indices( len( self.aList ) ) # This is an *unavoidable* call TypeError: object cannot be interpreted as an index Inject_FloatSliceFilter( ThirdParty ) test[0:f16:2] ('Filter To', 0, 8, 2) ('__getitems__', slice(0, 8, 2)) [1, 3, 5, 7] test[f16] 9 We could also require the user to explicitly declare when they're performing arithmetic on variables that might not be floats. Then we can turn off run-time type checking unless the user explicitly requests it, all in the name of micro-optimization and explicitness. :) None of those would help micro-optimization that I can see. Seriously, whether x is usab
Re: Multi-dimensional list initialization
On 11/04/2012 10:27 PM, Demian Brecht wrote: So, here I was thinking "oh, this is a nice, easy way to initialize a 4D matrix" (running 2.7.3, non-core libs not allowed): m = [[None] * 4] * 4 The way to get what I was after was: m = [[None] * 4, [None] * 4, [None] * 4, [None * 4]] FYI: The behavior is the same in python 3.2 m=[[None]*4]*4 produces a nested list with all references being to the first instance of the inner list construction. I agree, the result is very counter-intuitive; hmmm... but I think you meant: m = [[None] * 4, [None] * 4, [None] * 4, [None] *4 ] rather than: m = [[None] * 4, [None] * 4, [None] * 4, [None * 4]] ? :) ? I asked a why question on another thread, and watched several dodges to the main question; I'll be watching to see if you get anything other than "That's the way it's defined in the API". IMHO -- that's not a real answer. My guess is that the original implementation never considered anything beyond a 1d list. :) A more precise related question might be: is there a way to force the replication operator to use copying rather than referencing? :/ -- http://mail.python.org/mailman/listinfo/python-list
Re: Multi-dimensional list initialization
On 11/04/2012 11:27 PM, Chris Angelico wrote: On Mon, Nov 5, 2012 at 6:07 PM, Chris Rebert wrote: x = None x.a = 42 Traceback (most recent call last): File "", line 1, in AttributeError: 'NoneType' object has no attribute 'a' Python needs a YouGottaBeKiddingMeError for times when you do something utterly insane like this. Attributes of None??!? :) ChrisA Hmmm? Everything in Python is an object. Therefore! SURE. None *does* have attributes! ( even if not useful ones... ) eg: " None.__getattribute__( "__doc__" ) " doesn't produce an error. In C, in Linux, at the end of the file "errno.h", where all error codes are listed eg:( EIO, EAGAIN, EBUSY, E) They had a final error like the one you dreamed up, it was called "EIEIO"; and the comment read something like, "All the way around Elmer's barn". :) The poster just hit that strange wall -- *all* built in types are injection proof; and that property is both good and bad... -- http://mail.python.org/mailman/listinfo/python-list
Re: Multi-dimensional list initialization
On 11/05/2012 06:30 PM, Oscar Benjamin wrote: On 6 November 2012 02:01, Chris Angelico wrote: On Tue, Nov 6, 2012 at 12:32 PM, Oscar Benjamin wrote: I was just thinking to myself that it would be a hard thing to change because the list would need to know how to instantiate copies of all the different types of the elements in the list. Then I realised it doesn't. It is simply a case of how the list multiplication operator is implemented and whether it chooses to use a reference to the same list or make a copy of that list. Since all of this is implemented within the same list type it is a relatively easy change to make (ignoring backward compatibility concerns). I don't see this non-copying list multiplication behaviour as contradictory but has anyone ever actually found a use for it? Stupid example of why it can't copy: bad = [open("test_file")] * 4 How do you clone something that isn't Plain Old Data? Ultimately, that's where the problem comes from. It's easy enough to clone something that's all scalars (strings, integers, None, etc) and non-recursive lists/dicts of scalars, but anything more complicated than that is rather harder. That's not what I meant. But now you've made me realise that I was wrong about what I did mean. In the case of stuff = [[obj] * n] * m I thought that the multiplication of the inner list ([obj] * n) by m could create a new list of lists using copies. On closer inspection I see that the list being multiplied is in fact [[obj] * n] and that this list can only know that it is a list of lists by inspecting its element(s) which makes things more complicated. I retract my claim that this change would be easy to implement. Oscar Hi Oscar, In general, people don't use element multiplication (that I have *ever* seen) to make lists where all elements of the outer most list point to the same sub-*list* by reference. The most common use of the multiplication is to fill an array with a constant, or short list of constants; Hence, almost everyone has to work around the issue as the initial poster did by using a much longer construction. The most compact notation in programming really ought to reflect the most *commonly* desired operation. Otherwise, we're really just making people do extra typing for no reason. Further, list comprehensions take quite a bit longer to run than low level copies; by a factor of roughly 10. SO, it really would be worth implementing the underlying logic -- even if it wasn't super easy. I really don't think doing a shallow copy of lists would break anyone's program. The non-list elements, whatever they are, can be left as reference copies -- but any element which is a list ought to be shallow copied. The behavior observed in the opening post where modifying one element of a sub-list, modifies all elements of all sub-lists is never desired as far as I have ever witnessed. The underlying implementation of Python can check an object type trivially, and the only routine needed is a shallow list copy. So, no it really isn't a complicated operation to do shallow copies of lists. :) -- http://mail.python.org/mailman/listinfo/python-list
Re: Multi-dimensional list initialization
On 11/05/2012 10:07 PM, Chris Angelico wrote: On Tue, Nov 6, 2012 at 4:51 PM, Andrew Robinson wrote: I really don't think doing a shallow copy of lists would break anyone's program. Well, it's a change, a semantic change. It's almost certainly going to break _something_. But for the sake of argument, we can suppose that the change could be made. Would it be the right thing to do? Shallow copying by default would result in extremely weird behaviour. All the same confusion would result, only instead of comparing [None]*4 with [[None]]*4, there'd be confusion over the difference between [[None]]*4 and [[[None]]]*4. I don't think it would help anything, and it'd result in a lot more work for no benefit. ChrisA I don't follow. a=[ None ]*4 would give a=[ None, None, None, None ] as usual. All four None's would be the same object, but there are automatically 4 different pointers to it. Hence, a[0]=1 would give a=[ 1, None, None, None ] as usual. a=[ [None] ]*4 would give a=[ [None], [None], [None], [None] ] as usual BUT: a[0][0] = 1 would no longer give a=[ [1],[1],[1],[1] ] *Rather* it would give a=[ [1].[None].[None],[None] ] The None objects are all still the same one, BUT the lists themselves are different. Again, a=[ ["alpha","beta"] * 4 ] would give: a=[ ["alpha","beta"], ["alpha","beta"], ["alpha","beta"], ["alpha","beta"] ] All four strings, "alpha", are the same object -- but there are 5 different lists; The pointers inside the initial list are copied four times -- not the string objects; But the *lists* themselves are created new for each replication. If you nest it another time; [[[None]]]*4, the same would happen; all lists would be independent -- but the objects which aren't lists would be refrenced-- not copied. a=[[["alpha","beta"]]]*4 would yield: a=[[['alpha', 'beta']], [['alpha', 'beta']], [['alpha', 'beta']], [['alpha', 'beta']]] and a[0][0]=1 would give [[1],[['alpha', 'beta']], [['alpha', 'beta']], [['alpha', 'beta' rather than a=[[1], [1], [1], [1]] Or at another level down: a[0][0][0]=1 would give: a=[[[1, 'beta']], [['alpha', 'beta']], [['alpha', 'beta']], [['alpha', 'beta']] ] rather than a=[[[1, 'beta']], [[1, 'beta']], [[1, 'beta']], [[1, 'beta']]] The point is, there would be no difference at all noticed in what data is found where in the array; the *only* thing that would change is that replacing an item by assignment would only affect the *location* assigned to -- all other locations would not be affected. That really is what people *generally* want. If the entire list is meant to be read only -- the change would affect *nothing* at all. See if you can find *any* python program where people desired the multiplication to have the die effect that changing an object in one of the sub lists -- changes all the objects in the other sub lists. I'm sure you're not going to find it -- and even if you do, it's going to be 1 program in 1000's. -- http://mail.python.org/mailman/listinfo/python-list
Re: Multi-dimensional list initialization
On 11/06/2012 06:35 AM, Oscar Benjamin wrote: > In general, people don't use element multiplication (that I have *ever* seen) to make lists where all elements of the outer most list point to the same sub-*list* by reference. The most common use of the multiplication is to fill an array with a constant, or short list of constants; Hence, almost everyone has to work around the issue as the initial poster did by using a much longer construction. That's what I have seen as well. I've never seen an example where someone wanted this behaviour. > > The most compact notation in programming really ought to reflect the most *commonly* desired operation. Otherwise, we're really just making people do extra typing for no reason. It's not so much the typing as the fact that this a common gotcha. Apparently many people expect different behaviour here. I seem to remember finding this surprising at first. :) That's true as well. > > Further, list comprehensions take quite a bit longer to run than low level copies; by a factor of roughly 10. SO, it really would be worth implementing the underlying logic -- even if it wasn't super easy. > > I really don't think doing a shallow copy of lists would break anyone's program. > The non-list elements, whatever they are, can be left as reference copies -- but any element which is a list ought to be shallow copied. The behavior observed in the opening post where modifying one element of a sub-list, modifies all elements of all sub-lists is never desired as far as I have ever witnessed. It is a semantic change that would, I imagine, break many things in subtle ways. ?? Do you have any guesses, how ? > > The underlying implementation of Python can check an object type trivially, and the only routine needed is a shallow list copy. So, no it really isn't a complicated operation to do shallow copies of lists. Yes but if you're inspecting the object to find out whether to copy it what do you test for? If you check for a list type what about subclasses? What if someone else has a custom list type that is not a subclass? Should there be a dunder method for this? No dunder methods. :) Custom non-subclass list types aren't a common usage for list multiplication in any event. At present one has to do list comprehensions for that, and that would simply remain so. Subclasses, however, are something I hadn't considered... I don't think it's such a simple problem. Oscar You made a good point, Oscar; I'll have to think about the subclassing a bit. :) -- http://mail.python.org/mailman/listinfo/python-list
Re: Multi-dimensional list initialization
On 11/06/2012 09:32 AM, Prasad, Ramit wrote: Ian Kelly wrote: On Tue, Nov 6, 2012 at 1:21 AM, Andrew Robinson [snip] See if you can find *any* python program where people desired the multiplication to have the die effect that changing an object in one of the sub lists -- changes all the objects in the other sub lists. I'm sure you're not going to find it -- and even if you do, it's going to be 1 program in 1000's. Per the last thread where we discussed extremely rare scenarios, shouldn't you be rounding "1 in 1000s" up to 20%? ;-) :D -- Ian -- also consider that I *am* willing to use extra memory. Not everything can be shrunk to nothing and still remain functional. :) So, it isn't *all* about *micro* optimization -- it's also about psychology and flexibility. Actually, I would be surprised if it was even 1 in 1000. Of course, consistency makes it easier to learn and *remember*. I value that far more than a minor quirk that is unlikely to bother me now that I know of it. Well, at least not as long as I do not forget my morning coffee/tea :) But, having it copy lists -- when the only purpose of multiplication is for lists; is only a minor quirk as well. ~Ramit -- http://mail.python.org/mailman/listinfo/python-list
Re: Multi-dimensional list initialization
On 11/06/2012 01:19 AM, Ian Kelly wrote: On Tue, Nov 6, 2012 at 1:21 AM, Andrew Robinson If you nest it another time; [[[None]]]*4, the same would happen; all lists would be independent -- but the objects which aren't lists would be refrenced-- not copied. a=[[["alpha","beta"]]]*4 would yield: a=[[['alpha', 'beta']], [['alpha', 'beta']], [['alpha', 'beta']], [['alpha', 'beta']]] and a[0][0]=1 would give [[1],[['alpha', 'beta']], [['alpha', 'beta']], [['alpha', 'beta' rather than a=[[1], [1], [1], [1]] Or at another level down: a[0][0][0]=1 would give: a=[[[1, 'beta']], [['alpha', 'beta']], [['alpha', 'beta']], [['alpha', 'beta']] ] rather than a=[[[1, 'beta']], [[1, 'beta']], [[1, 'beta']], [[1, 'beta']]] You wrote "shallow copy". When the outer-level list is multiplied, the mid-level lists would be copied. Because the copies are shallow, although the mid-level lists are copied, their contents are not. Thus the inner-level lists would still be all referencing the same list. To demonstrate: I meant all lists are shallow copied from the innermost level out. Equivalently, it's a deep copy of list objects -- but a shallow copy of any list contents except other lists. from copy import copy class ShallowCopyList(list): ... def __mul__(self, number): ... new_list = ShallowCopyList() ... for _ in range(number): ... new_list.extend(map(copy, self)) ... return new_list ... That type of copy is not equivalent to what I meant; It's a shallow copy only of non-list objects. This shows that assignments at the middle level are independent with a shallow copy on multiplication, but assignments at the inner level are not. In order to achieve the behavior you describe, a deep copy would be needed. Yes, it can be considered a deep copy of *all* list objects -- but not of non list contents. It's a terminology issue -- and you're right -- I need to be more precise. That really is what people *generally* want. If the entire list is meant to be read only -- the change would affect *nothing* at all. The time and memory cost of the multiplication operation would become quadratic instead of linear. Perhaps, but the copy would still not be _nearly_ as slow as a list comprehension !!! Being super fast when no one uses the output -- is , "going nowhere fast." I think It's better to get at the right place at a medium speed than nowhere fast; List comprehensions *do* get to the right place, but *quite* slowly. They are both quadratic, *and* multiple tokenized steps. :) -- http://mail.python.org/mailman/listinfo/python-list
Re: Multi-dimensional list initialization
On 11/06/2012 01:04 AM, Steven D'Aprano wrote: On Mon, 05 Nov 2012 21:51:24 -0800, Andrew Robinson wrote: The most compact notation in programming really ought to reflect the most *commonly* desired operation. Otherwise, we're really just making people do extra typing for no reason. There are many reasons not to put minimizing of typing ahead of all other values: I didn't. I put it ahead of *some* values for the sake of practicality and human psychology. " Practicality beats purity. " * Typically, code is written once and read many times. Minimizing typing might save you a second or two once, and then cost you many seconds every time you read the code. That's why we tell people to choose meaningful variable names, instead of naming everything "a" and "b". Yes. But this isn't going to cost any more time than figuring out whether or not the list multiplication is going to cause quirks, itself. Human psychology *tends* (it's a FAQ!) to automatically assume the purpose of the list multiplication is to pre-allocate memory for the equivalent (using lists) of a multi-dimensional array. Note the OP even said "4d array". The OP's original construction was simple, elegant, easy to read and very commonly done by newbies learning the language because it's *intuitive*. His second try was still intuitive, but less easy to read, and not as elegant. * Consistency of semantics is better than a plethora of special cases. Python has a very simple and useful rule: objects should not be copied unless explicitly requested to be copied. This is much better than having to remember whether this operation or that operation makes a copy. The answer is consistent: Bull. Even in the last thread I noted the range() object produces special cases. >>> range(0,5)[1] 1 >>> range(0,5)[1:3] range(1, 3) >>> The principle involved is that it gives you what you *usually* want; I read some of the documentation on why Python 3 chose to implement it this way. (pardon me for belabouring the point here) Q: Does [0]*10 make ten copies of the integer object? A: No, list multiplication doesn't make copies of elements. Neither would my idea for the vast majority of things on your first list. Q: What about [[]]*10? A: No, the elements are never copied. YES! For the obvious reason that such a construction is making mutable lists that the user wants to populate later. If they *didn't* want to populate them later, they ought to have used tuples -- which take less overhead. Who even does this thing you are suggesting?! >>> a=[[]]*10 >>> a [[], [], [], [], [], [], [], [], [], []] >>> a[0].append(1) >>> a [[1], [1], [1], [1], [1], [1], [1], [1], [1], [1]] Oops! Damn, not what anyone normal wants Q: How about if the elements are subclasses of list? A: No, the elements are never copied. Another poster brought that point up -- it's something I would have to study before answering. It's a valid objection. Q: What about other mutable objects like sets or dicts? A: No, the elements are never copied. They aren't list multiplication compatible in any event! It's a total nonsense objection. If these are inconsistent in my idea -- OBVIOUSLY -- they are inconsistent in Python's present implementation. You can't even reference duplicate them NOW. >>> { 1:'a', 2:'b', 3:'c' } * 2 Traceback (most recent call last): File "", line 1, in TypeError: unsupported operand type(s) for *: 'dict' and 'int' Q: How about on Tuesdays? I bet they're copied on Tuesdays. A: No, the elements are never copied. That's really a stupid objection, and everyone knows it. " Although that way may not be obvious at first unless you're Dutch. " Your proposal throws away consistency for a trivial benefit on a rare use- case, and replaces it with a bunch of special cases: RARE You are NUTS Q: What about [[]]*10? A: Oh yeah, I forgot about lists, they're copied. Yup. Q: How about if the elements are subclasses of list? A: Hmmm, that's a good one, I'm not actually sure. Q: How about if I use delegation to proxy a list? A: Oh no, they definitely won't be copied. Give an example usage of why someone would want to do this. Then we can discuss it. Q: What about other mutable objects like sets or dicts? A: No, definitely not. Unless people complain enough. now you're just repeating yourself to make your contrived list longer -- but there's no new objections... Losing consistency in favour of saving a few characters for something as uncommon as list multiplication is a poor tradeoff. That&
Re: Multi-dimensional list initialization
Hi IAN! On 11/06/2012 03:52 PM, Ian Kelly wrote: On Tue, Nov 6, 2012 at 3:41 PM, Andrew Robinson The objection is not nonsense; you've merely misconstrued it. If [[1,2,3]] * 4 is expected to create a mutable matrix of 1s, 2s, and 3s, then one would expect [[{}]] * 4 to create a mutable matrix of dicts. If the dicts are not copied, then this fails for the same reason :) The idea does create a multable list of dicts; just not a mutable list of different dicts. Q: How about if I use delegation to proxy a list? A: Oh no, they definitely won't be copied. Give an example usage of why someone would want to do this. Then we can discuss it. Seriously? Read a book on design patterns. You might start at SO: http://stackoverflow.com/questions/832536/when-to-use-delegation-instead-of-inheritance :) I wasn't discarding the argument, I was asking for a use case to examine. I know what a delegation *is*; but I'm not spending lots of times thinking about this issue. (Besides this thread just went more or less viral, and I can't keep up) I have a book on design patterns -- in fact, the one called "Design Patterns" by Gamma, Helm, Johnson, Vlissides. (Is it out of date already or something?) Please link to the objection being proposed to the developers, and their reasoning for rejecting it. I think you are exaggerating. > From Google: http://bugs.python.org/issue1408 http://bugs.python.org/issue12597 http://bugs.python.org/issue9108 http://bugs.python.org/issue7823 Note that in two out of these four cases, the reporter was trying to multiply lists of dicts, not just lists of lists. That's helpful. Thanks. I'll look into these. Besides, 2D arrays are *not* rare and people *have* to copy internals of them very often. The copy speed will be the same or *faster*, and the typing less -- and the psychological mistakes *less*, the elegance more. List multiplication is not potentially useful for copying 2D lists, only for initializing them. For copying an existing nested list, you're still stuck with either copy.deepcopy() or a list comprehension. Yes, I totally agree. But, as far as I know -- the primary use of list multiplication is initialization. That was my point about the most compact notation ought to be for the most common case. Initialization is a very common use case. List comprehensions are appropriate for the other's. Even D'Aprano thought the * operator was not a common operation; and I suppose that when compared to other operations done in a program (relative counting) he's correct; most programs are not primarily matrix or initialization oriented. It's hardly going to confuse anyone to say that lists are copied with list multiplication, but the elements are not. Every time someone passes a list to a function, they *know* that the list is passed by value -- and the elements are passed by reference. People in Python are USED to lists being "the" way to weird behavior that other languages don't do. Incorrect. Python uses what is commonly known as call-by-object, not call-by-value or call-by-reference. Passing the list by value would imply that the list is copied, and that appends or removes to the list inside the function would not affect the original list. Interesting, you avoided the main point "lists are copied with list multiplication". But, in any event: _Pass_ by value (not call by value) is a term stretching back 30 years; eg: when I learned the meaning of the words. Rewording it as "Call by value" is something that happened later, and the nuance is lost on those without a very wide programming knowledge *and* age. In any event: All objects in Python are based on pointers; all parameters passed to functions, etc, are *copies* of those pointers; (by pointer value). I made the distinction between contents of the list and the list object itself for that reason; I gave an explicit correction to the _pass_ by "value" generalization by saying: ("the elements are passed by reference"). The concept I gave, although archaically stated -- still correctly represents what actually happens in Python and can be seen from it's source code(s). The point I am making is not generally true of everyone learning Python; For some people obviously learn it from scratch. But, for people who learn the language after a transition, this is a common FAQ; how do I modify the variables by reference and not by value; -- the answer is, you can't -- you must embed the return value in another object; parameters are always passed the *same* way. Every function written, then, has to decide when objects are passed to it -- whether to modify or copy the object (internals) when modifying it. That's all I meant. -- http://mail.python.org/mailman/listinfo/python-list
Re: Multi-dimensional list initialization
On 11/06/2012 05:55 PM, Steven D'Aprano wrote: On Tue, 06 Nov 2012 14:41:24 -0800, Andrew Robinson wrote: Yes. But this isn't going to cost any more time than figuring out whether or not the list multiplication is going to cause quirks, itself. Human psychology *tends* (it's a FAQ!) to automatically assume the purpose of the list multiplication is to pre-allocate memory for the equivalent (using lists) of a multi-dimensional array. Note the OP even said "4d array". I'm not entirely sure what your point is here. The OP screwed up -- he didn't generate a 4-dimensional array. He generated a 2-dimensional array. If his intuition about the number of dimensions is so poor, why should his intuition about list multiplication be treated as sacrosanct? Yes he did screw up. There is a great deal of value in studying how people screw up, and designing interfaces which tend to discourage it. "Candy machine interfaces". As they say, the only truly intuitive interface is the nipple. No it's not -- that interface really sucks. :) Have you ever seen a cat trying to suck a human nipple -- ? Or, have you ever asked a young child who was weaned early and doesn't remember nursing -- what a breast is for ? Once the oral stage is left, remaining behavior must be re-learned. There are many places where people's intuition about programming fail. And many places where Fred's intuition is the opposite of Barney's intuition. OK. But that doesn't mean that *all* places have opposite intuition; Nor does it mean that one intuition which is statistically *always* wrong shouldn't be discouraged, or re-routed into useful behavior. Take the candy machine, if the items being sold are listed by number -- and the prices are also numbers; it's very easy to type in the price instead of the object number because one *forgets* that the numbers have different meaning and the machine can't always tell from the price, which object a person wanted (duplicate prices...); Hence a common mistake... people get the wrong item, by typing in the price. By merely avoiding a numeric keypad -- the user is re-routed into choosing the correct item by not being able to make the mistake. For this reason, Python tends to *like* things such as named parameters and occasionally enforces their use. etc. Even more exciting, there are places where people's intuition is *inconsistent*, where they expect a line of code to behave differently depending on their intention, rather than on the code. And intuition is often sub-optimal: e.g. isn't it intuitively obvious that "42" + 1 should give 43? (Unless it is intuitively obvious that it should give 421.) I agree, and in places where an *exception* can be raised; it's appropriate to do so. Ambiguity, like the candy machine, is *bad*. So while I prefer intuitively obvious behaviour where possible, it is not the holy grail, and I am quite happy to give it up. "where possible"; OK, fine -- I agree. I'm not "happy" to give it up; but I am willing. I don't like the man hours wasted on ambiguous behavior; and I don't ever think that should make someone "happy". The OP's original construction was simple, elegant, easy to read and very commonly done by newbies learning the language because it's *intuitive*. His second try was still intuitive, but less easy to read, and not as elegant. Yes. And list multiplication is one of those areas where intuition is suboptimal -- it produces a worse outcome overall, even if one minor use- case gets a better outcome. I'm not disputing that [[0]*n]*m is intuitively obvious and easy. I'm disputing that this matters. Python would be worse off if list multiplication behaved intuitively. How would it be worse off? I can agree, for example, that in "C" -- realloc -- is too general. One can't look at the line where realloc is being used, and decide if it is: 1) mallocing 2) deleting 3) resizing Number (3) is the only non-redundant behavior the function provides. There is, perhaps, a very clear reason that I haven't discovered why the extra functionality in list multiplication would be bad; That reason is *not* because list multiplication is unable to solve all the copying problems in the word; (realloc is bad, precisely because of that); But a function ought to do at least *one* thing well. Draw up some use cases for the multiplication operator (I'm calling on your experience, let's not trust mine, right?); What are all the Typical ways people *Do* to use it now? If those use cases do not *primarily* center around *wanting* an effect explicitly caused by reference duplication -- then it may be better to abolish list multiplication all together; and rather, improve the list comprehensions to overcome the memory, clarity,
Re: Multi-dimensional list initialization
On 11/06/2012 10:56 PM, Demian Brecht wrote: My question was *not* based on what I perceive to be intuitive (although most of this thread has now seemed to devolve into that and become more of a philosophical debate), but was based on what I thought may have been inconsistent behaviour (which was quickly cleared up with None being immutable and causing it to *seem* that the behaviour was inconsistent to the forgetful mind). I originally brought up "intuitive"; and I don't consider the word to mean an "exclusive" BEST way -- I meant it to mean easily guessed or understood. An intelligent person can see when there may be more than one reasonable explanation -- ergo: I just called your OP intelligent, even if you were wrong; and D'Aprano ripped you for being wrong. The debate is degenerating because people are _subjectively_ judging other people's intelligence. The less intelligent a person is, the more black and white their judgements _tend_ to be. As you touch on here, "intuition" is entirely subjective. If you're coming from a C/C++ background, I'd think that your intuition would be that everything's passed by value unless explicitly stated. Yup -- that's my achillies heel and bias, I'm afraid. I learned basic, then assembly, and then pascal, and then fortran77 with C (historically in that order) In my view, pass by value vs. reference always exists at the hardware/CPU level regarless of the language; and regardless of whether the language hides the implementation details or not; I'm an EE; I took software engineering to understand the clients who use my hardware, and to make my hardware drivers understandable to them by good programming practices. An EE's perspective often lead to doing efficient things which are hard to understand; That's why I look for a consensus (not a compromise) before implementing speed/memory improvements and ways to clarify what is being done. Someone coming from another background (Lua perhaps?) would likely have entirely different intuition. Yes, they might be ignorant of what LUA is doing at the hardware level; even though it *is* doing it. So while I prefer intuitively obvious behaviour where possible, it is not the holy grail, and I am quite happy to give it up. I fail to see where there has been any giving up on intuitiveness in the context of this particular topic. In my mind, intuitiveness is generally born of repetitiveness and consistency. YES I think a good synonym would be habit; and when a habit is good -- it's called strength, or "virtue"; When it's bad it's called "vice" or "sin" or "bad programming habit." :) Virtues don't waste people's time in debugging. As everything in Python is a reference, it would seem to me to be inconsistent to treat expressions such as [[obj]*4]*4 un-semantically (Pythonically speaking) and making it *less* intuitive. I agree that Python would definitely be worse off. That's a fair opinion. I was pleasantly surprised when the third poster actually answered the "WHY" question with the idea that Python always copies by reference unless forced to do deep copy. That's intuitive, and as a habit (not a requirement) Python implements things that way. I've already raised the question about why one would want a multiplier at all, if it were found that the main desired use case never *wants* all objects to change together. I laid out a potential modification of list comprensions; which, BTW, copy by re-instantiating rather than reference; so the paradigm of Python is wrong in that case But, I think the modifications in that context can't be argued against as easily as list multiplication (For the same reason that comprehensions already break the copy by reference mold ) -- http://mail.python.org/mailman/listinfo/python-list
Re: Multi-dimensional list initialization
On 11/07/2012 05:39 AM, Joshua Landau wrote: On 7 November 2012 11:11, Oscar Benjamin wrote: On Nov 7, 2012 5:41 AM, "Gregory Ewing" wrote: > > If anything is to be done in this area, it would be better > as an extension of list comprehensions, e.g. > > [[None times 5] times 10] > > which would be equivalent to > > [[None for _i in xrange(5)] for _j in xrange(10)] Oscar, I'm really in agreement with you; I think that it's better to group all *special* array/list constructions into a single logical unit which will show up in the same part of the Python documentation. A multidimensional list comprehension would be useful even for people who are using numpy as it's common to use a list comprehension to initialise a numpy array. I hadn't paid that much attention; but I think that's true of people using the newer releases of Numpy. A Very interesting point... Thank you for mentioning it. A more modest addition for the limited case described in this thread could be to use exponentiation: >>> [0] ** (2, 3) [[0, 0, 0], [0, 0, 0]] I'm against over using the math operators, for the reason that matrix and vector algebra have meanings mathematicians desire (rightly) to maintain. Numpy users might find matricies overloaded to do these things in the future -- and then it becomes unclear whether an initialization is happening or a mathematical operation. I think it best just not to set up an accident waiting to happen in the first place. Hold on: why not just use multiplication? >>> [0] * (2, 3) Would you consider that better than [0].nest(2).nest(3) ? or [0].nest(2,3) ? (I'm against multiplication, but I'm still interested in what you find attractive about it.) We do have to think of the potential problems, though. There are definitely some. For one, code that relies on lst * x throwing an error would break. It may confuse others - although I don't see how. Excellent observation: People relying on an exception, would be in the try: operation. So, since lst * int does not cause an exception; they would need a reason to be concerned that someone passed in a list instead of an integer. Semantically, the same KIND of result happens, lst is in some way duplicated; so if the result is accepted, it likely would work in place of an integer. So, the concern would be where someone wanted to detect the difference between an integer and a list, so as to run some alternate algorithm. Eg, say a vector multiply, or similar operation. The design would want to shadow * and call a method to do the multiply; You'd have a fragment possibly like the following: ... try: ret = map( lambda x: x*rightSide, leftSide ) except TypeError: for i in rightSide: self.__mul__( rightSide, i ) # recursive call to __mul__ ... That's a common technique for type checking dating from earlier releases of Python, where the "type" attribute wasn't available. It also works based on functionality, not specific type -- so objects which "work" alike (subclasses, alternate reinventions of the wheel) also can be handled. -- http://mail.python.org/mailman/listinfo/python-list
Re: Multi-dimensional list initialization
On 11/07/2012 01:01 PM, Ian Kelly wrote: On Wed, Nov 7, 2012 at 12:51 PM, Andrew Robinson wrote: Interesting, you avoided the main point "lists are copied with list multiplication". It seems that each post is longer than the last. If we each responded to every point made, this thread would fill a book. It already is :) Anyway, your point was to suggest that people would not be confused by having list multiplication copy lists but not other objects, because passing lists into functions as parameters works in basically the same way. Not quite; Although I wasn't clear; The variable passed in is by *value* in contradistinction to the list which is by reference. Python does NOT always default copy by reference *when it could*; that's the point. Hence the programmer has to remember in foo( x,y ), the names x and y when assigned to -- *DONT* affect the variables from which they came. But any object internals do affect the objects everywhere. A single exception exists; My thesis is for a single exception as well -- I think Python allows that kind of thinking. So actually I did address this point with the "call-by-object" tangent; I just did not explicitly link it back to your thesis. My apology for not proof reading my statements for clarity. It was definitely time for a nap back then. Potayto, potahto. The distinction that you're describing is between "strict" versus "non-strict" evaluation strategies. Hinging the distinction on the non-descriptive words "call" and "pass" is lazy terminology that should never have been introduced in the first place. I would do it again. Other's have already begun to discuss terminology with you -- I won't double team you. -- http://mail.python.org/mailman/listinfo/python-list
Re: Multi-dimensional list initialization
On 11/07/2012 03:39 PM, Ian Kelly wrote: Why? Just to get rid of an FAQ? :-) Here's one of the more interesting uses from my own code: OK, and is this a main use case? (I'm not saying it isn't I'm asking.) Replacing the list multiplication in that function with a list comprehension would be awkward, as the obvious replacement of [iter(iterable) for _ in range(n)] would produce different results. Yes. I have a thought on that. How exactly do you propose to indicate to the compiler which parts of the expressions are meant to be cached, and which are not? Exactly? OK; Here's what I would consider a safe implementation -- but it could be improved later. There is a special keyword which signals the new type of comprehension; A normal comprehension would say eg: '[ foo for i in xrange ]'; but when the 'for i in' is reduced to a specific keyword such as 'ini' (instead of problematic 'in') the caching form of list comprehension would start. So, then, just like a comprehension -- the interpreter will begin to evaluate the code from the opening bracket '['; But anything other than a function/method will raise a type error (people might want to change that, but it's safe). The interpreter then caches all functions/initialiser methods it comes into contact with. Since every function/method has a parameter list (even if empty); The interpreter would evaluate the parameter list on the first pass through the comprehension, and cache each parameter list with it's respective function. When the 'ini' keyword is parsed a second time, Python would then evaluate each cached function on its cached parameter list; and the result would be stored in the created list. This cached execution would be repeated as many times as is needed. Now, for your example: values = zip(samples, times * num_groups) if len(values)< len(times) * num_groups: # raise an error Might be done with: values = zip( samples, [ lambda:times, ini xrange(num_groups) ] ) if len(values) < len(times) * num_groups The comma after the lambda is questionable, and this construction would be slower since lambda automatically invokes the interpreter; but it's correct. If you could provide a built in which returns a reference to the parameter passed to it; that would run at max system speed; by default, all built-in object initializers are maximally fast. The key difference is that the ini syntax evaluates the parameter lists only once; and the ini's purpose is for repeating an initialization of the same kind of object in multiple different places. As an aside, how would you do the lambda inside a list comprehension? [lambda:6 for i in xrange(10) ] # Nope. Generic lists allow a spurrious comma, so that [ 3,3,3, ] = [3,3,3] dropped; [lambda:6, for i in xrange(10) ] # but this is no good. I have to do: def ref(): return 6 [ref(x) for i in xrange(10) ] Of course you got an integer. You took an index of the range object, not a slice. The rule is that taking an index of a sequence returns an element; taking a slice of a sequence returns a sub-sequence. You still have not shown any inconsistency here. Because it's an arbitrary rule which operates differently than the traditional idea shown in python docs? slice.indices() is *for* (QUOTE)"representing the _set of indices_ specified by _range_(start, stop, step)" http://docs.python.org/2/library/functions.html#slice There are examples of python doing this; use Google... They use slice indices() to convert negative indexes into positive ones _compatible with range()_. some_getitem_method_in_a_subclass_foo( self, range ): ret=[] for i in xrange( range.indices( len(self) ) ): ret.append( self.thing[i] ) return ret The return is equivalent to a range object in the sense that it is an iterator object, but it's not the same iterator object. It will still work with legacy code since different iterators can be interchanged so long as they return the same values. No, he wasn't. He was talking about multiplying lists of dicts, and whether the dicts are then copied or not, just like every other Q&A item in that dialogue was concerning whether item X in a list should expect to be copied when the containing list is multiplied. I already told him several times before that what the answer was; It doesn't copy anything except the list itself. Then he asks, "does it multiply dicts" and no mention of it being inside a list. He's browbeating a dead horse. Perhaps you're not aware that on the Internet, TYPING IN ALL CAPS is commonly construed as SHOUTING. Sure, and people say: THIS IS YELLING, AND I AM DOING IT HERE AS AN EXAMPLE. This is STRESS. This is SHOCK! I don't recall typing any _full sentence_ in all caps, if I did, I'm awfully sorry. I didn't mean it. Yes, he is beginning to get condescendingly exasperating. Everyone else seems to understand 85+% of what I say, correctly. He doesn't; and now
Re: Multi-dimensional list initialization
On 11/07/2012 04:00 PM, Steven D'Aprano wrote: Andrew, it appears that your posts are being eaten or rejected by my ISP's news server, because they aren't showing up for me. Possibly a side- effect of your dates being in the distant past? Date has been corrected since two days ago. It will remain until a reboot Ignorance, though, might be bliss... Every now and again I come across somebody who tries to distinguish between "call by foo" and "pass by foo", but nobody has been able to explain the difference (if any) to me. I think the "Call by foo" came into vogue around the time of C++; Eg: It's in books like C++ for C programmers; I never saw it used before then so I *really* don't know for sure... I know "Pass by value" existed all the way back to the 1960's. I see "pass by" in my professional books from those times and even most newer ones; but I only find "Call by value" in popular programming books of more recent times. (Just my experience) So -- I "guess" the reason is that when invoking a subroutine, early hardware often had an assembler mnemonic by the name "call". See for example: Intelx86 hardware books from the 1970's; Most early processors (like the MC6809E, and 8080) allow both direct and indirect *references* to a function (C would call them function pointers); So, occasionally early assembly programs comment things like: "; dynamic VESA libraries are called by value in register D."; And they meant that register D is storing a function call address from two or more vesa cards. It had little to do with the function's parameters, (which might be globals anyway) (It procedural dynamic binding!) Today, I don't know for sure -- so I just don't use it. "pass" indicates a parameter of the present call; but not the present call itself. -- http://mail.python.org/mailman/listinfo/python-list
Re: Multi-dimensional list initialization
On 11/07/2012 11:09 PM, Ian Kelly wrote: On Wed, Nov 7, 2012 at 8:13 PM, Andrew Robinson wrote: OK, and is this a main use case? (I'm not saying it isn't I'm asking.) I have no idea what is a "main" use case. Well, then we can't evaluate if it's worth keeping a list multiplier around at all. You don't even know how it is routinely used. FYI, the Python devs are not very fond of adding new keywords. Any time a new keyword is added, existing code that uses that word as a name is broken. 'ini' is particularly bad, because 1) it's not a word, and 2) it's the name of a common type of configuration file and is probably frequently used as a variable name in relation to such files. Fine; Its a keyword TBD then; I should have said 'foo'. in is worse than ini, ini is worse than something else -- at the end of the rainbow, maybe there is something values = zip( samples, [ lambda:times, ini xrange(num_groups) ] ) if len(values)< len(times) * num_groups How is this any better than the ordinary list comprehension I already suggested as a replacement? For that matter, how is this any better than list multiplication? You _asked it to implement_ a list multiplication of the traditional kind; By doing copies by *REFERENCE*; so of course it's not better. My intentions were for copying issues, not-non copying ones. Your basic complaint about list multiplication as I understand it is that the non-copying semantics are unintuitive. No. 1) My basic complaint is that people (I think from watching) primarily use it to make initializer lists, and independent mutable place holders; List multiplication doesn't do that well. 2) If it is indeed very rare (as D'Aprano commented) then -- it has a second defect in looking to casual inspection to be the same as vector multiplication; which opacifies which operation is being done when matrix packages are potentially being used. Well, the above is even less intuitive. It is excessively complicated and almost completely opaque. If I were to come across it outside the context of this thread, I would have no idea what it is meant to be doing. Nor would I *know* what this list multiplier look alike does [1,2,3]*aValue without checking to see if someone imported a vector library and the variable aValue has a special multiplication operator. As an aside, how would you do the lambda inside a list comprehension? As a general rule, I wouldn't. I would use map instead. OK: Then copy by reference using map: values = zip( map( lambda:times, xrange(num_groups) ) ) if len(values) < len(times) * num_groups ... Done. It's clearer than a list comprehension and you still really don't need a list multiply. I''m not going to bother explaining what the construction I offered would be really good at. It's pointless to explain to the disinterested. Thak constructs a list of 10 functions and never calls them. If you want to actually call the lambda, then: Yep, I was very tired. slice.indices() has nothing to do with it. Indexing a sequence and calling the .indices() method on a slice are entirely different operations. Yes, but you're very blind to history and code examples implementing the slice operation. slice usually depends on index; index does not depend on slice. Slice is suggested to be implemented by multiple calls to single indexes in traditional usage and documentation. The xrange(,,)[:] implementation breaks the tradition, because it doesn't call index multiple times; nor does it return a result equivalent identical to doing that. It's different. period. You're not convincing in the slightest by splitting hairs. -- http://mail.python.org/mailman/listinfo/python-list
Re: Preventing tread collisions
On 12/12/2012 12:29 PM, Dave Angel wrote: On 12/12/2012 03:11 PM, Wanderer wrote: I have a program that has a main GUI and a camera. In the main GUI, you can manipulate the images taken by the camera. You can also use the menu to check the camera's settings. Images are taken by the camera in a separate thread, so the long exposures don't block the GUI. I block conflicts between the camera snapshot thread and the main thread by setting a flag called self.cameraActive. I check to see if the cameraActive flag is false and set the cameraActive to True just before starting the thread. I generate an event on exiting the thread which sets the cameraActive flag to False. I also check and set and reset the flag in all the menu commands that access the camera. Like this. def onProperties(self, event): """ Display a message window with the camera properties event -- The camera properties menu event """ # Update the temperature if not self.cameraActive: self.cameraActive = True self.camera.getTemperature() camDict = self.camera.getPropertyDict() self.cameraActive = False else: camDict = {'Error': 'Camera Busy'} dictMessage(camDict, 'Camera Properties') This works I don't think so. in between the if and the assignment, another thread could get in there and also set the flag. Then when either one of them finishes, it'll clear the flag and the other code is unprotected. For semaphores between multiple threads, you either have to define only a single thread at any given moment being permitted to modify it, or you have to use lower-level primitives, sometimes called test+set operation. i don't know the "right" way to do this in Python, but this isn't it. but my question is, is there a better way using semaphores, locks or something else to prevent collisions between threads? Thanks if you already have the cameraActive variable reset by an event at thread termination; it's not necessary to set it false in the menu command. It's better NOT to do that. Your GUI menu functions need only test to see if self.cameraActive is false, and then set it to true just before the launch of the second thread. The second thread, itself, ought never change the cameraActive variable. I'm also not sure why you are able to obtain the information from the camera sequentially (camDict?) when you say you are not blocking the GUI. I assume self.camera.getTemperature() launches the second thread ? Is it, somehow, explicitly allowing the continued processing of GUI events that accessing the camera straight in the GUI would not allow? If you are talking about the Python semaphore library, I don't think you need it. Semaphores are really for use when multiple threads wish to access a resource where more than one thread can use the resource at a time; That would mean multiple threads using the camera at once... not a good idea. The Lock() object essentially does the same thing, but assumes only 1 thread may use it at a time; hence that would be sufficient (if it were needed at all!). A lock is in the "thread" library (Python 2.xx) or the "threading" library (Python 3.xx). Semaphores aren't part of the thread library in Python 2.xx... (another reason not to bother with them...) However, Locking will cause the GUI thread to block when the camera is in use, which isn't what you want -- correct? There is a way to test the lock but not block, which is equivalent to your variable (to be honest!); I'm pretty sure that Python doesn't use true Posix threads but only the GNU Pth library. That means that the only time threads truly switch is determined by the Python interpreter. In that case, all python variable assignments are going to be effectively atomic anyhow... and a variable, like you are using, is identical to a lock. (Atomic merely means the write can't be interrupted by a thread switch partway through). If you have a multi-processing environment, there is a multiprocessor library -- where the lock or semaphore mechanism would be important. But I really don't think you need it. -- http://mail.python.org/mailman/listinfo/python-list
Re: Running a python script under Linux
On 12/13/2012 06:45 PM, Steven D'Aprano wrote: I understand this is not exactly a Python question, but it may be of interest to other Python programmers, so I'm asking it here instead of a more generic Linux group. I have a Centos system which uses Python 2.4 as the system Python, so I set an alias for my personal use: [steve@ando ~]$ which python alias python='python2.7' /usr/local/bin/python2.7 When I call "python some_script.py" from the command line, it runs under Python 2.7 as I expected. So I give the script a hash-bang line: #!/usr/bin/env python and run the script directly, but instead of getting Python 2.7, it runs under Python 2.4 and gives me system errors. When I run env directly, it ignores my alias: steve@ando ~]$ /usr/bin/env python -V Python 2.4.3 What am I doing wrong? After seeing the lecture on Bad Ideas ... this might backfire on me :) But ... if you really want to make the alias show up in all bash shells, you can put it in your ~/.bashrc file which is executed every time a shell is created. alias python='python2.7' However, alias expansions do not work in non-interactive shells -- so I don't think it will launch with the #!/bin/env technique. OTOH -- Shell functions DO operate in non-interactive mode, so you could add something like: function python() { python3 # whichever version of python you want as default } # eof of function example to add to ~/.bashrc OR In a bash shell, you can also do: function python { python3 # or 2.7 ... } export -f python And that would give the same effect as an alias, but funtions can be exported to child processes. It's your system, and we're adults here -- screw it up however you want to. Cheers! -- --Jesus Christ is Lord. -- http://mail.python.org/mailman/listinfo/python-list
Re: Running a python script under Linux
On 12/13/2012 06:45 PM, Steven D'Aprano wrote: What am I doing wrong? By the way, I didn't include command line parameters as part of the function definition, so you might want to add them to insure it acts like a generic alias. Also, (alternately), you could define a generic python shell script/import with the duty of checking for a compatible python version; and if the wrong one is executing -- it could then import the shell command execution function, and *fork* the correct version of python on the script; then it could exit. ... or whatever ;) -- http://mail.python.org/mailman/listinfo/python-list
Re: where to view open() function's C implementation source code ?
On 12/18/2012 07:03 AM, Chris Angelico wrote: On Wed, Dec 19, 2012 at 1:28 AM, Roy Smith wrote: In article, iMath wrote: Download the source for the version you're interested in. but which python module is open() in ? I met you half-way, I showed you where the source code is. Now you need to come the other half and look at the code. Maybe start by grepping the entire source tree for "open"? Ouch, that mightn't be very effective! With some function names, you could do that. Not so much "open". Still, it'd be a start... ChrisA In Python3.3.0 -- the built in open() appears in Python-3.3.0/Modules/_io/_iomodule.c; There is another module defined in an object in Python-3.3.0/Modules/_io/fileio.c; but I don't think that the one called when a lone x=open(...) is done. Cheers. --Andrew. -- http://mail.python.org/mailman/listinfo/python-list
Vote tallying...
Hi, I have a problem which may fit in a mysql database, but which I only have python as an alternate tool to solve... so I'd like to hear some opinions... I'm building a experimental content management program on a standard Linux Web server. And I'm needing to keep track of archived votes and their voters -- for years. Periodically, a python program could be given a batch of new votes removed from the database, and some associated comments, which are no longer real-time necessary; and then a python script needs to take that batch of votes, and apply them to an appropriate archive file. It's important to note that it won't just be appending new votes, it will be sorting through a list of 10's of thousands of votes, and changing a *few* of them, and appending the rest. XML may not be the ideal solution, but I am easily able to see how it might work. I imagine a file like the following might be inefficient, but capable of solving the problem: 12345A3 FF734B5D 7FBED The woodstock games I think you're on drugs, man.! It would have been better if they didn't wake up in the morning. 10 1 3 The questions I have are, is using XML for vote recording going to be slow compared to other stock solutions that Python may have to offer? The voter ID's are unique, 32 bits long, and the votes are only from 1 to 10. (4 bits.). I'm free to use any import that comes with python 2.5. so if there's something better than XML, I'm interested. And secondly, how likely is this to still work once the vote count reaches 10 million? Is an XML file with millions of entries something someone has already tried succesfully? -- http://mail.python.org/mailman/listinfo/python-list
Re: Vote tallying...
On 01/18/2013 08:47 AM, Stefan Behnel wrote: Andrew Robinson, 18.01.2013 00:59: I have a problem which may fit in a mysql database Everything fits in a MySQL database - not a reason to use it, though. Py2.5 and later ship with sqlite3 and if you go for an external database, why use MySQL if you can have PostgreSQL for the same price? MySQL is provided by the present server host. It's pretty standard at web hosting sites. It works through "import MySQLdb" -- and it means an IP call for every action... Postgre isn't available :( otherwise, I'd use it I'm mildly concerned about scaling issues but don't have a lot of time (just a few days) to come to a decision. I don't need high performance, just no grotesque degradation when the system is scaled up, and no maintenance nightmare. The votes table is going to get monsterous if all votes are held in one table Your comment about sqlite is interesting; I've never used it before. At a glance, it uses individual files as databases, which is good... But it wants to lock the entire database against reads as well as writes when any access of the database happens. Which is bad... http://www.sqlite.org/different.html http://www.sqlite.org/whentouse.html ... XML files are a rather static thing and meant to be processed from start to end on each run. That adds up if the changes are small and local while the file is ever growing. You seem to propose one file per article, which might work. That's unlikely to become too huge to process, and Python's cElementTree is a very fast XML processor. Yes, that's exactly what I was thinking one file/article. It's attractive, I think, because many Python programs are allowed to read the XML file concurrently, but only one periodically updates it as a batch/chron/or triggered process; eg: the number/frequency of update is actually controllable. eg: MySQL accumulates a list of new votes and vote changes and python occasionally flushes the database into the archive file. That way, MySQL only maintains a small database of real-time changes, and the speed/accuracy of the vote tally can be tailored to the user's need. However, your problem sounds a lot like you could map it to one of the dbm databases that Python ships. They work like dicts, just on disk. Doing a Google search, I see some of these that you are mentioning -- yes, they may have some potential. IIUC, you want to keep track of comments and their associated votes, maybe also keep a top-N list of the highest voted comments. So, keep each comment and its votes in a dbm record, referenced by the comment's ID (which, I assume, you keep a list of in the article that it comments on). The comments themselves are just ancillary information; the votes only apply to the article itself at this time. The two pieces of feedback information are independent, occasionally having a user that gives both kinds. Statistically, there are many votes -- and few comments. Each archive file has the same filename as the article that is being commented or voted on; but with a different extension (eg: xml, or .db,or...) so there's no need to store article information on each vote or comment; (unlike the MySQL database, which has to store all that information for every vote ugh!) You can use pickle (see the shelve module) or JSON or whatever you like for storing that record. Then, on each votes update, look up the comment, change its votes and store it back. If you keep a top-N list for an article, update it at the same time. Consider storing it either as part of the article or in another record referenced by the article, depending of how you normally access it. You can also store the votes independent of the comment (i.e. in a separate record for each comment), in case you don't normally care about the votes but read the comments frequently. It's just a matter of adding an indirection for things that you use less frequently and/or that you use in more than one place (not in your case, where comments and votes are unique to an article). You see, lots of options, even just using the stdlib... Stefan Yes, lots of options Let's see... you've noticed just about everything important, and have lots of helpful thoughts; thank you. There are implementation details I'm not aware of regarding how the file-system dictionaries (dbm) work; and I wouldn't know how to compare it to XML access speed either but I do know some general information about how the data might be handled algorithmically; and which might suggest a better Python import to use? If I were to sort all votes by voter ID (a 32 bit number), and append the vote value (A 4 to 8bit number); Then a vote becomes a chunk of 40 bits, fixed length; and I can stack one right after another in a compact format. Blocks of compacted votes are ideal for bin
XML/XHTML/HTML differences, bugs... and howto
Good day :), I've been exploring XML parsers in python; particularly: xml.etree.cElementTree; and I'm trying to figure out how to do it incrementally, for very large XML files -- although I don't think the problems are restricted to incremental parsing. First problem: I've come across an issue where etree silently drops text without telling me; and separate. I am under the impression that XHTML is a subset of XML (eg:defined tags), and that once an HTML file is converted to XHTML, the body of the document can be handled entirely as XML. If I convert a (partial/contrived) html file like: This is example bold text. to XHTML, I might do --right or wrong-- (1): This is example bold text. or, alternate difference: (2): " This is example bold text. " But, when I parse with etree, in example (1) both "This is an example" and "text." are dropped; The missing text is part of the start, or end event tags, in the incrementally parsed method. Likewise: In example (2), only "text" gets dropped. So, etree is silently dropping all text following a close tag, but before another open tag happens. Q: Isn't XML supposed to error out when invalid xml is parsed? Is there a way in etree to recover/access the dropped text? If not -- is the a python library issue, or the underlying expat.so, etc. library. Secondly; I have an XML file which will grow larger than memory on a target machine, so here's what I want to do: Given a source XML file, and a destination file: 1) iteratively scan part of the source tree. 2) Optionally Modify some of scanned tree. 3) Write partial scan/tree out to the destination file. 4) Free memory of no-longer needed (partial) source XML. 5) continue scanning a new section of the source file... eg: goto step 1 until source file is exhausted. But, I don't see a way to write portions of an XML tree, or iteratively write a tree to disk. How can this be done? :) Thanks! -- http://mail.python.org/mailman/listinfo/python-list
Re: XML/XHTML/HTML differences, bugs... and howto
On 01/24/2013 06:42 AM, Stefan Behnel wrote: Andrew Robinson, 23.01.2013 16:22: Good day :), Nope, you should read the manual on this. Here's a tutorial: http://lxml.de/tutorial.html#elements-contain-text I see, so it should be under the "tail" attribute, not the "text" attribute. That's why I missed it. But, I don't see a way to write portions of an XML tree, or iteratively write a tree to disk. How can this be done? There are several ways to do it. Python has a couple of external libraries available that are made specifically for generating markup incrementally. lxml also gained that feature recently. It's not documented yet, but here are usage examples: https://github.com/lxml/lxml/blob/master/src/lxml/tests/test_incremental_xmlfile.py Stefan Thanks Stefan ! I'll look that over. :) -- http://mail.python.org/mailman/listinfo/python-list
XML validation / exception.
A quick question: On xml.etree, When I scan in a handwritten XML file, and there are mismatched tags -- it will throw an exception. and the exception will contain a line number of the closing tag which does not have a mate of the same kind. Is there a way to get the line number of the earlier tag which caused the XML parser to know the closing tag was mismatched, so I can narrow down the location of the mismatches for a manual repair? (I don't want auto-repair like beautiful soup. but google is worthless for finding a solution...) And secondly, for times where I want to throw a software/content specific error on valid XML files; I don't see which attribute of an element, or method, allows me to find out the line number and column number that an element I am examining is found at. ? How do I get it ? Cheers, --Andrew. -- http://mail.python.org/mailman/listinfo/python-list
Re: Hey, I'm new to python so don't judge.
When i check the code it comes up with invalid syntax and my writing line gets re directed here def is_same(target, number: if target == number: result="win" elif target > number: result="low" else: result="high" return result -- https://mail.python.org/mailman/listinfo/python-list
Re: Hey, I'm new to python so don't judge.
On Wednesday, January 4, 2017 at 1:03:18 PM UTC+13, Erik wrote: > On 03/01/17 23:56, Chris Angelico wrote: > > On Wed, Jan 4, 2017 at 10:49 AM, wrote: > >> #think of a number > >> computer_number = number.randint(1,100) > > > > What's wrong is that you aren't showing us the exception you get on > > this line. *Copy and paste* that exception - the whole thing. It's > > very helpful. > > I doubt it's getting that far (I can see at least one syntax error in > the code pasted). > > cr2001: I echo Chris's sentiment though - what is the error you are > seeing (in it's entirety)? > > E. My apologizes but i'm quite new and would need instructions to what information you need me to get. -- https://mail.python.org/mailman/listinfo/python-list
Re: Hey, I'm new to python so don't judge.
On Wednesday, January 4, 2017 at 1:17:11 PM UTC+13, Chris Angelico wrote: > On Wed, Jan 4, 2017 at 11:03 AM, Erik wrote: > > I doubt it's getting that far (I can see at least one syntax error in the > > code pasted). > > True true. In any case, the point is to copy and paste the error > message. Callum, please, copy and paste it. > > ChrisA I'm sorry if I'm doing something wrong but all that is happening is when i try to run it a popup says Invalid syntax -- https://mail.python.org/mailman/listinfo/python-list
Re: Hey, I'm new to python so don't judge.
On Wednesday, January 4, 2017 at 1:26:26 PM UTC+13, Erik wrote: > Hi Callum, > > On 04/01/17 00:02, Callum Robinson wrote: > > When i check the code it comes up with invalid syntax and my writing > line gets re directed here > > > > def is_same(target, number: > > if target == number: > > result="win" > > elif target > number: > > result="low" > > else: > > result="high" > > return result > > OK, good. That implies it's something wrong with the function definition > ('def'). Look at that very carefully :) (*) > > E. > > (*) My emoticon may give you a hint ... I feel like im missing something so blatantly obvious. -- https://mail.python.org/mailman/listinfo/python-list
Re: Hey, I'm new to python so don't judge.
On Wednesday, January 4, 2017 at 1:26:26 PM UTC+13, Erik wrote: > Hi Callum, > > On 04/01/17 00:02, Callum Robinson wrote: > > When i check the code it comes up with invalid syntax and my writing > line gets re directed here > > > > def is_same(target, number: > > if target == number: > > result="win" > > elif target > number: > > result="low" > > else: > > result="high" > > return result > > OK, good. That implies it's something wrong with the function definition > ('def'). Look at that very carefully :) (*) > > E. > > (*) My emoticon may give you a hint ... I forgot a bloody bracket xD and now theirs a new error ill try to figure this out on my own. -- https://mail.python.org/mailman/listinfo/python-list
Re: Hey, I'm new to python so don't judge.
On Wednesday, January 4, 2017 at 1:45:22 PM UTC+13, Erik wrote: > Hi Callum, > > On 04/01/17 00:30, Callum Robinson wrote: > > I feel like im missing something so blatantly obvious. > > That's because you are ;). I don't want to come across as patronising, > but I want you to see it for yourself, so, here's a function definition > similar to yours that doesn't have the same syntax error that yours does: > > def foo(spam, ham): > if spam == ham: > return "same" > return "different" > > See the difference? > > E. I've figured out that out but I have a new issue. I like what you are doing making me figure this out as it helps me remember. I'll post the new code and the issue. If you could give me a hint that would be great. -- Issue -- Traceback (most recent call last): File "D:/Python/random.py", line 6, in computer_number = number.randint(1, 100) NameError: name 'number' is not defined - Here is the most recent code - # mynumber.py # this game uses a home made function import random #think of a number computer_number = number.randint(1, 100) #create the function is_same() def is_same(target, number): if target == number: result="Win" elif target > number: result="Low" else: result="High" return result # start the game print("hello. \nI have thought of a number between 1 and 100.") #collect the user's guess as an interger guess = int(input("Can you guess it? ")) #Use our function higher_or_lower = is_same(computer_number, guess) #run the game untill the user is correct while higher_or_lower != "win": if higher_or_lower == "low": guess = int(input("Sorry, you are too low. Try again.")) else: guess = int(input("Sorry your are too high. Try again.")) higher_or_lower = is_same(computer_number, guess) #end of game input("Correct!\nWell Done\n\n\nPress RETURN to exit.") -- https://mail.python.org/mailman/listinfo/python-list
Re: Hey, I'm new to python so don't judge.
On Wednesday, January 4, 2017 at 2:16:08 PM UTC+13, Steve D'Aprano wrote: > On Wed, 4 Jan 2017 12:04 pm, Callum Robinson wrote: > > > Traceback (most recent call last): > > File "D:/Python/random.py", line 6, in > > computer_number = number.randint(1, 100) > > NameError: name 'number' is not defined > > > That's exactly what we need to see! The full traceback, thank you! > > You're asking Python to get the variable "number", and call the randint > method. But: > > - you don't have a variable called "number"; > > NameError: name 'number' is not defined > > > - and even if you did, that's not how you get a random number. What you want > is: > > computer_number = random.randint(1, 100) > > > > > > > -- > Steve > “Cheer up,” they said, “things could be worse.” So I cheered up, and sure > enough, things got worse. Hey man thanks, the sad thing is i have no idea why i put that in. I must be having a terrible day. -- https://mail.python.org/mailman/listinfo/python-list
Re: Hey, I'm new to python so don't judge.
On Wednesday, January 4, 2017 at 12:49:28 PM UTC+13, Callum Robinson wrote: > Im doing a new task from my teacher but i can't seem to find what is wrong > with this code. Can anyone help? > > #mynumber.py > # this game uses a home made function > import random > > #think of a number > computer_number = number.randint(1,100) > > #create the function is_same() > def is_same(target, number: > if target == number: > result="win" > elif target > number: > result="low" > else: > result="high" > return result > > # start the game > print("hello. \nI have thought of a number between 1 and 100.") > > #collect the user's guess as an interger > guess = int(input("Can you guess it? ")) > #Use our function > higher_or_lower = is_same(computer_number, guess) > #run the game untill the user is correct > while higher_or_lower != "win" > if higher_or_lower == "to low" > guess = int(input("Sorry, you are too low. Try again.")) > else: > guess = int(input("Sorry your are too high. Try again.")) > > higher_or_lower = is_same(computer_number, guess) > > #end of game > input("Correct!\nWell Done\n\n\nPress RETURN to exit.") Hey again, i'm sorry for bothering you with so many questions i just did not want to keep asking my teacher who is on holiday these. I have another issue where the code runs but i can guess every number from 1-100 but it always says Sorry your are too high. Try again. I don't understand what i have done to cause this. -- https://mail.python.org/mailman/listinfo/python-list
Re: Hey, I'm new to python so don't judge.
On Wednesday, January 4, 2017 at 3:05:48 PM UTC+13, MRAB wrote: > On 2017-01-04 01:37, Callum Robinson wrote: > > On Wednesday, January 4, 2017 at 12:49:28 PM UTC+13, Callum Robinson wrote: > >> Im doing a new task from my teacher but i can't seem to find what is wrong > >> with this code. Can anyone help? > >> > >> #mynumber.py > >> # this game uses a home made function > >> import random > >> > >> #think of a number > >> computer_number = number.randint(1,100) > >> > >> #create the function is_same() > >> def is_same(target, number: > >> if target == number: > >> result="win" > >> elif target > number: > >> result="low" > >> else: > >> result="high" > >> return result > >> > >> # start the game > >> print("hello. \nI have thought of a number between 1 and 100.") > >> > >> #collect the user's guess as an interger > >> guess = int(input("Can you guess it? ")) > >> #Use our function > >> higher_or_lower = is_same(computer_number, guess) > >> #run the game untill the user is correct > >> while higher_or_lower != "win" > >> if higher_or_lower == "to low" > >> guess = int(input("Sorry, you are too low. Try again.")) > >> else: > >> guess = int(input("Sorry your are too high. Try again.")) > >> > >> higher_or_lower = is_same(computer_number, guess) > >> > >> #end of game > >> input("Correct!\nWell Done\n\n\nPress RETURN to exit.") > > > > Hey again, i'm sorry for bothering you with so many questions i just did > > not want to keep asking my teacher who is on holiday these. > > > > I have another issue where the code runs but i can guess every number from > > 1-100 but it always says Sorry your are too high. Try again. I don't > > understand what i have done to cause this. > > > What values can 'is_same' return? > > Which of those values are you checking for in the loop? I'm sorry but i do not completely understand what you are stating -- https://mail.python.org/mailman/listinfo/python-list
Re: Hey, I'm new to python so don't judge.
On Wednesday, January 4, 2017 at 3:35:53 PM UTC+13, Erik wrote: > On 04/01/17 02:24, Callum Robinson wrote: > > On Wednesday, January 4, 2017 at 3:05:48 PM UTC+13, MRAB wrote: > >> What values can 'is_same' return? > >> > >> Which of those values are you checking for in the loop? > > > > I'm sorry but i do not completely understand what you are stating > > You need to think about the specific things (their type, their exact > values) that your functions might return. Printing some trace output is > a classic way of debugging your program. If, after this line: > > >>>> higher_or_lower = is_same(computer_number, guess) > > ... you added: > > print (higher_or_lower) > > ... what values do you then see being output? How will those values be > processed by the conditions you see that work on the "higher_or_lower" > variable? > > E. I did it and this is what it states when i run it hello. I have thought of a number between 1 and 100. Can you guess it? 5 Low Sorry , you are too high. Try again. Does this mean the number i entered is to low but the code is still stating it is to high? -- https://mail.python.org/mailman/listinfo/python-list
Re: Hey, I'm new to python so don't judge.
On Wednesday, January 4, 2017 at 1:17:11 PM UTC+13, Chris Angelico wrote: > On Wed, Jan 4, 2017 at 11:03 AM, Erik wrote: > > I doubt it's getting that far (I can see at least one syntax error in the > > code pasted). > > True true. In any case, the point is to copy and paste the error > message. Callum, please, copy and paste it. > > ChrisA I'm sorry if I'm doing something wrong but all that is happening is when i try to run it a popup says Invalid syntax -- https://mail.python.org/mailman/listinfo/python-list
Re: Hey, I'm new to python so don't judge.
When i check the code it comes up with invalid syntax and my writing line gets re directed here def is_same(target, number: if target == number: result="win" elif target > number: result="low" else: result="high" return result -- https://mail.python.org/mailman/listinfo/python-list
Re: Hey, I'm new to python so don't judge.
On Wednesday, January 4, 2017 at 1:26:26 PM UTC+13, Erik wrote: > Hi Callum, > > On 04/01/17 00:02, Callum Robinson wrote: > > When i check the code it comes up with invalid syntax and my writing > line gets re directed here > > > > def is_same(target, number: > > if target == number: > > result="win" > > elif target > number: > > result="low" > > else: > > result="high" > > return result > > OK, good. That implies it's something wrong with the function definition > ('def'). Look at that very carefully :) (*) > > E. > > (*) My emoticon may give you a hint ... I forgot a bloody bracket xD and now theirs a new error ill try to figure this out on my own. -- https://mail.python.org/mailman/listinfo/python-list
Re: Hey, I'm new to python so don't judge.
On Wednesday, January 4, 2017 at 1:03:18 PM UTC+13, Erik wrote: > On 03/01/17 23:56, Chris Angelico wrote: > > On Wed, Jan 4, 2017 at 10:49 AM, wrote: > >> #think of a number > >> computer_number = number.randint(1,100) > > > > What's wrong is that you aren't showing us the exception you get on > > this line. *Copy and paste* that exception - the whole thing. It's > > very helpful. > > I doubt it's getting that far (I can see at least one syntax error in > the code pasted). > > cr2001: I echo Chris's sentiment though - what is the error you are > seeing (in it's entirety)? > > E. My apologizes but i'm quite new and would need instructions to what information you need me to get. -- https://mail.python.org/mailman/listinfo/python-list
Re: Hey, I'm new to python so don't judge.
On Wednesday, January 4, 2017 at 2:16:08 PM UTC+13, Steve D'Aprano wrote: > On Wed, 4 Jan 2017 12:04 pm, Callum Robinson wrote: > > > Traceback (most recent call last): > > File "D:/Python/random.py", line 6, in > > computer_number = number.randint(1, 100) > > NameError: name 'number' is not defined > > > That's exactly what we need to see! The full traceback, thank you! > > You're asking Python to get the variable "number", and call the randint > method. But: > > - you don't have a variable called "number"; > > NameError: name 'number' is not defined > > > - and even if you did, that's not how you get a random number. What you want > is: > > computer_number = random.randint(1, 100) > > > > > > > -- > Steve > â £Cheer up,â Ø they said, â £things could be worse.â Ø So I cheered up, and sure > enough, things got worse. Hey man thanks, the sad thing is i have no idea why i put that in. I must be having a terrible day. -- https://mail.python.org/mailman/listinfo/python-list
Re: Hey, I'm new to python so don't judge.
On Wednesday, January 4, 2017 at 1:26:26 PM UTC+13, Erik wrote: > Hi Callum, > > On 04/01/17 00:02, Callum Robinson wrote: > > When i check the code it comes up with invalid syntax and my writing > line gets re directed here > > > > def is_same(target, number: > > if target == number: > > result="win" > > elif target > number: > > result="low" > > else: > > result="high" > > return result > > OK, good. That implies it's something wrong with the function definition > ('def'). Look at that very carefully :) (*) > > E. > > (*) My emoticon may give you a hint ... I feel like im missing something so blatantly obvious. -- https://mail.python.org/mailman/listinfo/python-list
Re: Hey, I'm new to python so don't judge.
On Wednesday, January 4, 2017 at 12:49:28 PM UTC+13, Callum Robinson wrote: > Im doing a new task from my teacher but i can't seem to find what is wrong with this code. Can anyone help? > > #mynumber.py > # this game uses a home made function > import random > > #think of a number > computer_number = number.randint(1,100) > > #create the function is_same() > def is_same(target, number: > if target == number: > result="win" > elif target > number: > result="low" > else: > result="high" > return result > > # start the game > print("hello. \nI have thought of a number between 1 and 100.") > > #collect the user's guess as an interger > guess = int(input("Can you guess it? ")) > #Use our function > higher_or_lower = is_same(computer_number, guess) > #run the game untill the user is correct > while higher_or_lower != "win" > if higher_or_lower == "to low" > guess = int(input("Sorry, you are too low. Try again.")) > else: > guess = int(input("Sorry your are too high. Try again.")) > > higher_or_lower = is_same(computer_number, guess) > > #end of game > input("Correct!\nWell Done\n\n\nPress RETURN to exit.") Hey again, i'm sorry for bothering you with so many questions i just did not want to keep asking my teacher who is on holiday these. I have another issue where the code runs but i can guess every number from 1-100 but it always says Sorry your are too high. Try again. I don't understand what i have done to cause this. -- https://mail.python.org/mailman/listinfo/python-list
Re: Hey, I'm new to python so don't judge.
On Wednesday, January 4, 2017 at 1:45:22 PM UTC+13, Erik wrote: > Hi Callum, > > On 04/01/17 00:30, Callum Robinson wrote: > > I feel like im missing something so blatantly obvious. > > That's because you are ;). I don't want to come across as patronising, > but I want you to see it for yourself, so, here's a function definition > similar to yours that doesn't have the same syntax error that yours does: > > def foo(spam, ham): > if spam == ham: > return "same" > return "different" > > See the difference? > > E. I've figured out that out but I have a new issue. I like what you are doing making me figure this out as it helps me remember. I'll post the new code and the issue. If you could give me a hint that would be great. -- Issue -- Traceback (most recent call last): File "D:/Python/random.py", line 6, in computer_number = number.randint(1, 100) NameError: name 'number' is not defined - Here is the most recent code - # mynumber.py # this game uses a home made function import random #think of a number computer_number = number.randint(1, 100) #create the function is_same() def is_same(target, number): if target == number: result="Win" elif target > number: result="Low" else: result="High" return result # start the game print("hello. \nI have thought of a number between 1 and 100.") #collect the user's guess as an interger guess = int(input("Can you guess it? ")) #Use our function higher_or_lower = is_same(computer_number, guess) #run the game untill the user is correct while higher_or_lower != "win": if higher_or_lower == "low": guess = int(input("Sorry, you are too low. Try again.")) else: guess = int(input("Sorry your are too high. Try again.")) higher_or_lower = is_same(computer_number, guess) #end of game input("Correct!\nWell Done\n\n\nPress RETURN to exit.") -- https://mail.python.org/mailman/listinfo/python-list
Re: Hey, I'm new to python so don't judge.
On Wednesday, January 4, 2017 at 3:05:48 PM UTC+13, MRAB wrote: > On 2017-01-04 01:37, Callum Robinson wrote: > > On Wednesday, January 4, 2017 at 12:49:28 PM UTC+13, Callum Robinson wrote: > >> Im doing a new task from my teacher but i can't seem to find what is wrong with this code. Can anyone help? > >> > >> #mynumber.py > >> # this game uses a home made function > >> import random > >> > >> #think of a number > >> computer_number = number.randint(1,100) > >> > >> #create the function is_same() > >> def is_same(target, number: > >> if target == number: > >> result="win" > >> elif target > number: > >> result="low" > >> else: > >> result="high" > >> return result > >> > >> # start the game > >> print("hello. \nI have thought of a number between 1 and 100.") > >> > >> #collect the user's guess as an interger > >> guess = int(input("Can you guess it? ")) > >> #Use our function > >> higher_or_lower = is_same(computer_number, guess) > >> #run the game untill the user is correct > >> while higher_or_lower != "win" > >> if higher_or_lower == "to low" > >> guess = int(input("Sorry, you are too low. Try again.")) > >> else: > >> guess = int(input("Sorry your are too high. Try again.")) > >> > >> higher_or_lower = is_same(computer_number, guess) > >> > >> #end of game > >> input("Correct!\nWell Done\n\n\nPress RETURN to exit.") > > > > Hey again, i'm sorry for bothering you with so many questions i just did not want to keep asking my teacher who is on holiday these. > > > > I have another issue where the code runs but i can guess every number from 1-100 but it always says Sorry your are too high. Try again. I don't understand what i have done to cause this. > > > What values can 'is_same' return? > > Which of those values are you checking for in the loop? I'm sorry but i do not completely understand what you are stating -- https://mail.python.org/mailman/listinfo/python-list
Re: Hey, I'm new to python so don't judge.
On Wednesday, January 4, 2017 at 3:35:53 PM UTC+13, Erik wrote: > On 04/01/17 02:24, Callum Robinson wrote: > > On Wednesday, January 4, 2017 at 3:05:48 PM UTC+13, MRAB wrote: > >> What values can 'is_same' return? > >> > >> Which of those values are you checking for in the loop? > > > > I'm sorry but i do not completely understand what you are stating > > You need to think about the specific things (their type, their exact > values) that your functions might return. Printing some trace output is > a classic way of debugging your program. If, after this line: > > >>>> higher_or_lower = is_same(computer_number, guess) > > ... you added: > > print (higher_or_lower) > > ... what values do you then see being output? How will those values be > processed by the conditions you see that work on the "higher_or_lower" > variable? > > E. I did it and this is what it states when i run it hello. I have thought of a number between 1 and 100. Can you guess it? 5 Low Sorry , you are too high. Try again. Does this mean the number i entered is to low but the code is still stating it is to high? -- https://mail.python.org/mailman/listinfo/python-list
installer question
Target audience is little or no programming experience. I have a win32 only library I need to write an installer for. As part of the installation it must: 1.. find where a program is installed 2.. copy a file to the directory 3.. add the directory to the pythonpath and change a ini file. 4.. add a example directory at a user selected path.As well as add this to pythonpath. 5.. Add the main library to site packages. There is also a package of examples which need to be independently upgradable and located in the main directory. Suggestions? I'm thinking disutils would make for the easiest method but as far as I can see you can't run a script on finishing the installation or get the user to select from a directory. Nor does it seem contain methods to find windows programs without downloading pythonwin32 as well. For the examples, NSIS or equivalent looks to be what I need but overly complicated. Can you combine NSIS and disutils? Or should I just use NSIS without disutils. Advice appreciated. The first time I've released software before ;-) Guy -- http://mail.python.org/mailman/listinfo/python-list
Re: The Industry choice
On Fri, 07 Jan 2005 12:06:42 -0800, Jeff Shannon <[EMAIL PROTECTED]> wrote: >Bulba! wrote: > >> On 6 Jan 2005 19:01:46 -0500, [EMAIL PROTECTED] (Aahz) wrote: >> >> >>>>Note that the so-called 'viral' nature of GPL code only applies to >>>>*modifications you make* to the GPL software. The *only* way in which >>>>your code can be 'infected' by the GPL is if you copy GPL source. >> >> >>>That's not true -- consider linking to a GPL library. >> >> >> Will someone please explain to me in simple terms what's >> the difference between linking to LGPLed library and linking >> to GPLed library - obviously in terms of consequences of >> what happens to _your_ source code? >> >> Because if there isn't any, why bother with distinguishing >> between the two? > >Releasing a product in which your code is linked together with GPL'ed >code requires that your code also be GPL'ed. The GPL goes to some >lengths to define what exactly "linked together" means. That looks like a typo. The LGPL goes to great length to how you can link to LGPL software without using either the LGPL or GPL. The GPL (linked to by fsf.org) merely states: 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: Note that the conditions are all those of any program released under the GPL. Whatever "forming a work based on the Program" means is whatever you and the copyright owner agree to, or whatever copyright law considers a derived work in areas you wish to release your code into. I would suggest consulting a lawyer before getting close to the line, but you can expect that any legally enforceable restrictions claimed by FSF and/or RMS to be legally binding on all software released under the (L)GPL that the FSF owns the copyright of (they encourage programmers to sign over copyright to the FSF itself). > >Releasing a product in which your code is linked together with LGPL'ed >code does *not* require that your code also be (L)GPL'ed. Changes to >the core library must still be released under (L)GPL, but application >code which merely *uses* the library does not. (I've forgotten, now, >exactly how LGPL defines this distinction...) > >Jeff Shannon >Technician/Programmer >Credit International Scott Robinson -- http://mail.python.org/mailman/listinfo/python-list
getting a class attribute using a keyword argument
Hello, I have a list of class instances. I wish to get the appropriate class attribute in each class instance depending on a SINGLE keyword in the calling class. How do I get the calling method to correctly recognise the keyword as a keyword and not a class attribute? See example code below (which doesn't work). class tocall: def __init__(self): self.title = "test" self.name = "name" def callingmethod(self,**kw): for key in kw: if tocall.key == kw[key]: return tocall.key which should work as such(but doesn't): print callmethod(title = "test") print callmethod(name = "name") Regards, Guy -- http://mail.python.org/mailman/listinfo/python-list
Re: python and gpl
On 30 Jan 2005 21:59:25 -0800, Paul Rubin <http://[EMAIL PROTECTED]> wrote: >John Hunter <[EMAIL PROTECTED]> writes: >> The question is: does shipping a backend which imports a module that >> links with GPL code make some or all of the library GPL. > >Literally speaking, no, not automatically, any more than driving a car >makes you into a licensed driver if you weren't one already. But if >you weren't licensed, then you've broken the law by driving the car. >So your question should be: 1) is shipping that backend one of the >things you need the GPL to license you to legally do, and 2) if so, >does the GPL in fact give you that license? > >If you're asking in terms of legal enforcement, the answer is 1) maybe >and 2) almost certainly not. I think it's better to ask in terms of >the GPL's spirit. I would say that it's not in the GPL's spirit and >that GPL die-hards would consider that use objectionable, though they >might make exceptions for specific cases (so it doesn't hurt to ask). >Some authors who use the GPL are less strict about how they interpret >it, so again, the friendly thing to do is ask the author. > > * If a backend module somebackend does > > import somelib > >where somelib is a python wrapper of GPL code, is somebackend GPLd? > >It's GPL'd if you GPL it. If you don't GPL it, then distributing it >it may be a GPL violation that could get you taken to court. I >believe the FSF's view is that it is fact a violation; however, the >courts have not yet established this. The law doesn't have a >black-and-white boundary. It's more like a fractal. The only way to >find out what a court will decide is to actually try a case there. > >Rather than try to probe how closely you can dance around the >boundaries of the GPL, you might just ask the author of the GPL'd >library whether what you want to do is ok with him or her. If s/he >says no and you do it anyway, you're both inviting trouble over the >possible infringement, and also inviting people to try to use your >code in ways you don't like. Since the free software movement depends >on a spirit of cooperation, I think it's best to avoid trying to press >too hard against the boundaries of anyone's licenses. > >http://www.gnu.org/licenses/gpl-faq.html If you read the GPL, it claims everything it can (any "work" created using GPLed "work"). My guess is that anything that calls the code in a way not specifically allowed by the author is going to get you into trouble. IANAL, but from what I can remember about earlier licensing issues, any code specific for a GPLed library (especially "import") will get you into to trouble. Having a non-free library with an identical API and issuing exec("import "+sys.argv[1]) where the user can supply sys.argv as the name of the gpl'ed library will work (I think there is a free/non-free library out there that is never run, but exists for exactly this condition). Scott Robinson -- http://mail.python.org/mailman/listinfo/python-list
howto load and unload a module
Hello, I have a directory of python scripts that all (should) contain a number of attributes and methods of the same name. I need to import each module, test for these items and unload the module. I have 2 questions. 1.. How do unload an imported module? 2.. how do I test for the existance of a method in a module without running it? TIA, Guy -- http://mail.python.org/mailman/listinfo/python-list
Re: howto load and unload a module
> > Why would you want to? Doing what you describe doesn't require that you > "unload" a module, unless that means something more to you than, say, > merely releasing the memory used by it (which is likely insignificant to > you). > Hi Peter, I have an application with Python embedded. I'm parsing a script directory to build a dictionary of script names with descriptions of what the scripts etc extracted from each script. The user then selects one of these scripts to execute by the embedded python. Some of these scripts could potentially be quite large. Also the list of scripts could be quite large. So the main reason for unloading modules is to save memory. Regards, Guy -- http://mail.python.org/mailman/listinfo/python-list
Re: howto load and unload a module
> BTW, question for the OP: what on earth is the use-case for this? Bulk > checking of scripts written by students? > > Cheers, > John I've embedded python in an application which has a .NET API. So users can write scripts in python that access the .NET API. Because of the way the API works running scripts is a 2 stage process. First you select a script from a list then run the selected script. All scripts must therefore share a common calling function name and I wanted to test this function existed. I will have no idea the name or how many or how complicated the scripts will be so it seemed a good idea to try and free up memory from the scripts that won't be run. >(It's hard to judge a poster's level of expertise in Python without any example >code from him. I'm not a professional programmer so my terminology is probably confusing.It looks like I shouldn't worry about memory issues. Thanks for your help Peter and John, Guy -- http://mail.python.org/mailman/listinfo/python-list
Re: python for microcontrollers
How about just helping this project: http://pyastra.sourceforge.net/ I know he's trying to rewrite it to work across multiple uC's (AVR,msp430 etc) HTH, Guy Evil Bastard wrote: > Hi all, > > I'm currently tackling the problem of implementing a python to assembler > compiler for PIC 18Fxxx microcontrollers, and thought I'd open it up > publicly for suggestions before I embed too many mistakes in the > implementation. > > The easy part is getting the ast, via compiler.ast. Also easy is > generating the code, once the data models are worked out. > > The hard part is mapping from the abundant high-level python reality to > the sparse 8-bit microcontroller reality. > > I looked at pyastra, but it has fatal problems for my situation: > - no backend for 18fxxx devices > - only 8-bit ints supported > > I'm presently ripping some parts from the runtime engine of a forth > compiler I wrote earlier, to add support for 8-32 bit ints, floats, and > a dual-stack environment that offers comfortable support for local > variables/function parameters, as well as support for simpler and more > compact code generation. > > Python is all about implicitly and dynamically creating/destroying > arbitrarily typed objects from a heap. I've got a very compact > malloc/free, and could cook up a refcounting scheme, but using this for > core types like ints would destroy performance, on a chip that's already > struggling to do 10 mips. > > The best idea I've come up with so far is to use a convention of > identifier endings to specify type, eg: > - foo_i16 - signed 16-bit > - foo_u32 - unsigned 32-bit > - bar_f - 24-bit float > - blah - if an identifier doesn't have a 'magic ending', it will > be deemed to be signed 16-bit > > also, some virtual functions uint16(), int16(), uint32(), int32(), > float() etc, which work similar to C casting and type conversion, so I > don't have to struggle with type inference at compile time. > > Yes, this approach sucks. But can anyone offer any suggestions which > suck less? > -- http://mail.python.org/mailman/listinfo/python-list
Re: Big development in the GUI realm
On Mon, 07 Feb 2005 20:56:44 -0800, Courageous <[EMAIL PROTECTED]> wrote: > >>OK, so according to Linus, the GPL allows > >No. Pay attention. Linus has his own revised version, to clarify >this point, and in fact /overruling/ the GPL if the point is >clarified differently by RMS or others. > >That's the right of their community, it's /their/ code. > >>make calls to the kernel, but TrollTech says the GPL doesn't allow a >>proprietary program to make calls to the Qt library. > >That's their prerogative, although TrollTech's authority as an >/interpretational/ entity over the GPL means precisely zero. I >wouldn't push this, though, unless you've got a big litigation >budget. It should also be pointed out that the FSF's interpretation of the GPL with respect to Qt means absolutely zero. If TrollTech publishes an interpretation of the GPL and announces it to any interested in licensing their software, I suspect that the courts will take that into consideration. This won't help that at all if it isn't a legally valid interpretation, but it establishes that you *knew* what their interpretation was when you agreed to the terms to distribute their copyrighted software. > >>It's this double-standard that I find confusing, since both projects >>are said to be based on the same license. > >Linus doesn't use "the" GPL, he uses "his" GPL, version-whatever. > >Anyway, your safe bet: > >Follow the copyright holder's wishes. > >That's fair. After all, it's free, so they're doing you a damn >big favor. > >C// Scott Robinson -- http://mail.python.org/mailman/listinfo/python-list
Re: pyGoogle is fun and easy to use, and thinks Python is the best programming language
Regrettably, inserting "Visual Basic" into the list produces a different winner. I think you want some very subtle hard coding which limits it to on-space-delimited languages :-( - Andy -- http://mail.python.org/mailman/listinfo/python-list
Re: Tuple index
On 21 Feb 2005 15:01:05 -0800, "John Machin" <[EMAIL PROTECTED]> wrote: > >Steve M wrote: >> John Machin wrote: >> >> > >> > Steve M wrote: >> >> I'm actually doing this as part of an exercise from a book. What >the >> > program >> >> is supposed to do is be a word guessing game. The program >automaticly >> >> randomly selects a word from a tuple. >> > >> > Care to tell us which book is using a tuple for this, but hasn't >got to >> > lists yet? >> > >> > Cheers, >> > John >> >> Python Programming for the absoulte beginner by Michael Dawson > >In a review I found on the web: >http://www.skattabrain.com/css-books-plain/1592000738.html >"Dawson will take you by the hand and lead you down the garden path." > >Malapropism? Intentional humour? The book teaches you enough about programming and python to get you programming. It was the only python book in my local library so I read it while trying to learn the basics of python. It got me to the point where I could comfortably write Fortran-style python (I am not claiming that anyone else will leave the book that way, only that was as far as I had progressed in understanding python). I think that this book suggests using pickle/unpickle to send data over the internet. This is an amazingly bad idea, which is obvious once you understand how overloading works (I'm pretty sure overloading isn't covered in that book). In short, I think that this book is a good introduction to programming, and it will explain the basics of python, but it doesn't really begin to explain how to program in python. Scott Robinson -- http://mail.python.org/mailman/listinfo/python-list
Python COM API binding job offer
Hello, I have an API I have tried to create a python binding to. It involves creating com server functions which are then registered with the parent application. I am not a professional programmer nor do I have much win programming knowledge. As such what I am wanting to do is pay someone to download the parent application and API documentation then attempt to get to first base for me and provide a proof of concept. You would need to have good python, COM knowledge. I'm agnostic as to it being a win32com or a ctypes binding. The API is from a large multinational Company.And the API is not public so the person would have to sign an NDA. My understanding is the eventual license for the API will be open so my intention is to put the python binding (if it's working) out for public consumption if it can be made to work. If anyone is interested please contact me off list. [EMAIL PROTECTED] Regards, Guy Robinson -- http://mail.python.org/mailman/listinfo/python-list
creating .NET clients with python
Hello, Can anyone confirm if there is a python library that can allow me to create .NET clients in python. My understanding is both IronPython and python for .NET can't create python .net clients? Regards, Guy -- http://mail.python.org/mailman/listinfo/python-list
Re: creating .NET clients with python
Thanks Alan, Are you saying I can create python .net clients with PythonNet. My understanding is I can only use .net clients from python not the other way around. Do you have an example showing creating a .net client in python? regards, Guy yaipa wrote: Guy, I can tell you that pythonNet is quite far along, rel 1, Beta 4 actually. here is a c.l.p link to the three major releases. http://groups-beta.google.com/group/comp.lang.python/browse_frm/thread/ddfc68767901007c/445f2052948d93e2?q=pythonnet&_done=%2Fgroup%2Fcomp.lang.python%2Fsearch%3Fgroup%3Dcomp.lang.python%26q%3Dpythonnet%26qt_g%3D1%26searchnow%3DSearch+this+group%26&_doneTitle=Back+to+Search&&d#445f2052948d93e2 Cheers, --Alan Guy Robinson wrote: Hello, Can anyone confirm if there is a python library that can allow me to create .NET clients in python. My understanding is both IronPython and python for .NET can't create python .net clients? Regards, Guy -- http://mail.python.org/mailman/listinfo/python-list
ANN: ReportLab Toolkit - Release 1.20
At long last, I can annouce that Release 1.20 of the ReportLab Toolkit is out. The ReportLab Toolkit is a mature, full-featured library for generating PDF documents and data graphics. This release offers a number of minor formatting improvements ad new features, especially within tables. Full details are here: http://www.reportlab.org/relnotes.html Best Regards, Andy Robinson CEO/Chief Architect ReportLab Europe Ltd tel +44-20-8544-8049 -- http://mail.python.org/mailman/listinfo/python-list
UK Python Conference - 20-23 April 2005 - Call for papers
The UK Python Conference for 2005 will take place at the Randolph Hotel, Oxford on 20-23 April 2005. We hereby invite speakers to submit proposals for talks. About the event === This will once again be held as a track within the ACCU conference. The conference site is here, and more details on the Python track will appear shortly. http://www.accu.org/conference/ The ACCU event is one of the foremost conferences for programmers, attracting the inventors and/or leading proponents of C, C++, Java, .NET and Python over the last few years. Past Python speakers have included Guido van Rossum, David Ascher, Alex Martelli, Armin Rigo, Paul Everitt, Marc-Andre Lemburg and many others, and the ACCU now treats Python as being fully on par with Java and C++. The event is priced midway between commercial and community events, at approx. £100 per day, and is professionally managed. It is located in a historic hotel in the centre of Oxford and is ideal for anyone wanting to combine a holiday with a conference. Conference Format = The Python conference will span THREE days, with ONE track. The first slot each morning is taken by the cross-conference keynote. This was the overwhelming preference of those we polled last year. (There will NOT be a separate Open Source track this year; the "rotating special subject" is Security. As a result, Python-related security talks would be of interest) You may propose 90 minute or 45 minute talks. The ACCU's general preference is for a small number of high quality, well prepared talks on subjects of broad interest to programmers, and the Python track will follow this. There will also be space for less formal lunchtime talks, evening BOFs and other events. Speakers' compensation is yet to be confirmed, but in the past those doing 90 mimutes (or 2x45 minute talks) will be eligible for 4 days paid accomodation and admission to the 4 day event; 45 minute speakers will gain 1 day's admission. Where possible, we will attempt to allocate resources to ensure that the best speakers are able to attend irrespective of circumstances. Submission Procedure === Please send an email to [EMAIL PROTECTED] not later than 26th December, with the following information: Your Name Short Biography Talk Title Talk Synopsis This is a simple mailbox; the committee will review and acknowledge submissions a couple of times a week. If this shows promise, you will be given a chance to refine the details through a web based system later. Committee = A small committee will be formed to scrutinize talk proposals including those whol volunteered last year. This includes myself, Dr. Tim Couper and Dr. John Lee. General discussion about the event should be directed to the python-uk list ([EMAIL PROTECTED]) ReportLab Europe Ltd. is managing parts of the event infrastructure and will be providing some staff time to provide a guaranteed point of contact. --- Best Regards Andy Robinson CEO/Chief Architect ReportLab Europe Ltd tel +44-20-8544-8049 -- http://mail.python.org/mailman/listinfo/python-list
Re: GPL and Python modules.
On Mon, 25 Oct 2004 20:13:46 -0700, Robert Kern <[EMAIL PROTECTED]> wrote: >Tim Churches wrote: >> From: [EMAIL PROTECTED] >> >>>[mailto:[EMAIL PROTECTED] >>> On Behalf Of Robert Kern >>>Sent: Tuesday, 26 October 2004 11:34 AM >>>To: [EMAIL PROTECTED] >>>Subject: Re: GPL and Python modules. >>> >>> >>>Tim Churches wrote: >>> >>>>On Tue, 2004-10-26 at 11:12, Robert Kern wrote: >>> >>>>>Whether just using system calls is simply "normal use" for a GPLd OS >>>>>kernel or this is simply a special exception to the GPL for >>> >>>Linux only >>> >>>>>is something that a court will have to decide. But such a >>> >>>suit would >>> >>>>>have to be about some other GPL kernel, not Linux. >>>> >>>> >>>>Looks like it is a special exception for the Linux kernel >>> >>>(or whatever >>> >>>>other Linux code is distributed with this COPYING file. >>> >>>Doesn't apply >>> >>>>to other GPLed code. >>> >>>Well, not necessarily. It certainly isn't phrased as one. It >>>is at least >>>a statement of someone's (Linus's?) belief that standard applications >>>that only use system calls and running on Linux are not >>>derivative works >>>with respect to Linux. >> >> >> Yes, so it is a specific exemption to the GPL granted by the copyright >> holder(s) of the Linux kernel code. The GPL allows the copyright holder to >> grant exemptions to the GPL privisions as they see fit - but no-one else. > >It's still phrased as Linus's interpretation of what constitutes a >derivative work and what constitutes normal use of the GPLed kernel. >He's specifically saying that userland applications are not derivative >works not "even though they are derivative works, they are excepted from >the requirements of this license." > >>>Are Windows programs actual derivative >>>works of >>>the Windows kernel? Does the Windows EULA make a statement about the >>>derivative status of applications? >> >> >> No, and no. An important point of difference between the world views held >> by, say, Steve Ballmer and, say, Richard Stallman. > >The world views of Ballmer and Stallman are irrelevant to whether >something is a derivative or not. They may be relevant to whether one >may get sued or not, but that's a different issue. > >In any case, Stallman does not appear to believe that userland >applications are automatically derivative works of the kernel: > >http://www.fsf.org/licenses/gpl-faq.html#GPLInProprietarySystem > >"""If the two programs remain well separated, like the compiler and the >kernel, or like an editor and a shell, then you can treat them as two >separate programs--but you have to do it properly.""" I would be careful in taking legal advise from Richard Stallman. The GPL merely states that*: 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: After that, all notion of "derived work" falls on the appropriate copyright law of the country in question. I suspect that following Stallman's verdicts won't cause you to violate the GPL, but I would hardly be willing to be certain about going to court over a GPLed module imported into an unfree python program. Scott Robinson * note that I believe that this is fair use. According to the GPL, you can only distribute it unmodified. -- http://mail.python.org/mailman/listinfo/python-list
Re: Socket being garbage collected too early
On 16 Dec 2004 20:38:29 -0500, David Bolen <[EMAIL PROTECTED]> wrote: >Scott Robinson <[EMAIL PROTECTED]> writes: > >> I have been having trouble with the garbage collector and sockets. > >Are you actually getting errors or is this just theoretical? > >> Unfortunately, google keeps telling me that the problem is the garbage >> collector ignoring dead (closed?) sockets instead of removing live >> ones. My problem is >> >> >> x.sock=socket.socket(socket.AF_INET,socket.SOCK_STREAM) >> do_stuff(x.sock) >> >> >> def do_stuff(sock): >> sock_list.append(sock) >> >> once do_stuff finishes, x.sock disappears, and I can only believe it >> is being garbage collected. > >Can you clarify this? What do you mean by "x.sock" disappears? Are >you getting a NameError later when trying to use "x.sock"? > >x.sock is just a name binding, so it is not really involved in garbage >collection (GC applies to the objects to which names are bound). > >In this case, you need to include much more in the way of code (a >fully running, but smallest possible, snippet of code would be best), >since the above can be interpreted many ways. At the least, it's very >important to include information about the namespace within which >those two code snippets run if anyone is likely to be able to give you >a good answer. Also, being very precise about the error condition you >are experiencing (including actual error messages, tracebacks, etc...) >is crucial. > >Is 'x' referencing a local or global object, and does that socket code >occur within a method, a function, or what? Also, in do_stuff, where >is sock_list defined? Is it local, global? > >If, as written, sock_list is a local name to do_stuff, then that >binding is going to disappear when do_stuff completes, thus, the list >to which it is bound will be destroyed, including all references to >objects that the list may contain. So at that point, when you return >from do_stuff, the only reference to the socket object will be in >x.sock. But if 'x' is also local to the function/method where the >call to do_stuff is, the name binding will be removed when the >function/method returns, at which point there will be no references to >the socket object, and yes, it will be destroyed. > >But if sock_list is global, and continues to exist when do_stuff >completes, then the reference it contains to the socket will keep the >socket object alive even if you remove the x.sock binding. > >-- David (so much for Python being executable psuedocode). It looks like I was completely wrong. The problem I ran into was not checking into baseHTTPserver and looking for self.close_connection=1. I am pretty sure this happened to me before, and I rewrote the code to avoid sockets being closed after being referenced to a live object, but I can't reproduce it. Anyway, here is my debugged test rig. It works. Ignore it. Scott [test program follows] import socket, thread, time class sock_holder: pass HOST = '127.0.0.1' PORT = 2004 def echo_server(port): print "started at",port s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.bind((HOST, port)) s.listen(1) conn, addr = s.accept() print 'Connected by', addr while 1: data = conn.recv(1024) if not data: break conn.send(data) conn.close() def wait_and_speak(a): time.sleep(5) try: a.sock.send("this is message 2") except: print "error on message 2" try: data = a.sock.recv(1024) print data except: print "error recieving message 2" a.sock.close() def other_thread(a): s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) thread.start_new(echo_server,(PORT,)) time.sleep(1) s.connect((HOST,PORT )) s.send('Hello, port 1') data = s.recv(1024) print data a.sock=s thread.start_new(wait_and_speak,(a,)) a=sock_holder() thread.start_new(other_thread,(a,)) time.sleep(10) -- http://mail.python.org/mailman/listinfo/python-list
Re: BASIC vs Python
On Fri, 17 Dec 2004 15:00:54 -0600, Mike Meyer <[EMAIL PROTECTED]> wrote: >"not [quite] more i squared" <[EMAIL PROTECTED]> writes: > >> Adam DePrince wrote: >> Given the hardware constraints of the early 1980s, which language do you think should have been used instead of BASIC? >>> Lisp >>> Forth >> Exactly my pick > >Logo (my pick) has been called "Lisp without the parenthesis". It has >the advantage of using standard algebraic notation for formulas, >instead of operator post or pre. > >http://mail.python.org/mailman/listinfo/python-list
Socket being garbage collected too early
I have been having trouble with the garbage collector and sockets. Unfortunately, google keeps telling me that the problem is the garbage collector ignoring dead (closed?) sockets instead of removing live ones. My problem is x.sock=socket.socket(socket.AF_INET,socket.SOCK_STREAM) do_stuff(x.sock) def do_stuff(sock): sock_list.append(sock) once do_stuff finishes, x.sock disappears, and I can only believe it is being garbage collected. I'd like to hear the standard means for avoiding this issue (gc appears to have only the interface to declare something garbage, not to declare something not garbage). Scott Robinson -- http://mail.python.org/mailman/listinfo/python-list
Re: BASIC vs Python
On Fri, 17 Dec 2004 20:41:11 -0600, Mike Meyer <[EMAIL PROTECTED]> wrote: >Scott Robinson <[EMAIL PROTECTED]> writes: > >> Forth seems better than basic, but is *weird* (I tried it for a >> while). I'm not sure going from Forth to C (or Python) would be much >> easier than Basic to C or Python. The biggest disappointment for >> Forth was that no significant Forth chips were made (and none until it >> was too late). A machine designed to be run on Forth would have been >> unbelievably powerful from the late 70s to the mid 90s (it would be >> more painful now than the x86 legacy, but still). > >I think you overestimate how long the Forth chip would have been a >serious competitor to x`the x86 line. LISP chips - which should have >all the same advantages - didn't last that long. > >http://mail.python.org/mailman/listinfo/python-list
Re: BASIC vs Python
On Fri, 17 Dec 2004 20:41:11 -0600, Mike Meyer <[EMAIL PROTECTED]> wrote: >Scott Robinson <[EMAIL PROTECTED]> writes: > >> Forth seems better than basic, but is *weird* (I tried it for a >> while). I'm not sure going from Forth to C (or Python) would be much >> easier than Basic to C or Python. The biggest disappointment for >> Forth was that no significant Forth chips were made (and none until it >> was too late). A machine designed to be run on Forth would have been >> unbelievably powerful from the late 70s to the mid 90s (it would be >> more painful now than the x86 legacy, but still). > >I think you overestimate how long the Forth chip would have been a >serious competitor to x`the x86 line. LISP chips - which should have >all the same advantages - didn't last that long. > >http://mail.python.org/mailman/listinfo/python-list
Re: BASIC vs Python
On Mon, 20 Dec 2004 08:46:14 + (UTC), Alan Gauld <[EMAIL PROTECTED]> wrote: >> >>> was too late). A machine designed to be run on Forth would have been >> >>> unbelievably powerful from the late 70s to the mid 90s (it would be >> >>> more painful now than the x86 legacy, but still). > >A small data point here is that Sun still use Forth in their >Sparc workstations. Their system prompt is really a Forth >interpreter... I don;t know where the interpreter resides, >presumably not in Sparc since its a RISC but interesting that >they still use it. (Or they did last time I used a >Sparc - 4 years ago?) > >Alan G. >Author of the Learn to Program website >http://www.freenetpages.co.uk/hp/alan.gauld It was still there three years ago. While debugging some Sun based hardware I tried playing with it after it crashed. Forth was still there. It certainly is useful for a hardware independent bios, but I was making the point it would be good for general purpose. I suspect that it would quickly run up against memory limitations and would go no faster than the machine driving the memory market (with a possible last gasp when Rambus came online). Scott Robinson -- http://mail.python.org/mailman/listinfo/python-list
Re: What's the best GUI toolkit in Python,Tkinter,wxPython,QT,GTK?
On Mon, 28 Mar 2005 10:06:14 GMT, Dave Cook <[EMAIL PROTECTED]> wrote: >On 2005-03-27, Tom <[EMAIL PROTECTED]> wrote: > >> 1) Portable to Windows, Unix-like platforms, and the Macintosh; >> 2) Powerful, GUI is very beautiful ; >> 3) Efficiency of development is high; >> >> What's the best, Tkinter, wxPython, QT, GTK or other? > >Don't forget Swing and SWT via Jython. Of course that brings with it all >the joys and sorrows of Java. > >GTK on the Mac (OS X) requires installing and running an X server (an X >server is included on Apple's OS X install discs, but not installed by >default; it can also be downloaded for free from Apple). This may be enough >of an annoyance to turn some users off. I've had success with using GTK on >win32, and it's very standard on Linux systems. > >I'm not sure what the status of QT on OS X is. > >Tkinter still seems viable for things that don't require a lot of complex >controls. Also, it has a very powerful canvas widget. However, it won't >look very good on unix systems (no anti-aliasing, for one thing). > >If you don't need a lot of complex controls, you might consider the embedded >webserver + browser route using CherryPy or Twisted.web + Nevow. > >wxPython seems to have the best cross-platform support among CPython >toolkits, but it never seemed very Pythonic to me. There's a higher-level >package called wax that aims to remedy that. > >Dave Cook PythonCard builds on wxPython (a subset, I believe) and includes a graphic GUI builder. The way it handles the wxPython objects seems pretty pythonic to me, but I can't say I build pretty interface with it. PythonCard seems to like to stick to basics, but also includes a certain ability to get to the rest of wxPython (file/save/message dialogs are pretty easy to include). Note that my only other experience in building GUIs was with visual basic, which seems to have spoiled me. I tried wxPython and Tinker, but could only really get PythonCard to work. Scott Robinson -- http://mail.python.org/mailman/listinfo/python-list
Tutorial at Python-UK, Oxford, 19 May - handful of places left
Michele Simionato is giving a full day tutorial titled "The Wonders of Python" at the UK Python Conference, Randolph Hotel, Oxford on 19 May. (This replaces Alex Martelli, who is now working for Google in California). The program is here: https://www.accu.org/conference/python_tutorial.html This is a fantastic opportunity to boost your Python skills and catch up on the newer features of the language, for a fraction of the price of a professional training course. The course costs £135 for ACCU members and £160 for non-ACCU. There are still a few places left; anyone wishing to attend should directly contact the organisers, Archer Yates Associates, whose details are on the bottom left corner of the page. Best Regards Andy Robinson UK Python Conference program chair -- http://mail.python.org/mailman/listinfo/python-list
Python consulting opportunity
We'd like to find an experienced Python programmer for a full-time, three-month consulting contract to help us with our product, Goombah (http://www.goombah.com). Experience with wxPython and/or PyObjC would be a big plus. More importantly we're looking for someone who can get up to speed very quickly and who is used to working independently. A longer-term relationship is possible, but right now we're focused on adding a fixed set of features that we plan to add in the very near-term. It's a lot of work and we'll need help to get it done as quickly as we want. If this sounds like an opportunity you'd be interested in, or if you know of someone who might be a match, please let us know. Thanks, Gary -- Gary Robinson CTO Emergent Music, LLC [EMAIL PROTECTED] 207-942-3463 Company: http://www.goombah.com Blog:http://www.garyrobinson.net -- http://mail.python.org/mailman/listinfo/python-list
Re: OOP
On Thu, 28 Apr 2005 17:58:47 GMT, Charles Krug <[EMAIL PROTECTED]> wrote: >On 28 Apr 2005 10:34:44 -0700, [EMAIL PROTECTED] ><[EMAIL PROTECTED]> wrote: >> Hey yall, >> I'm new to Python and I love it. Now I can get most of the topics >> covered with the Python tutorials I've read but the one thats just >> stumping me is Object Orientation. I can't get the grasp of it. Does >> anyone know of a good resource that could possibly put things in focus >> for me? Thanks. >> > >"Learning Python" (Lutz/Ascher) has a good discussion of the basics. > >Unfortunately, most of the OOP writings I've read fall into two >catagories: Trivial examples where you say, "But why Bother??" and >examples that you don't understand until you've some OO design under >your belt and can understand what it's all good for. > >Objects are, at the end of the day, data and the accompanying methods. >Once you've read the various tutorials take a stab at converting a >problem you know well into objects. > >You'll get it wrong at first. Most everyone does. Don't sweat it. >Eventually, you'll just "get" it. [Note: this is just the start of an explanation. If you don't understand OOP, just try programming that way (yes, I got it wrong to see my usage of "Wally objects"). This is something I thought of awhile ago, and wondered where I could use it. My background is a hardware guy who first learned spaghetti coding in basic on 8-bits, received the wisdom of modular programming when learning assembler, then much later tried his hand teaching himself python. Those from other backgrounds may be amused at my naivete.] I've been trying to figure out the "Dilbert" view of OOP. My first objects were like C types: class Super_object: pass Consider this the Wally object. Wally=Super_object(): Things get put on his desk: Wally.MeetingActionItems=[1,2,3] And stay there. At first, this seems great. It gives you plenty of desks to store data on. After a while, you might paint yourself into a corner (such as wanting to append to lists, but later wish to hard limit the number of entries, thus needing to change from a list to an overloaded object). This brings the Dilbert object. You can put things on Dilbert's desk, but unlike Wally, he can actually notice the objects, manage them, and do some work on it. Class Dilbert_object: __init__(self): ActionItems=[] def AddItems(self,items): self.ActionItems.append(items) def DoAction(self): return self.ActionItems.pop() Ok, I admit that this just looks like yet another getter and setter. Maybe this is an Asok object and Dilbert would realize that the Boss doesn't remember everything on his desk, so we change it to: Class Dilbert_object: __init__(self): ActionItems=[] def AddItems(self,items): self.ActionItems.append(items) if len(self.ActionItems)>10: self.ActionItems.pop(0) def DoAction(self): return self.ActionItems.pop() Since OOP dogmatists insist that inheritance is vital to OOP, we include the Alice object. Alice can do everything Dilbert can do, and then some. To include Dilbert's skills we simply include Class Alice_object(Dilbert_object): To add new things to the Alice object: Class Alice_object(Dilbert_object): def FistOfDeath(self): import os os._exit(0) The critical thing is that you can now let Dilbert manage your data. That's one of the main reasons for inventing computers anyway, to manage data. So write subprograms (objects) that do your work for you, and work as thanklessly as Dilbert, and then try to concentrate on debugging the big picture. Scott -- http://mail.python.org/mailman/listinfo/python-list
install issue
When I run the installer (python-3.5.0.exe [win32]) I see this: There seems to be "hidden" buttons as clicking in the middle of this dialog box does continue the process. However, when complete, and I start python, I get an error saying its not a valid win32 application. So, I uninstalled, and there is the same issue with the un-installer - I have to click random places in the dialog box to "find" the uninstall button, that is not shown. (plus AVG shows this as the Heri virus - and, yes, I did disable AVG while attempting the installation.) Win xp, SP3, AMD Phenom, 1100, 8gb (dual boot with win7) Rgds -- https://mail.python.org/mailman/listinfo/python-list