[Tutor] why can use a widget assigned to a variable or just use it on it's own?
Hi, I'm trying to understand working with objects. If I have grasped things correctly a widget is an object. So why can I assign the widget, or use it stand alone? See sample code below = #!/usr/bin/python3 from tkinter import * main=Tk() # as I understand it this will create an instance of the button widget called b1 b1=Button(main, text='instantce', command= lambda b='goodbye' : print(b)).grid(row=1, column=0) # but here I haven't made an instance, but all seems well Button(main, text='test1', command=lambda a='hello' :print(a)).grid(row=0, column=0) main.mainloop() === any explanation gratefully recieved Regards, Chris ROy-Smith ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] why can use a widget assigned to a variable or just use it on it's own?
Op 02-07-18 om 03:54 schreef Chris Roy-Smith: Hi, I'm trying to understand working with objects. If I have grasped things correctly a widget is an object. So why can I assign the widget, or use it stand alone? See sample code below = #!/usr/bin/python3 from tkinter import * main=Tk() # as I understand it this will create an instance of the button widget called b1 b1=Button(main, text='instantce', command= lambda b='goodbye' : print(b)).grid(row=1, column=0) # but here I haven't made an instance, but all seems well Button(main, text='test1', command=lambda a='hello' :print(a)).grid(row=0, column=0) You still create an instance, but don't assign it to a variable. See following example: class Foo: def __init__(self): print("Instance created") f = Foo() # prints "Instance created" Foo() # print "Instance created" Two instances are created, just that the second one isn't accessible. Timo main.mainloop() === any explanation gratefully recieved Regards, Chris ROy-Smith ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] why can use a widget assigned to a variable or just use it on it's own?
On 02/07/18 02:54, Chris Roy-Smith wrote: > If I have grasped things correctly a widget is an object. Every value in Python is an object. numbers, strings, lists, functions, instances of classes. All are objects. You can see that by using the dir() function on them: >>> dir(5) ['__abs__', '__add__', '__and__', '__bool__', '__ceil__', '__class__', '__delattr__', '__dir__', '__divmod__', '__doc__', '__eq__', '__float__', '__floor__', '__floordiv__', '__format__', '__ge__', '__getattribute__', '__getnewargs__', '__gt__', '__hash__', '__index__', '__init__', '__init_subclass__', '__int__', '__invert__', '__le__', '__lshift__', '__lt__', '__mod__', '__mul__', '__ne__', '__neg__', '__new__', '__or__', '__pos__', '__pow__', '__radd__', '__rand__', '__rdivmod__', '__reduce__', '__reduce_ex__', '__repr__', '__rfloordiv__', '__rlshift__', '__rmod__', '__rmul__', '__ror__', '__round__', '__rpow__', '__rrshift__', '__rshift__', '__rsub__', '__rtruediv__', '__rxor__', '__setattr__', '__sizeof__', '__str__', '__sub__', '__subclasshook__', '__truediv__', '__trunc__', '__xor__', 'bit_length', 'conjugate', 'denominator', 'from_bytes', 'imag', 'numerator', 'real', 'to_bytes'] >>> dir(print) ['__call__', '__class__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__name__', '__ne__', '__new__', '__qualname__', '__reduce__', '__reduce_ex__', '__repr__', '__self__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__text_signature__'] >>> Those are all the attributes and methods/operations that you can access for a number and a function. And so, yes, widgets are also objects...They are instances of classes. > from tkinter import * > main=Tk() main is now a reference to an instance of the top level Tkinter class, Tk. > # as I understand it this will create an instance of the button widget > called b1 > b1=Button(main, text='instantce', command= lambda b='goodbye' : > print(b)).grid(row=1, column=0) No, this will create an instance of the Button class but it will not be called b1. You call grid() on your instance and grid always returns None. So b1 stores a reference to None. (Note that None is also an object!) > # but here I haven't made an instance, but all seems well > Button(main, text='test1', command=lambda a='hello' > :print(a)).grid(row=0, column=0) You have made an instance, exactly like before. The instance is created by you calling the class: Button(.) # creates an instance b = Button(.) ' creates instance and stores a reference in b b = Button(...).grid() # creates instance and # calls its grid method returning None to b Everything works because when you create a widget instance the first argument is always the parent widget. Inside the widget __init__() method the code looks something like this: def __init__(...): parent.children.append(self) So one of the first things the widget does is add itself to its parent's list of child widgets. That means that there is a reference to the widget inside parent whether you store a local reference or not. As a result the widget is not immediately destroyed. > any explanation gratefully received Hopefully that helps. -- 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] how to change the command "string" on a tkinter Button?
On 01/07/18 23:34, Alan Gauld via Tutor wrote: > Realize that you made a mistake, get the original > version back > > co -l -v1.1 myfile.py Oops, a bit rusty. The command should be: co -l1.1 myfile.py -- 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] why can use a widget assigned to a variable or just use it on it's own?
On Mon, Jul 02, 2018 at 11:54:08AM +1000, Chris Roy-Smith wrote: > Hi, > > I'm trying to understand working with objects. > > If I have grasped things correctly a widget is an object. In Python, all values are objects. (That's not the case in all languages.) > So why can I > assign the widget, or use it stand alone? See sample code below That depends on the object, but in general, you can use any object you like even if it doesn't survive the experience. Python knows enough to only access objects which are still alive. That's *incredibly common* for small, lightweight values like floats and strings. We might say: print(math.sin(1.3*math.pi) + 1) which creates (and then destroys) the following transient objects: * the float 1.3 * then the float 4.084070449666731 (multiplying the above by pi) * then the float -0.8090169943749473 (calling sin on the above) * then 0.19098300562505266 (adding 1) none of which survive more than a few microseconds. By the time the final value is printed, all of those transient objects will have been reclaimed for recycling by the garbage collector, their memory ready for re-use. The same applies for big, complex objects. But under normal circumstances, the bigger and more complex, the more unlikely you are to treat it as a transient, disposable object. (Creating lightweight objects is cheap, but the bigger the object, the less cheap it is.) In the case of tkinter, things are even more murky. Like many (all?) GUI frameworks, tkinter does a lot of behind the scenes clever stuff that makes it easier to use at the cost of being less comprehensible. And so: > # as I understand it this will create an instance of the button widget > called b1 > b1=Button(main, text='instantce', command= lambda b='goodbye' : > print(b)).grid(row=1, column=0) Actually, no, if you print the value of b1 -- or print its repr, print(repr(b1)) -- you might be in for a surprise. Your b1 is not actually the button, but the None object. But don't worry, the button object itself is safely attached to the TK main window, as if by magic. (That's tkinter's magic: the first argument to the Button constructor is the window to attach it to.) > # but here I haven't made an instance, but all seems well > Button(main, text='test1', command=lambda a='hello' > :print(a)).grid(row=0, column=0) Indeed. You don't have to hold onto the button, because the main window does it for you. -- Steve ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
[Tutor] Pip install and Ipv6
Hello, Is anyone else here having problems using Pip repository with ipv6? If I try to install something with pip, I get this: (python2) lgcosta:api/ $ pip install falcon Collecting falcon Retrying (Retry(total=4, connect=None, read=None, redirect=None, status=None)) after connection broken by 'ProtocolError('Connection aborted.', error(104, 'Connection reset by peer'))': /simple/falcon/ and it does not work ... but, I discovered this: (python2) lgcosta:api/ $ curl -I https://pypi.python.org/ curl: (35) gnutls_handshake() failed: Error in the pull function. (python2) lgcosta:api/ $ host pypi.python.org pypi.python.org is an alias for dualstack.python.map.fastly.net. dualstack.python.map.fastly.net has address 151.101.16.223 dualstack.python.map.fastly.net has IPv6 address 2a04:4e42:4::223 My default output is ipv6, so if I force it out by ipv4, it works: (python2) lgcosta:api/ $ curl -I -4 https://pypi.python.org/ HTTP/1.1 301 Redirect to Primary Domain Server: Varnish Retry-After: 0 Location: https://pypi.org/ Content-Type: text/html; charset=UTF-8 Content-Length: 122 output over ipv6, the repository does not work, only for ipv4. I did not find the option to force ipv4 on the pip. Does anyone have any notice or similar reports? Thanks ! -- Luiz Gustavo Costa (Powered by BSD) *+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+ ICQ: 2890831 / Gtalk: gustavo@gmail.com Blog: http://www.luizgustavo.pro.br ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
[Tutor] Need all values from while loop - only receiving one
Hi folks, I'm trying to calculate the amount of rent per lease for the life of the lease, by month. The following code provides the correct results except for the monthnum and billper. Monthnum is intended to show the month within the lease and the billper should list each date for rent billing. For example, if the lease commences May 1, 2018 for a 60 month term, 2018-05-01 is monthnum = 1 and the billper = 2018-05-01. The following 59 rows needs to increment the monthnum and billper values by 1. The while loop (below) returns the first value correctly but stops without continuing through the rest of the True matches. Code (see below for results): import xml.etree.ElementTree as ET import pyodbc import dateutil.relativedelta as rd import dateutil.parser as pr tree = ET.parse('DealData.xml') root = tree.getroot() for deal in root.findall("Deals"): for dl in deal.findall("Deal"): dealid = dl.get("DealID") for dts in dl.findall("DealTerms/DealTerm"): dtid = dts.get("ID") dstart = pr.parse(dts.find("CommencementDate").text) dterm = dts.find("LeaseTerm").text darea = dts.find("RentableArea").text for brrent in dts.findall("BaseRents/BaseRent"): brid = brrent.get("ID") begmo = int(brrent.find("BeginIn").text) if brrent.find("Duration").text is not None: duration = int(brrent.find("Duration").text) else: duration = 0 brentamt = brrent.find("Rent").text brper = brrent.find("Period").text perst = dstart + rd.relativedelta(months=begmo-1) perend = perst + rd.relativedelta(months=duration-1) billmocount = begmo while billmocount < duration: monthnum = billmocount billmocount += 1 billmo = perst while billmo < perend: billper = billmo billmo += rd.relativedelta(months=1) if dealid == "706880": print(dealid, dtid, brid, begmo, dstart, dterm, darea, brentamt, brper, duration, perst, perend, \ monthnum, billper) Results: 706880 4278580 45937180 1 2018-01-01 00:00:00 60 6200 15.0 rsf/year 36 2018-01-01 00:00:00 2020-12-01 00:00:00 35 2020-11-01 00:00:00 706880 4278580 45937181 37 2018-01-01 00:00:00 60 6200 18.0 rsf/year 24 2021-01-01 00:00:00 2022-12-01 00:00:00 35 2022-11-01 00:00:00 Any help is appreciated! Thank you, Daryl ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Need all values from while loop - only receiving one
On 02/07/18 21:06, Daryl Heppner wrote: > I'm trying to calculate the amount of rent per lease for the life of > the lease, by month. The following code provides the correct results > except for the monthnum and billper. > The while loop (below) returns the first value correctly but stops > without continuing through the rest of the True matches. Which whiole loop? There are two. > for dl in deal.findall("Deal"): > dealid = dl.get("DealID") > for dts in dl.findall("DealTerms/DealTerm"): > dtid = dts.get("ID") > dstart = pr.parse(dts.find("CommencementDate").text) > dterm = dts.find("LeaseTerm").text > darea = dts.find("RentableArea").text I'm a bit confused by this loop. You go round and round overwriting the same values but not doing anything with them? They eventually wind up weith the last value read. Is that really what you want? > for brrent in dts.findall("BaseRents/BaseRent"): > brid = brrent.get("ID") > begmo = int(brrent.find("BeginIn").text) > if brrent.find("Duration").text is not None: > duration = int(brrent.find("Duration").text) > else: > duration = 0 > brentamt = brrent.find("Rent").text > brper = brrent.find("Period").text > perst = dstart + rd.relativedelta(months=begmo-1) > perend = perst + rd.relativedelta(months=duration-1) > billmocount = begmo This is basically the same in that only the last value will be stored because you overwrite the same variables each time. > while billmocount < duration: > monthnum = billmocount > billmocount += 1 And this too is odd. You set monthnum to billmocount Then you increment billmocount Then you go round and do the same until billmocount equals duration(or somehow is slightly greater than), at which point monthnum is one less than billmo. So, assuming integer values are used, you could replace the loop with: billmocount = duration monthnum = billmocount -1 If it's floats then its only slightly more complex to work out the values directly. > billmo = perst > while billmo < perend: > billper = billmo > billmo += rd.relativedelta(months=1) And again here. billmo winds up equal or greater than perend and billper has the value billmo - rd.relativedelta(months=1) It would be more efficient to write billmo = perst delta = rd.relativedelta(months=1) while billmo < perend: billmo += delta billper = billmo - delta > if dealid == "706880": > print(dealid, dtid, brid, begmo, dstart, dterm, > darea, brentamt, brper, duration, perst, perend, \ > monthnum, billper) > I'm not clear what you think you are doing but it looks fundamentally flawed to me. I think you need a rethink of your design. -- 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