Re: [Tutor] Wondering about a project
Well I've made some progress in terminal mode. The OS is Ubuntu 12.04 LXDE desktop This script works. It prompts for the url, lets the user confirm download and then runs the video in Gnome-Player. Once Gnome-Player is dropped by the user, it prompts to either move the file to storage or delete. Then returns for another round. --- #!/usr/bin/python from subprocess import call import glob,re,shutil,os,time geturl="" while True: call(["clear"]) geturl= input("Enter Youtube URL ") if len(geturl)==0: break def unquote(geturl): return re.compile('%([0-9a-fA-F]{2})',re.M).sub(lambda m: chr(int(m.group(1),16)), geturl) print("Download %s?" %geturl) answer= raw_input("Press ENTER to continue: ") call(["youtube-dl", geturl]) #get the youtube video file names YTfile=glob.glob('./*.mp4') print("%s Youtube files: "%(YTfile)) #clean up the file names for x in range(len(YTfile)): YTfile[x] = YTfile[x][2:] print("%s: "+str(x)+" "+YTfile[x]+'\n') #now play the youtube video #for x in range(len(YTfile)): call(["gnome-mplayer", YTfile[0]]) #Decide to save the file or delete it dofile = raw_input('Save or Delete: S or D ') if dofile=='S': #save the file by moving it into folder for x in range(len(YTfile)): shutil.move(YTfile[x],'/home/user/Documents/YOUTUBEFILES') #delete the file else: os.remove(YTfile[0]) print("Deleted %s "%YTfile[0]) time.sleep( 3 ) -- bw...@fastmail.net ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Wondering about a project
On 02/02/15 18:42, dw wrote: geturl="" You don't really need this since you assign it inside the loop. while True: call(["clear"]) geturl= input("Enter Youtube URL ") if len(geturl)==0: break def unquote(geturl): return re.compile('%([0-9a-fA-F]{2})',re.M).sub(lambda m: chr(int(m.group(1),16)), geturl) Its not a good idea to define a functin inside a loop. Everytime the loop is executed you redefine the function all over again, which is a waste. Keep the function definitions out of your main code. print("Download %s?" %geturl) answer= raw_input("Press ENTER to continue: ") If you are using Python2.7 then you should also use raw_input above to get the url. call(["youtube-dl", geturl]) #get the youtube video file names YTfile=glob.glob('./*.mp4') print("%s Youtube files: "%(YTfile)) #clean up the file names for x in range(len(YTfile)): YTfile[x] = YTfile[x][2:] print("%s: "+str(x)+" "+YTfile[x]+'\n') this would be prettier using enumerate: for x, file in enumerate(YTFile): YTFile[x] = file[2:] print("%s:%d" % (file, x)) #now play the youtube video #for x in range(len(YTfile)): Again this would be prettier using normal python style for file in YTFile: call(["gnome-mplayer", YTfile[0]]) #Decide to save the file or delete it dofile = raw_input('Save or Delete: S or D ') if dofile=='S': You will get annoyed always having to press shift key to get caps. You should check for one case after forcing conversion: if dofile.upper() == 'S': Although after writing a GUI that will be less of an issue because you'll be using a dialog to get the choice. #save the file by moving it into folder for x in range(len(YTfile)): shutil.move(YTfile[x],'/home/user/Documents/YOUTUBEFILES') Again, don't use indexing, Let python do the work, its more reliable. for file in YTFile: shutil.move(file, 'your/path') #delete the file else: os.remove(YTfile[0]) print("Deleted %s "%YTfile[0]) time.sleep( 3 ) Note that this else will delete the file even if the user presses 's' instead of 'S' unless you do the upper conversion I show above. It will also delete the file if the user happens to hit return before 's'... I'd recommend an explicit test for 'D' here. But again, not an issue in a GUI version. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Wondering about a project
On 02/03/2015 07:12 AM, Alan Gauld wrote: On 02/02/15 18:42, dw wrote: You forgot to tell us the Python version you're targeting. From various clues in your code, I have to assume you're using 2.7, but if I'm wrong, there are other comments I should have made. geturl="" You don't really need this since you assign it inside the loop. while True: call(["clear"]) geturl= input("Enter Youtube URL ") Need to use raw_input() for version 2.7. As it stands, you're requiring the user to enter quotes around his response, and taking the risk that if he doesn't, or if they're unmatched, he might be doing some unexpected things. if len(geturl)==0: break def unquote(geturl): return re.compile('%([0-9a-fA-F]{2})',re.M).sub(lambda m: chr(int(m.group(1),16)), geturl) Its not a good idea to define a functin inside a loop. Everytime the loop is executed you redefine the function all over again, which is a waste. Keep the function definitions out of your main code. print("Download %s?" %geturl) answer= raw_input("Press ENTER to continue: ") If you are using Python2.7 then you should also use raw_input above to get the url. call(["youtube-dl", geturl]) #get the youtube video file names YTfile=glob.glob('./*.mp4') print("%s Youtube files: "%(YTfile)) You need to decide here whether there might be more than one file to play and/or delete. If your design says there's just one file, then you should ensure that, perhaps by deleting the others before the loop below, or by printing an error message. I'll assume you're designing for the possibility of multiple files on that Youtube page. I don't know youtube-dl well enough to know if that's possible. #clean up the file names for x in range(len(YTfile)): YTfile[x] = YTfile[x][2:] print("%s: "+str(x)+" "+YTfile[x]+'\n') this would be prettier using enumerate: for x, file in enumerate(YTFile): YTFile[x] = file[2:] print("%s:%d" % (file, x)) #now play the youtube video That's now "videos", plural. #for x in range(len(YTfile)): Again this would be prettier using normal python style for file in YTFile: for myfile in YTFile: call(["gnome-mplayer", myfile) Besides which, if you had uncommented the range thing, you'd need to change the [0] below to [x]. Otherwise you'd be playing the first file multiple times. call(["gnome-mplayer", YTfile[0]]) #Decide to save the file or delete it dofile = raw_input('Save or Delete: S or D ') if dofile=='S': Here again, your design has to decide whether it'll be all or nothing. I'll assume you'll be either saving them all, or deleting them all. You will get annoyed always having to press shift key to get caps. You should check for one case after forcing conversion: if dofile.upper() == 'S': Although after writing a GUI that will be less of an issue because you'll be using a dialog to get the choice. #save the file by moving it into folder save the files by moving them into folder for x in range(len(YTfile)): shutil.move(YTfile[x],'/home/user/Documents/YOUTUBEFILES') Again, don't use indexing, Let python do the work, its more reliable. for file in YTFile: shutil.move(file, 'your/path') #delete the file else: os.remove(YTfile[0]) print("Deleted %s "%YTfile[0]) time.sleep( 3 ) You're only deleting the first one. Need a loop here as well. Note that this else will delete the file even if the user presses 's' instead of 'S' unless you do the upper conversion I show above. It will also delete the file if the user happens to hit return before 's'... I'd recommend an explicit test for 'D' here. But again, not an issue in a GUI version. -- DaveA ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
[Tutor] Macintosh Help with Python
Can you help me through a phone number or chat on working with Python? -- Mark Warren Humboldt Unified School District # 258 801 New York Street Humboldt, Kansas 66748 Phone -- (620) 704-1527 ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Macintosh Help with Python
On 03/02/15 15:22, Mark Warren wrote: Can you help me through a phone number or chat on working with Python? Sorry Mark, this is a mailing list. We can answer questions posted by email. If you tell us what it is you want to do somebody can describe the process for you. There are also a ton of videos on YouTube on using Python on different platforms. Here is one for MacOSX: https://www.youtube.com/watch?feature=player_detailpage&v=BE1wDsLzOJA But there are many others. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
[Tutor] Why is an instance smaller than the sum of its components?
Hello, I was writing something and thought: Since the class had some 'constants', and multiple instances would be created, I assume that each instance would have its own data. So this would mean duplication of the same constants? If so, I thought why not put the constants in memory once, for every instance to access (to reduce memory usage). Correct me if I'm wrong in my assumptions (i.e: If instances share stuff). So I investigated further.. >>> import sys >>> sys.getsizeof(5) 12 So an integer on my machine is 12 bytes. Now: >>> class foo(object): ... def __init__(self): ... pass >>> sys.getsizeof(foo) 448 >>> sys.getsizeof(foo()) 28 >>> foo >>> foo() <__main__.foo object at 0xXXX - Second weird thing: >>> class bar(object): ... def __init__(self): ... self.w = 5 ... self.x = 6 ... self.y = 7 ... self.z = 8 >>> sys.getsizeof(bar) 448 >>> sys.getsizeof(foo) 448 >>> sys.getsizeof(bar()) 28 >>> sys.getsizeof(foo()) 28 >>> sys.getsizeof(bar().x) 12 >>> sys.getsizeof(bar().y) 12 Summary questions: 1 - Why are foo's and bar's class sizes the same? (foo's just a nop) 2 - Why are foo() and bar() the same size, even with bar()'s 4 integers? 3 - Why's bar()'s size smaller than the sum of the sizes of 4 integers? Thanks.. -- ~Jugurtha Hadjar, ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Why is an instance smaller than the sum of its components?
class bar(object): > ... def __init__(self): > ... self.w = 5 > ... self.x = 6 > ... self.y = 7 > ... self.z = 8 > sys.getsizeof(bar()) > 28 > 3 - Why's bar()'s size smaller than the sum of the sizes of 4 integers? But what is the documented behavior of sys.getsizeof? Reading... https://docs.python.org/3/library/sys.html#sys.getsizeof Ah. The following phrase in the documentation seems to apply directly to your question: "Only the memory consumption directly attributed to the object is accounted for, not the memory consumption of objects it refers to." But the docs there also have a link to a recursive getsizeof() recipe that does what I think you intend. Take a look at that recipe. Good luck! ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Why is an instance smaller than the sum of its components?
On 2/3/2015 1:12 PM, Jugurtha Hadjar wrote: Hello, I was writing something and thought: Since the class had some 'constants', and multiple instances would be created, I assume that each instance would have its own data. So this would mean duplication of the same constants? If so, I thought why not put the constants in memory once, for every instance to access (to reduce memory usage). Correct me if I'm wrong in my assumptions (i.e: If instances share stuff). So I investigated further.. >>> import sys >>> sys.getsizeof(5) 12 So an integer on my machine is 12 bytes. Now: >>> class foo(object): ...def __init__(self): ...pass >>> sys.getsizeof(foo) 448 >>> sys.getsizeof(foo()) 28 >>> foo >>> foo() <__main__.foo object at 0xXXX - Second weird thing: >>> class bar(object): ...def __init__(self): ...self.w = 5 ...self.x = 6 ...self.y = 7 ...self.z = 8 >>> sys.getsizeof(bar) 448 >>> sys.getsizeof(foo) 448 >>> sys.getsizeof(bar()) 28 >>> sys.getsizeof(foo()) 28 >>> sys.getsizeof(bar().x) 12 >>> sys.getsizeof(bar().y) 12 Summary questions: 1 - Why are foo's and bar's class sizes the same? (foo's just a nop) i'm not sure on this one. 2 - Why are foo() and bar() the same size, even with bar()'s 4 integers? neither foo() nor bar() return anything explicitly, so both return the default none 3 - Why's bar()'s size smaller than the sum of the sizes of 4 integers? same as above. ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Why is an instance smaller than the sum of its components?
>> >> Summary questions: >> >> 1 - Why are foo's and bar's class sizes the same? (foo's just a nop) > > > i'm not sure on this one. > >> 2 - Why are foo() and bar() the same size, even with bar()'s 4 integers? > > > neither foo() nor bar() return anything explicitly, so both return the > default none This needs correction. I think you're thinking of regular functions. But 'foo' and 'bar' are the names of the classes, so this is instance construction. To demonstrate the difference: # >>> class foo(object): pass ... >>> foo() <__main__.foo object at 0x7f27655c0fd0> # Compare what we see here to: ## >>> def bar(): pass ... >>> bar() >>> ## where the interactive evaluator is suppressing output of the None value. ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Why is an instance smaller than the sum of its components?
On Tue, Feb 3, 2015 at 3:59 PM, Emile van Sebille wrote: > On 2/3/2015 1:12 PM, Jugurtha Hadjar wrote: >> 2 - Why are foo() and bar() the same size, even with bar()'s 4 integers? > > neither foo() nor bar() return anything explicitly, so both return the > default none This is not correct, foo() and bar() return a foo instance and a bar instance, respectively; not None. For the OP: while this will probably be a nice exercise for learning more about Python's internals, please keep in mind that 9 times out of 10 you won't need to worry about memory usage in Python, especially not before you've proven to yourself that your program is using more memory than is acceptable. -- Zach ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Why is an instance smaller than the sum of its components?
Jugurtha Hadjar wrote: > Hello, > > I was writing something and thought: Since the class had some > 'constants', and multiple instances would be created, I assume that each > instance would have its own data. So this would mean duplication of the > same constants? If so, I thought why not put the constants in memory > once, for every instance to access (to reduce memory usage). CPython already does this for many common values, e. g. small integers and variable names >>> a = 42 >>> b = 42 >>> a is b True >>> a = 300 >>> b = 300 >>> a is b False It also performs constant folding over a single compilation: >>> a = 300; b = 300; a is b True > Correct me if I'm wrong in my assumptions (i.e: If instances share stuff). > > So I investigated further.. > > >>> import sys > >>> sys.getsizeof(5) > 12 > > > So an integer on my machine is 12 bytes. > > Now: > > >>> class foo(object): > ... def __init__(self): > ... pass > > >>> sys.getsizeof(foo) > 448 > > >>> sys.getsizeof(foo()) > 28 > > >>> foo > > >>> foo() > <__main__.foo object at 0xXXX To know its class the foo instance only needs a reference to the class object, not a complete copy of the class. This is typically provided by putting a pointer into the instance, and this consumes only 8 bytes on 64- bit systems. > - Second weird thing: > > >>> class bar(object): > ... def __init__(self): > ... self.w = 5 > ... self.x = 6 > ... self.y = 7 > ... self.z = 8 > > >>> sys.getsizeof(bar) > 448 > >>> sys.getsizeof(foo) > 448 > >>> sys.getsizeof(bar()) > 28 > >>> sys.getsizeof(foo()) > 28 > > >>> sys.getsizeof(bar().x) > 12 > >>> sys.getsizeof(bar().y) > 12 The instances of most user-defined classes use a dict to hold references to the attributes, and only the memory consumed by the pointer to that dict is reported. If all referenced values were included, what would you expect to be the size of `a` below >>> class A: pass ... >>> a = A() >>> a.a = a >>> sys.getsizeof(a) 56 > Summary questions: > > 1 - Why are foo's and bar's class sizes the same? (foo's just a nop) Assigning attributes in the initializer only affects the instance; Python doesn't scan the code to reserve slots for these attributes. When the instance is created the initialiser is executed and every self.x = value basically results in self.__dict__["x"] = value > 2 - Why are foo() and bar() the same size, even with bar()'s 4 integers? To get a more realistic idea of the objects' size you can include the size of __dict__. That grows in bursts: >>> class A: pass ... >>> a = A() >>> old_size = sys.getsizeof(a.__dict__) >>> for i in range(1000): ... setattr(a, "x" + str(i), i) ... new_size = sys.getsizeof(a.__dict__) ... if new_size != old_size: ... print(i, "a.__dict__ grows from", old_size, "to", new_size) ... old_size = new_size ... 3 a.__dict__ grows from 96 to 192 11 a.__dict__ grows from 192 to 320 21 a.__dict__ grows from 320 to 576 43 a.__dict__ grows from 576 to 1088 85 a.__dict__ grows from 1088 to 2112 171 a.__dict__ grows from 2112 to 4160 341 a.__dict__ grows from 4160 to 8256 683 a.__dict__ grows from 8256 to 16448 > 3 - Why's bar()'s size smaller than the sum of the sizes of 4 integers? >From the above follows that this is not a meaningful question for a standard user-defined class. They all use __dict__ to store the interesting stuff. But there is a way to reserve space for attributes in the instance: >>> class A: ... __slots__ = () ... >>> class B: ... __slots__ = ("a",) ... >>> class C: ... __slots__ = ("a", "b") ... >>> class D: ... __slots__ = tuple("a" + str(i) for i in range(100)) ... >>> for K in A, B, C, D: ... print(K.__name__, sys.getsizeof(K())) ... A 16 B 48 C 56 D 840 >>> b = B() >>> sys.getsizeof(b) 48 >>> b.a = 42 >>> sys.getsizeof(b) 48 >>> (840-48)/99 8.0 And that looks very much like one 64-bit pointer per attribute. ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Why is an instance smaller than the sum of its components?
On 02/03/2015 10:57 PM, Danny Yoo wrote: But what is the documented behavior of sys.getsizeof? Reading... https://docs.python.org/3/library/sys.html#sys.getsizeof Ah ! I was reading this: https://docs.python.org/2/library/sys.html#sys.getsizeof The unlocking phrase: "Only the memory consumption directly attributed to the object is accounted for, not the memory consumption of objects it refers to." seems to be present in the Python 3 doc, but not in Python 2's. I'll make sure to include the version in my future questions. But the docs there also have a link to a recursive getsizeof() recipe that does what I think you intend. Take a look at that recipe. Good luck! Yeap, I see that. Thanks for your time! -- ~Jugurtha Hadjar, ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Why is an instance smaller than the sum of its components?
On 02/03/2015 11:28 PM, Zachary Ware wrote: For the OP: while this will probably be a nice exercise for learning more about Python's internals, please keep in mind that 9 times out of 10 you won't need to worry about memory usage in Python, especially not before you've proven to yourself that your program is using more memory than is acceptable. Thanks for the pointer, I was scratching the itch on my way to do something else... But this stuff is fascinating and hard to resist! -- ~Jugurtha Hadjar, ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Why is an instance smaller than the sum of its components?
On Tue, Feb 03, 2015 at 10:12:09PM +0100, Jugurtha Hadjar wrote: > Hello, > > I was writing something and thought: Since the class had some > 'constants', and multiple instances would be created, I assume that each > instance would have its own data. So this would mean duplication of the > same constants? Not necessarily. Consider: class A(object): spam = 23 def __init__(self): self.eggs = 42 In this case, the "spam" attribute is on the class, not the instance, and so it doesn't matter how many A instances you have, there is only one reference to 23 and a single copy of 23. The "eggs" attribute is on the instance. That means that each instance has its own separate reference to 42. Does that mean a separate copy of 42? Maybe, maybe not. In general, yes: if eggs was a mutable object like a list, or a dict, say: self.eggs = [] then naturally it would need to be a separate list for each instance. (If you wanted a single list shared between all instances, put it on the class.) But with immutable objects like ints, strings and floats, there is an optimization available to the Python compiler: it could reuse the same object. There would be a separate reference to that object per instance, but only one copy of the object itself. Think of references as being rather like C pointers. References are cheap, while objects themselves could be arbitrarily large. With current versions of Python, the compiler will intern and re-use small integers and strings which look like identifiers ("alpha" is an identifier, "hello world!" is not). But that is subject to change: it is not a language promise, it is an implementation optimization. However, starting with (I think) Python 3.4 or 3.5, Python will optimize even more! Instances will share dictionaries, which will save even more memory. Each instance has a dict, which points to a hash table of (key, value) records: __dict__ > [ UNUSED UNUSED (ptr to key, ptr to value) UNUSED ... ] __dict__ > [ UNUSED UNUSED (ptr to key, ptr to value) UNUSED ... ] For most classes, the instances a and b will have the same set of keys, even though the values will be different. That means the pointers to keys are all the same. So the new implementation of dict will optimize that case to save memory and speed up dictionary access. > If so, I thought why not put the constants in memory > once, for every instance to access (to reduce memory usage). > > Correct me if I'm wrong in my assumptions (i.e: If instances share stuff). In general, Python will share stuff if it can, although maybe not *everything* it can. > So I investigated further.. > > >>> import sys > >>> sys.getsizeof(5) > 12 > > > So an integer on my machine is 12 bytes. A *small* integer is 12 bytes. A large integer can be more: py> sys.getsizeof(2**100) 26 py> sys.getsizeof(2**1) 1346 py> sys.getsizeof(2**1000) 146 > Now: > > >>> class foo(object): > ... def __init__(self): > ... pass > > >>> sys.getsizeof(foo) > 448 > > >>> sys.getsizeof(foo()) > 28 > > >>> foo > > >>> foo() > <__main__.foo object at 0xXXX The *class* Foo is a fairly large object. It has space for a name, a dictionary of methods and attributes, a tuple of base classes, a table of weak references, a docstring, and more: py> class Foo(object): ... pass ... py> dir(Foo) ['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__qualname__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__'] py> vars(Foo) mappingproxy({'__qualname__': 'Foo', '__module__': '__main__', '__doc__': None, '__weakref__': , '__dict__': }) py> Foo.__base__ py> Foo.__bases__ (,) The instance may be quite small, but of course that depends on how many attributes it has. Typically, all the methods live in the class, and are shared, while data attributes are per-instance. > - Second weird thing: > > >>> class bar(object): > ... def __init__(self): > ... self.w = 5 > ... self.x = 6 > ... self.y = 7 > ... self.z = 8 > > >>> sys.getsizeof(bar) > 448 > >>> sys.getsizeof(foo) > 448 Nothing weird here. Both your Foo and Bar classes contain the same attributes. The only difference is that Foo.__init__ method does nothing, while Bar.__init__ has some code in it. If you call sys.getsizeof(foo.__init__.__code__) and compare it to the same for bar, you should see a difference. > >>> sys.getsizeof(bar()) > 28 > >>> sys.getsizeof(foo()) > 28 In this case, the Foo and Bar instances both have the same size. They both have a __dict__, and the Foo instance's __dict__ is empty, while the Bar instance's __dict__ has 4 items. Print: print(foo().__dict__) print(bar().__dict__) to see the difference. But w
Re: [Tutor] Why is an instance smaller than the sum of its components?
On 02/03/2015 04:12 PM, Jugurtha Hadjar wrote: Hello, Lots of other good comments, so I'll just remark on one point. >>> class bar(object): ...def __init__(self): ...self.w = 5 ...self.x = 6 ...self.y = 7 ...self.z = 8 If these really are "constants," meaning the same value for all instances, then you can make them class attributes instead of instance attributes. I'd advise doing this to avoid bugs, not to save memory, though if you have lots of instances, it'll certainly save memory. >>> class bar(object): ...w = 5 ...x = 6 ...def __init__(self): ...self.y = 7 ...self.z = 8 At this point, all instances will have a self.w of 5, and a self.x of 6. But they'll each have a self.y and self.z which could change independently. -- DaveA ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Wondering about a project
Thanks Alan for the tips!!! I greatly appreciate. :-D Duane -- bw...@fastmail.net ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Wondering about a project
Thanks Dave A for your Tips!! I greatly appreciate. :-D Duane -- bw...@fastmail.net ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
[Tutor] How can I replicate a list in a for loop
This is my sample piece of code (not full code of my original code just sample of it) I am using python 2.7 Import itertools var=[1,2,3,4,5] Length=int(raw_input("length of possible numbers required")) #This is for length of 3 chars for i in itertools.product(var,var,var): print i[0]+i[1]+i[2] Here what is my problem is i am unable to replicate the list based on the user input i tried var*length but it is creating a new single list with repeated values , how can i solve this problem?? I want the same original list to be used Thanks in advance ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Why is an instance smaller than the sum of its components?
On 02/03/2015 11:40 PM, Peter Otten wrote: CPython already does this for many common values, e. g. small integers and variable names a = 42 b = 42 a is b True a = 300 b = 300 a is b False The threshold seems to be 256 (last value where it evaluates to True): >>> a = 1 >>> b = 1 >>> same = True >>> while same: ... a += 1 ... b += 1 ... same = a is b ... >>> a 257 >>> b 257 Interesting that it does that, and interesting that it doesn't work for floats. To know its class the foo instance only needs a reference to the class object, not a complete copy of the class. This is typically provided by putting a pointer into the instance, and this consumes only 8 bytes on 64- bit systems. Okay, I thought the way it was done was that each instance was a full, independent, citizen/entity; with everything copied as many times as there are instances, which somehow bothered me memory wise, but had an appeal of having them completely separated. ... Rest of the post is partially grasped and requires further reading to fully appreciate. Thank you very much for taking the time and for the example code. -- ~Jugurtha Hadjar, ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] How can I replicate a list in a for loop
On 03/02/2015 22:51, Suresh Nagulavancha wrote: This is my sample piece of code (not full code of my original code just sample of it) I am using python 2.7 Import itertools var=[1,2,3,4,5] Length=int(raw_input("length of possible numbers required")) #This is for length of 3 chars for i in itertools.product(var,var,var): print i[0]+i[1]+i[2] Here what is my problem is i am unable to replicate the list based on the user input i tried var*length but it is creating a new single list with repeated values , how can i solve this problem?? I want the same original list to be used Thanks in advance If you are trying to get the first n items from the list all you need is the slice notation:- chunk = var[:Length] If not can you please rephrase your question as it makes no sense to me. -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Why is an instance smaller than the sum of its components?
On 02/04/2015 12:18 AM, Steven D'Aprano wrote: Not necessarily. Consider: class A(object): spam = 23 def __init__(self): self.eggs = 42 In this case, the "spam" attribute is on the class, not the instance, and so it doesn't matter how many A instances you have, there is only one reference to 23 and a single copy of 23. The "eggs" attribute is on the instance. That means that each instance has its own separate reference to 42. Hmm.. Here are the first few lines of my class: class Sender(object): """ Redacted """ SENDER_DB = 'sender.db' def __init__(self, phone, balance=0.0): self.phone = phone self.balance = balance I gave the (bad) examples that way because I thought what mattered is how much data was inside. I put SENDER_DB there because it made sense to put constants way on top, not because I had any idea it'd make the difference you mentioned (class attributes vs instance attributes). And also because it's a common piece of data to all the methods...(because after I started with each method opening and closing the database, I eliminated the code and made a method that returns a connection and a cursor, and the others just call it when they need to do stuff on the database. I'll ask another question later on how to refine it) But now that you, Dave, and Peter pointed this out, I'm thinking of putting the methods' constants up there (mainly patterns for regular expressions, and queries (SQL)). Does that mean a separate copy of 42? Maybe, maybe not. In general, yes: if eggs was a mutable object like a list, or a dict, say: self.eggs = [] then naturally it would need to be a separate list for each instance. (If you wanted a single list shared between all instances, put it on the class.) But with immutable objects like ints, strings and floats, there is an optimization available to the Python compiler: it could reuse the same object. There would be a separate reference to that object per instance, but only one copy of the object itself. Okay.. I think that even if Python does optimize that, this belongs to the "good practice" category, so it's better that I'm the one who does it instead of relying on what the compiler might do. I'm a beginner(that's the first thing I write that does something useful) and would like to reinforce good habits. Think of references as being rather like C pointers. References are cheap, while objects themselves could be arbitrarily large. That's the analogy I made, but I'm careful with those. I don't want to end up like the "English As She Is Spoke" book.. With current versions of Python, the compiler will intern and re-use small integers and strings which look like identifiers ("alpha" is an identifier, "hello world!" is not). ... In general, Python will share stuff if it can, although maybe not *everything* it can. That's interesting. I'll try to read up on this without being sidetracked. In this case, the Foo and Bar instances both have the same size. They both have a __dict__, and the Foo instance's __dict__ is empty, while the Bar instance's __dict__ has 4 items. Print: print(foo().__dict__) print(bar().__dict__) to see the difference. But with only 4 items, Bar's items will fit in the default sized hash table. No resize will be triggered and the sizes are the same. I thought that there was a default size allocated even for an "empty" class (which is correct), and then if I added w, x, y, z, their size would be *added* to the default size (which is incorrect).. Somehow, I didn't think of the analogy of 8dec being (1000b) (4 bits) and incrementing, it's still 4 bits through 15dec (b). So that's: default class size + data = default class size until it "overflows". (or until 50% of default class size is reached as you mentioned later). Run this little snippet of code to see what happens: d = {} for c in "abcdefghijklm": print(len(d), sys.getsizeof(d)) d[c] = None For memo: (0, 136) (1, 136) (2, 136) (3, 136) (4, 136) (5, 136) (6, 520) (7, 520) (8, 520) (9, 520) (10, 520) (11, 520) (12, 520) Summary questions: 1 - Why are foo's and bar's class sizes the same? (foo's just a nop) Foo is a class, it certainly isn't a NOP. Just because you haven't given it state or behaviour doesn't mean it doesn't have any. It has the default state and behaviour that all classes start off with. 2 - Why are foo() and bar() the same size, even with bar()'s 4 integers? Because hash tables (dicts) contain empty slots. Once the hash table reaches 50% full, a resize is triggered. 3 - Why's bar()'s size smaller than the sum of the sizes of 4 integers? Because sys.getsizeof tells you the size of the object, not the objects referred to by the object. Here is a recipe for a recursive getsizeof: http://code.activestate.com/recipes/577504 This is cool. Thanks a lot (and Dave, too) for the gr
Re: [Tutor] Why is an instance smaller than the sum of its components?
Sorry for the full lines. They were wrapped here but were sent unfolded. It seems I need to "rewrap" on Thunderbird. -- ~Jugurtha Hadjar, ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor