Re: [Tutor] How to access an instance variable of a superclass from an instance of the subclass?

2017-02-23 Thread Steven D'Aprano
On Thu, Feb 23, 2017 at 09:40:14PM +1100, Steven D'Aprano wrote:

> How do instance attributes normally get set? In the __init__ method:
> 
> class MyClass:
> def __init__(self):
> self.attribute = None
> 
> 
> If the __init__ method does get run, it doesn't get the chance to create 
> the instance attributes. So if you have a subclass that defines 
> __init__, you need to allow the superclass' __init__ to run too.

/me slaps forehead

Of course I meant to write:

If the __init__ method does NOT get run, it doesn't get the chance to 
create the instance attributes.


Sorry for any confusion.


-- 
Steve
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] How to access an instance variable of a superclass from an instance of the subclass?

2017-02-23 Thread boB Stepp
On Wed, Feb 22, 2017 at 10:49 PM, Zachary Ware
 wrote:
> On Wed, Feb 22, 2017 at 10:25 PM, boB Stepp  wrote:

>
> I'll give you a couple of hints.  First, try this:
>
> print('defining A')
> class A:
> print('Setting a on class A')

When I typed this in I was surprised to find that the print() happens
without having created an instance of this class yet.  Further
experimentation seems to indicate that all class methods and
attributes get executed and assigned when the class definition is
first read into the interpreter without any need to create an instance
of the class.  This is good to know!

> Next, have a look at
> https://docs.python.org/3/library/functions.html#super and in
> particular the link at the end to Raymond Hettinger's "super
> considered super" essay.

I had actually bookmarked this last week in my browser for later
reading.  I just got finished reading it.  It has brought additional
clarity, but also much more I need to think about and explore.

Thanks, Zach!



-- 
boB
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] How to access an instance variable of a superclass from an instance of the subclass?

2017-02-23 Thread boB Stepp
Thank you to everyone that provided illumination in this thread!
Things seem much clearer now, which caused me to realize that what I
wrote below cannot work as written (Even though I did copy and paste
it from the interpreter):

On Wed, Feb 22, 2017 at 10:53 PM, boB Stepp  wrote:
> On Wed, Feb 22, 2017 at 10:25 PM, boB Stepp  wrote:
>> I am trying to wrap my head around the mechanics of inheritance in
>> Python 3.  I thought that all attributes of a superclass were
>> accessible to an instance of a subclass.  But when I try the
>> following:
>>
>> py3: class A:
>> ... def __init__(self):
>> ... self.aa = 'class A'
>> ...
>> py3: class B(A):
>> ... def __init__(self):
>> ... self.bb = 'class B'
>> ...
>> py3: a = A()
>> py3: b = B()
>> py3: b.aa
>> Traceback (most recent call last):
>>   File "", line 1, in 
>> AttributeError: 'B' object has no attribute 'aa'
>>
>> I am unsuccessful...
>
> I have partially answered my own question, but I am not sure I
> understand the mechanics yet.  Apparently I must explicitly assign
> class A's attribute, aa, to an instance of class B as follows:
>
> py3: class B(A):
> ... def __init__(self):
> ... self.aa = super().aa
> ... self.bb = 'class B'
> ...
> py3: b = B()
> py3: b.aa
> 'class A'

If I had copied and pasted the above two sections of code
*contiguously*, this should have resulted in:

py3: class B(A):
... def __init__(self):
... self.aa = super().aa
... self.bb = 'class B'
...
py3: b = B()
Traceback (most recent call last):
  File "", line 1, in 
  File "", line 3, in __init__
AttributeError: 'super' object has no attribute 'aa'
py3: a = A()
py3: b = B()
Traceback (most recent call last):
  File "", line 1, in 
  File "", line 3, in __init__
AttributeError: 'super' object has no attribute 'aa'

When I went back to scroll back in ConEmu (Thanks Eryk Sun for
bringing this program to my attention!), I found that I had redefined
class A as follows:

py3: class A:
... aa = 'class A'
...

between those two blocks of code, which explains why "b = B()"
followed by "b.aa" worked.

Sorry 'bout that!  I did mention I was sleepy at the time... ~(:>))

-- 
boB
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Multiple muti-selection dropdown options

2017-02-23 Thread Alan Gauld via Tutor
On 23/02/17 22:25, Pooja Bhalode wrote:

> I am working on GUI where I have two dropdown menus in a Toplevel of the
> main root. 

That's not what your code shows. It shows scrolling listboxes, not
menus. But it seems like a Frame with a set of checkboxes would be
closer to what you actually want?

Anyway...

> The window shows as below:
> [image: Inline image 1]

As I keep pointing out you cannot send images to this list,
the server throws them away as potential security risks.

> Whereas the code is:
> 
> def selectexp():
> newlist = list()
> selection = lstbox.curselection()
> for i in selection:
> tempvar = lstbox.get(i)
> newlist.append(tempvar)
> 

Note that in this function you create a list, populate
it with values and then throw them all away. If you want
to keep the values you need to declare the list as a
global variable.

> for val in newlist:
> print (val)

Because you are not posting in plain text I can't
tell if those two lines are inside the previous
function or not. I'm assuming they are inside the
function? If not I'd expect a name error for newlist?

> def selectexp2():
> newlist2 = list()
> selection2 = lstbox2.curselection()
> for i in selection2:
> tempvar2 = lstbox2.get(i)
> newlist2.append(tempvar2)
> 
> for val in newlist2:
> print (val)

Same problem here, you declare newlist2 as a new
list inside the function, then when the function
exits it throws it away. If you want to access
variables after the function exits you need to
make them global (or start using classes and
objects)

> However, the issue is that when the user selects options from the first
> dropdown menu and moves on to selecting the second one, the first dropdown
> selections are lost, 

See comments above. Make the lists global.


-- 
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] Asking about Opening Teminal on Python

2017-02-23 Thread Alan Gauld via Tutor
On 23/02/17 22:16, Quang nguyen wrote:
> Hi everyone,
> I need to open a terminal on Raspberry Pi 2 in order to execute codesend of
> 433Utils to send a signal to RF Receiver. Anyone know how to open a
> terminal?

Do you really need a terminal? Or do you only need to execute some commands?

In either case the subprocess module should do what you need.
In the first case execute your local terminal program (eg xterm)
In the second case execute the command you want directly
via subprocess. This will be more efficient and save an extra
terminal window popping up to distract your user.


-- 
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] Multiple muti-selection dropdown options

2017-02-23 Thread Pooja Bhalode
Hi,

I am working on GUI where I have two dropdown menus in a Toplevel of the
main root. Here, both the dropdown menus have mutiple selection option and
thus, the selections can be taken as an input from the user and printed out
in the code.

The window shows as below:
[image: Inline image 1]
Whereas the code is:

simroot = Toplevel(root)
simroot.title("Simulation of experiments")

Label(simroot, text = "Displaying concentration profiles with respect to
time:").grid(row = 0, column = 0, sticky = W)

Label(simroot, text = "Select the experiments to be displayed: ").grid(row
= 1, column = 0, sticky = W)
varlist = StringVar()
varlist.set("Experiment1 Experiment2 Experiment3 Experiment4 Experiment5")
scroll1 = Scrollbar(simroot, orient = "vertical")
scroll1.grid(column = 2, sticky = W)

lstbox = Listbox(simroot, listvariable = varlist, selectmode = MULTIPLE,
yscrollcommand = scroll1.set, width = 20, height = 3)
lstbox.grid(row = 2, column = 1, sticky = W)
scroll1.config(command = lstbox.yview)

def selectexp():
newlist = list()
selection = lstbox.curselection()
for i in selection:
tempvar = lstbox.get(i)
newlist.append(tempvar)

for val in newlist:
print (val)


selectbutt = Button(simroot, text = "Submit", command = selectexp)
selectbutt.grid(row = 6,column = 1, sticky = W)
# Row 1 would print the name of the experiment selected and the species
displayed would be in row3.

Label(simroot, text = "Select concentration species:").grid(row = 7, column
= 0, sticky = W)
concvarlist = StringVar()
concvarlist.set("A B C D E")
scroll2 = Scrollbar(simroot, orient = "vertical")
scroll2.grid(column = 2, sticky = W)
lstbox2 = Listbox(simroot, listvariable = concvarlist, selectmode =
MULTIPLE, yscrollcommand = scroll2.set, width = 20, height = 3)
lstbox2.grid(row = 8, column = 1, sticky = W)
scroll2.config(command = lstbox2.yview)
def selectexp2():
newlist2 = list()
selection2 = lstbox2.curselection()
for i in selection2:
tempvar2 = lstbox2.get(i)
newlist2.append(tempvar2)

for val in newlist2:
print (val)
selectbutt = Button(simroot, text = "Submit", command = selectexp2)
selectbutt.grid(row = 9,column = 1, sticky = W)


def Submitplot():
print "Create plot"

Button(simroot, text = "Submit and Plot", command = Submitplot).grid(row =
10, column = 0, sticky = W)

However, the issue is that when the user selects options from the first
dropdown menu and moves on to selecting the second one, the first dropdown
selections are lost, is there a way to store the highlighted selections on
the display screen? In the code, I can get them printed and save the
selections, however I was looking for a way to keep them highlighted on the
screen as well for both the drop down menus.
Please let me know.
Thank you

Pooja
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


[Tutor] Asking about Opening Teminal on Python

2017-02-23 Thread Quang nguyen
Hi everyone,
I need to open a terminal on Raspberry Pi 2 in order to execute codesend of
433Utils to send a signal to RF Receiver. Anyone know how to open a
terminal?
Thank you.
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] How to access an instance variable of a superclass from an instance of the subclass?

2017-02-23 Thread Steven D'Aprano
On Wed, Feb 22, 2017 at 10:25:58PM -0600, boB Stepp wrote:
> I am trying to wrap my head around the mechanics of inheritance in
> Python 3.

Here is a simplified picture of how inheritence usually works in Python.

For an instance `spam`, when you look up an attribute (which includes 
methods), Python checks the following places *in this order*:

- attributes attached to spam itself ("instance attributes");

- attributes attached to spam's class ("class attributes");

- attributes attached to any parent classes (class attributes
  of superclasses).


(The actual rules are much more complex, but this will do for starters.)

If no such attribute is found, Python will try calling the class 
__getattr__ (if any) or superclass __getattr__, and if that doesn't 
exist or fails, Python will raise AttributeError.

How do class attributes normally get set? In the class definition:

class MyClass:
attribute = None


How do instance attributes normally get set? In the __init__ method:

class MyClass:
def __init__(self):
self.attribute = None


If the __init__ method does get run, it doesn't get the chance to create 
the instance attributes. So if you have a subclass that defines 
__init__, you need to allow the superclass' __init__ to run too.



-- 
Steve
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] How to access an instance variable of a superclass from an instance of the subclass?

2017-02-23 Thread Alan Gauld via Tutor
On 23/02/17 04:25, boB Stepp wrote:
> I am trying to wrap my head around the mechanics of inheritance in
> Python 3.  I thought that all attributes of a superclass were
> accessible to an instance of a subclass. 

For class attributes that happens automatically.

>>> class A:
a = 'A'
def __init__(self):
self.aa = 'aa'


>>> class X(A): pass

>>> x = X()
>>> x.a
'A'
>>> x.aa
'aa'

Notice that both the class and instance variables
are inherited. That's because there is no
__init__() in X so the inherited A.__init__()
is called.

Now, if we add an init to the subclass:

>>> class B(A):
b = 'B'
def __init__(self):
self.bb='bb'


>>> b = B()
>>> b.a
'A'
>>> b.bb
'bb'
>>> b.aa
Traceback (most recent call last):
  File "", line 1, in 
b.aa
AttributeError: 'B' object has no attribute 'aa'

We get the scenario you found. (But with the additional fact
that B can access A's class variable 'a')

The B.__init__() is called, but it does not create an aa instance
variable. To do so we need to call the superclass constructor:

>>> class C(A):
c = 'C'
def __init__(self):
super().__init__()
self.cc = 'cc'


>>> c = C()
>>> c.a
'A'
>>> c.aa
'aa'
>>> c.cc
'cc'
>>> c.bb
Traceback (most recent call last):
  File "", line 1, in 
c.bb
AttributeError: 'C' object has no attribute 'bb'
>>>

Now C can access cc and aa (as well as a), but
not B.bb of course because its not in the inheritance line.

There is no real magic(*) going on here.
When you call SomeClass() the SomeClass.__new__() method
gets called which is usually the one defined in object.
That method results in __init__() getting called. The
usual method lookup applies, the first init() found will
be executed. If it doesn't explicitly call the
superclass init then that method will never be
called.

(*)Actually its not quite this straightforward because
meta-classes are involved in the invocation of new()
and it all gets a bit mind-bending. But as a concept
you can stick with new() as the constructor calling
init() as the initializer and both being subject
to the usual method resolution rules.

-- 
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 access an instance variable of a superclass from an instance of the subclass?

2017-02-23 Thread Steven D'Aprano
On Wed, Feb 22, 2017 at 10:25:58PM -0600, boB Stepp wrote:
> I am trying to wrap my head around the mechanics of inheritance in
> Python 3.  I thought that all attributes of a superclass were
> accessible to an instance of a subclass.  But when I try the
> following:
> 
> py3: class A:
> ... def __init__(self):
> ... self.aa = 'class A'
> ...

There you have a class with an initializer method.

And here you subclass it:

> py3: class B(A):
> ... def __init__(self):
> ... self.bb = 'class B'
> ...

But you *override* the initialiser method and prevent the superclass' 
method from running. Only B's custom version will run.

That's allowed, but fairly unusual. Normally you want to "overload" the 
method. Python can't guess if you want to call the superclass' version 
before or after your customization, so you have to decide for yourself:

class B(A):
def __init__(self):
super().__init__()  # call the superclass first
self.bb = 'class B'
super().__init__()  # or last

(Just don't do it twice, as I have! :-)

In this specific instance, it doesn't matter whether you call super() 
first or last, but often it will.


Welcome to the complexity of inheritence! And wait until you learn about 
multiple-inheritence, diamond diagrams, mixins, traits, and more. 

It's not *always* this complex. Often you subclass just to extend the 
class by adding a new method, and inheritence Just Works. You don't even 
have to think about it. But when overriding and overloading methods, you 
do have to think about what you are doing.



-- 
Steve
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] How to access an instance variable of a superclass from an instance of the subclass?

2017-02-23 Thread Peter Otten
boB Stepp wrote:

> On Wed, Feb 22, 2017 at 10:25 PM, boB Stepp 
> wrote:
>> I am trying to wrap my head around the mechanics of inheritance in
>> Python 3.  I thought that all attributes of a superclass were
>> accessible to an instance of a subclass.  But when I try the
>> following:
>>
>> py3: class A:
>> ... def __init__(self):
>> ... self.aa = 'class A'
>> ...
>> py3: class B(A):
>> ... def __init__(self):
>> ... self.bb = 'class B'
>> ...
>> py3: a = A()
>> py3: b = B()
>> py3: b.aa
>> Traceback (most recent call last):
>>   File "", line 1, in 
>> AttributeError: 'B' object has no attribute 'aa'
>>
>> I am unsuccessful...
> 
> I have partially answered my own question, but I am not sure I
> understand the mechanics yet.  Apparently I must explicitly assign
> class A's attribute, aa, to an instance of class B as follows:
> 
> py3: class B(A):
> ... def __init__(self):
> ... self.aa = super().aa
> ... self.bb = 'class B'
> ...
> py3: b = B()
> py3: b.aa
> 'class A'
> 
> I was expecting that all of A's methods and attributes would
> seamlessly be available to any instance of class B, but apparently
> this is wrong-headed on my part.  Instead, it looks like I need to
> explicitly attach A's methods and attributes to B's instances via B's
> self.
> 
> I will continue to mull this over.
 
You are making this harder than need be. If you have one class

class A:
   def __init__(self):
   # complex calculation --> a
   self.a = a
   self.b = "whatever"

you could split the code into two methods, to keep it manageable, say:

class A:
def __init__(self):
self.init_a()
self.b = "whatever"

def init_a(self):
# complex calculation
self.a = a

This will obviously continue to work with two classes:

class A:
def init_a(self):
# complex calculation
self.a = a

class B(A):
def __init__(self):
self.init_a()
self.b = "whatever"

Now what if init_a() is actually called __init__? Just renaming will not 
work

class A:
def __init__(self):
# complex ...
self.a = a

class B(A)
def __init__(self):
self.__init__() # this will invoke B.__init__ again
# --> infinite recursion
self.b = "whatever"

so you either have to be explicit

class B(A)
def __init__(self):
A.__init__(self) # this will invoke A.__init__
 # because we told it to
self.b = "whatever"

or use "black magic"

class B(A):
def __init__(self):
super().__init__() # have Python figure out
   # what to call
self.b = "whatever"

___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor