Re: [Tutor] loops to assign variables

2006-07-26 Thread Alan Gauld
I'm reading the gmane news archive to see what I missed
while on vacation and noticed this. Sorry the response is
so late...

John CORRY [EMAIL PROTECTED] wrote

 For example, I have 30 textentry boxes numbered from entry20 to 
 entry50.
 I have used the following code to assign the entryboxes to a local 
 name.

 text20 = self.wTree.get_widget(entry20)
 text21 = self.wTree.get_widget(entry21)

This is not a resonse to Johns original request but a general
comment on variable naming. It seems quite common in GUI
work for folks to use this style of entryN, buttonM etc.

But its not very programmer friendly! We wouldn't normally
call our variables var1, var2 etc it makes the intent of the code
much harder to comprehend. So we choose meaningful variable
names like width, height, name, location etc.

So why not do the same with GUI widgets? I usually prepend
a short code to indicate the type of widget, and either use the
label text or action name for the vatriable. Thus

eName  an entry widget for holding the name and it has
an associated label text of Name

bSave -- a button that has an assaociated action
function called save()

A one or two letter prefix should cover all widget types and
it makes the code much easier to read! Even if using GUI
builder tools it is nearly always possible to rename the
widget from the default widgetXX type name to something
meaningful using the property editor.

 I have had a go at writing a loop for the above 30 textentry boxes. 
 It
 is below, but it does not work.

If you need to loop over widgets in a collection the best way
is to simply add the widgets to a collection.

for widget in widgets:
widget.doSomething()

Or use a dictionary:

widgets = {'Name': eName, 'Save': bSave, ...}
for widget in widgets:

in fact usually you can just navigate the widget containment
tree to access all the widgets at a given level.

Even if you are creating the widgets in bulk and don't have specific
names for each field you can still do the same thing and group
them together with a name for the group. Then load the entry
widgets into a list named by the group, for example of you have
a set of 5 arbitrary search strings that a user can specify,
you define a list called searchStrings and add the widgets to that:

for n in range(5):
searchStrings.append(Entry(args here))

Now we can access the seach strings with

for entry in searchStrings:
 searchString += entry.getval()

mydata.search(searchString)

Or similar techniques. There is hardly ever a good case for
using generic widgetXXX type names IMHO.

Just some stylistic considerations.

-- 
Alan Gauld
Author of the Learn to Program web site
http://www.freenetpages.co.uk/hp/alan.gauld



___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] loops to assign variables

2006-07-23 Thread Alan Gauld
I've been on vacation so missed the start of this, apologies 
if i'm missing a point somewhere but...

 Ah. I see.  A copy, eh?  Or, at least a new dictionary separate
 from the real namespace.  OK.  I don't know why locals() returns
 a copy as opposed to the original, 

What else can it do?
When you enter a function you enter a new namespace.
It starts out containing the global names and any parameters 
to the function then adds new names as they are created 
plus overrides any global names that get replaced with 
local versions.

It can only do that if it is working on a copy of the global 
namespace to start with otherwise it would be polluting the 
global namespace with local functon versions and in a 
multithreaded environment creating havoc across threads!...

I hope I haven't missed the point and have added some 
clarification, if not forgive me for butting in late! :-)

Alan G.

___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] loops to assign variables

2006-07-22 Thread Karl Pflästerer
On 22 Jul 2006, [EMAIL PROTECTED] wrote:


 On Sat, 2006-07-22 at 14:11 +0100, John CORRY wrote:
 Hi,
  
 I am refactoring my code.  I am trying to reduce the amount of lines
 by using more loops.  I tend to use copy and paste a lot instead of
 writing a loop to do the work.
  
 For example, I have 30 textentry boxes numbered from entry20 to
 entry50.
 I have used the following code to assign the entryboxes to a local
 name.
  
 text20 = self.wTree.get_widget(entry20)
 text21 = self.wTree.get_widget(entry21)
  
 I have had a go at writing a loop for the above 30 textentry boxes.
 It is below, but it does not work.  
  
 for x in range(20,51):
 ent = entry%s % (str(x))

 text_x = self.wTree.get_widget(ent)
  
 Is it possible to do what I want it to do?  

 NO.  You are looking to create local variables on the fly.  But there
 is a simple solution that accomplishes what you really want.

The no is not absolutely right IMO.  He could write directly in the
dictionary he gets when he calls locals() (but I think you're right in
saying that this is only seldom a good idea).


   Karl
-- 
Please do *not* send copies of replies to me.
I read the list
___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] loops to assign variables

2006-07-22 Thread Python
On Sat, 2006-07-22 at 17:18 +0200, Karl Pflästerer wrote:
 On 22 Jul 2006, [EMAIL PROTECTED] wrote:
 
 
  On Sat, 2006-07-22 at 14:11 +0100, John CORRY wrote:
  Hi,
   
  I am refactoring my code.  I am trying to reduce the amount of lines
  by using more loops.  I tend to use copy and paste a lot instead of
  writing a loop to do the work.
   
  For example, I have 30 textentry boxes numbered from entry20 to
  entry50.
  I have used the following code to assign the entryboxes to a local
  name.
   
  text20 = self.wTree.get_widget(entry20)
  text21 = self.wTree.get_widget(entry21)
   
  I have had a go at writing a loop for the above 30 textentry boxes.
  It is below, but it does not work.  
   
  for x in range(20,51):
  ent = entry%s % (str(x))
 
  text_x = self.wTree.get_widget(ent)
   
  Is it possible to do what I want it to do?  
 
  NO.  You are looking to create local variables on the fly.  But there
  is a simple solution that accomplishes what you really want.
 
 The no is not absolutely right IMO.  He could write directly in the
 dictionary he gets when he calls locals() (but I think you're right in
 saying that this is only seldom a good idea).

Well the reference documentation says:

locals(
)
Update and return a dictionary representing the current local
symbol table. Warning: The contents of this dictionary should
not be modified; changes may not affect the values of local
variables used by the interpreter.

I believe the compiler thinks it knows of all the local variables, so I
think assignment to locals() is likely to lead to grief even it appears
to work in simple test cases.

-- 
Lloyd Kvam
Venix Corp

___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] loops to assign variables

2006-07-22 Thread Dave Kuhlman
On Sat, Jul 22, 2006 at 11:37:38AM -0400, Python wrote:
 On Sat, 2006-07-22 at 17:18 +0200, Karl Pflästerer wrote:
  On 22 Jul 2006, [EMAIL PROTECTED] wrote:
  
  
   On Sat, 2006-07-22 at 14:11 +0100, John CORRY wrote:
   Hi,

   I am refactoring my code.  I am trying to reduce the amount of lines
   by using more loops.  I tend to use copy and paste a lot instead of
   writing a loop to do the work.

   For example, I have 30 textentry boxes numbered from entry20 to
   entry50.
   I have used the following code to assign the entryboxes to a local
   name.

   text20 = self.wTree.get_widget(entry20)
   text21 = self.wTree.get_widget(entry21)

   I have had a go at writing a loop for the above 30 textentry boxes.
   It is below, but it does not work.  

   for x in range(20,51):
   ent = entry%s % (str(x))
  
   text_x = self.wTree.get_widget(ent)

   Is it possible to do what I want it to do?  
  
   NO.  You are looking to create local variables on the fly.  But there
   is a simple solution that accomplishes what you really want.
  
  The no is not absolutely right IMO.  He could write directly in the
  dictionary he gets when he calls locals() (but I think you're right in
  saying that this is only seldom a good idea).
 
 Well the reference documentation says:
 
 locals(
 )
 Update and return a dictionary representing the current local
 symbol table. Warning: The contents of this dictionary should
 not be modified; changes may not affect the values of local
 variables used by the interpreter.
 
 I believe the compiler thinks it knows of all the local variables, so I
 think assignment to locals() is likely to lead to grief even it appears
 to work in simple test cases.
 

Lloyd is spot-on in telling you to avoid creating variables from
strings.  There almost always is a better way, which members of
this list seem to have to repeat once each week.

But, (and I'm going off-topic here and possibly into the ditch
along the side of the road) ..., locals() returns a dictionary.
It's a dictionary like any other dictionary.  And, it is that
dictionary which Python uses to check for the existence of a
variable *at runtime*.  Yes. That's right.  Python actually does a
dictionary look-up for each variable at runtime.  This is *not* a
flaw; it is part of the object model and execution model of
Python.  And, that's why compile-time (static) type checking in
Python is either impossible or would require type inference.

And, also, that's why the following statements all have exactly
the same effect:

total = 5
locals()['total'] = 5
exec('total = 5')

But, again, as Lloyd said, don't do that.  (1) Use a dictionary of
your own and do a look up.  Or, (2) implement a class that does a
lookup.  Or, (3) use one of the other suggestion made on this
list.

Dave



-- 
Dave Kuhlman
http://www.rexx.com/~dkuhlman
___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] loops to assign variables

2006-07-22 Thread Kent Johnson
Dave Kuhlman wrote:
 On Sat, Jul 22, 2006 at 11:37:38AM -0400, Python wrote:
   

 Well the reference documentation says:

 locals(
 )
 Update and return a dictionary representing the current local
 symbol table. Warning: The contents of this dictionary should
 not be modified; changes may not affect the values of local
 variables used by the interpreter.

 I believe the compiler thinks it knows of all the local variables, so I
 think assignment to locals() is likely to lead to grief even it appears
 to work in simple test cases.

 
 But, (and I'm going off-topic here and possibly into the ditch
 along the side of the road) ..., locals() returns a dictionary.
 It's a dictionary like any other dictionary.  And, it is that
 dictionary which Python uses to check for the existence of a
 variable *at runtime*.  Yes. That's right.  Python actually does a
 dictionary look-up for each variable at runtime.  This is *not* a
 flaw; it is part of the object model and execution model of
 Python.  And, that's why compile-time (static) type checking in
 Python is either impossible or would require type inference.

 And, also, that's why the following statements all have exactly
 the same effect:

 total = 5
 locals()['total'] = 5
 exec('total = 5')

You're not in the mood to believe the docs today, eh? Yes, locals() 
returns a dict and yes, you can modify it. And yes, changes may not 
affect the values of local variables used by the interpreter. In 
particular modifying locals() inside a function doesn't do what you 
think it will:

In [14]: def badlocals():
   : locals()['total'] = 5
   : print total
   :

In [15]: badlocals
Out[15]: function badlocals at 0x00E4AEB0

In [16]: badlocals()
---
exceptions.NameError Traceback (most 
recent call last)

F:\Bio\BIOE480\Final project\SequenceAlignment\ipython console

F:\Bio\BIOE480\Final project\SequenceAlignment\ipython console in 
badlocals()

NameError: global name 'total' is not defined

At global scope, locals() == globals() and modifying it affects the 
global namespace. In function scope, I believe locals() is actually a 
copy of the real namespace.

Kent

___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] loops to assign variables

2006-07-22 Thread Dave Kuhlman
On Sat, Jul 22, 2006 at 01:41:17PM -0400, Kent Johnson wrote:
 Dave Kuhlman wrote:

[snip]

  And, also, that's why the following statements all have exactly
  the same effect:
 
  total = 5
  locals()['total'] = 5
  exec('total = 5')
 
 You're not in the mood to believe the docs today, eh? Yes, locals() 
 returns a dict and yes, you can modify it. And yes, changes may not 
 affect the values of local variables used by the interpreter. In 
 particular modifying locals() inside a function doesn't do what you 
 think it will:
 
 In [14]: def badlocals():
: locals()['total'] = 5
: print total
:
 
 In [15]: badlocals
 Out[15]: function badlocals at 0x00E4AEB0
 
 In [16]: badlocals()
 ---
 exceptions.NameError Traceback (most 
 recent call last)
 
 F:\Bio\BIOE480\Final project\SequenceAlignment\ipython console
 
 F:\Bio\BIOE480\Final project\SequenceAlignment\ipython console in 
 badlocals()
 
 NameError: global name 'total' is not defined

Good lord.  I feel queasy.  I think I just felt the ground move
under me.  (We in California near the fault line are sensitive
that way.)  What is the explanation of this?

 
 At global scope, locals() == globals() and modifying it affects the 
 global namespace. In function scope, I believe locals() is actually a 
 copy of the real namespace.

Ah. I see.  A copy, eh?  Or, at least a new dictionary separate
from the real namespace.  OK.  I don't know why locals() returns
a copy as opposed to the original, but at least that explains the
results of the example you give.  And, the sickening feeling of
dread has gone away, the feeling or dread one has when the
fundamental structure of the (Python) world has been turned upside
down.

Thanks for correcting me and for clarification.  And, looks like
Lloyd was right.

Dave


-- 
Dave Kuhlman
http://www.rexx.com/~dkuhlman
___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor