[Tutor] why can use a widget assigned to a variable or just use it on it's own?

2018-07-02 Thread 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)


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?

2018-07-02 Thread Timo

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?

2018-07-02 Thread Alan Gauld via Tutor
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?

2018-07-02 Thread Alan Gauld via Tutor
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?

2018-07-02 Thread Steven D'Aprano
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

2018-07-02 Thread Luiz Gustavo S. Costa
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

2018-07-02 Thread Daryl Heppner
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

2018-07-02 Thread Alan Gauld via Tutor
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