[Edu-sig] Python for Fun
Kirby Urner
pdx4d@teleport.com
Fri, 25 May 2001 22:17:06 -0700
>>Could also go:
>>
>> self.connects.extend(inputs) (is that 1.5 or later?)
>>
>Is this actually different from .append ?
It's different with later versions because in those append
only accepts a single argument e.g.:
>>> a = [1,2,3]
>>> a.append([4,5,6])
>>> a
[1, 2, 3, [4, 5, 6]]
>>> a = [1,2,3]
>>> a.extend([4,5,6])
>>> a
[1, 2, 3, 4, 5, 6]
>I tried this and it seemed to work
>>>>
>>>> class con :
>... def __init__ (self) :
>... self.x = 5
>... def prnt (selfi,c) :
>... print self.x + c
>...
>>>> a = con()
>>>> b = [a,a,a]
>>>> map(lambda x: x.prnt(4), b)
>9
>9
>9
>[None, None, None]
If I use the following as my def of set in the Connector class:
def set (self, value) :
if self.value == value : return # Ignore if no change
self.value = value
if self.activates : self.owner.evaluate()
if self.monitor :
print "Connector %s-%s set to %s" %
(self.owner.name,self.name,self.value)
map(lambda con: con.set(value), self.connects)
Then upon import I get the warning:
d:\program files\python21\ocn\logic.py:25: SyntaxWarning: local name
'value' in 'set' shadows use of 'value' as global in nested scope 'lambda'
self.value = value
And the program crashes when using test4Bit:
>>> test4Bit('1001','1110')
Connector F0-Cin set to 0
Traceback (most recent call last):
File "<pyshell#40>", line 1, in ?
test4Bit('1001','1110')
File "d:\program files\python21\ocn\logic.py", line 124, in test4Bit
F0.Cin.set(0)
File "d:\program files\python21\ocn\logic.py", line 32, in set
map(lambda con: con.set(value), self.connects)
File "d:\program files\python21\ocn\logic.py", line 32, in <lambda>
map(lambda con: con.set(value), self.connects)
NameError: global name 'value' is not defined
However, if I insert:
from __future__ import nested_scopes
at the top of logic.py, then the code reloads w/o warnings and runs fine,
because with nested scopes, lambda is perfectly able to see the value of
'value' without needing to have that passed explicitly, as in:
map(lambda con, value=value: con.set(value), self.connects)
...which works OK without the nested_scopes feature (probably in
1.5.3 as well then). It's this value=value stuff that the nested
scopes feature is designed to avoid/obviate.
Another experiment: if I write a test module named test2.py with
the following function only:
def test(x):
y=5
return map(lambda x: x+y, [x])
then on import I get the warning:
>>> import test2
d:\program files\python21\ocn\test2.py:1: SyntaxWarning: local name
'y' in 'test' shadows use of 'y' as global in nested scope 'lambda'
def test(x):
but if I add the line:
from __future__ import nested_scopes
to the top of the test2.py module and reload, then y is captured
in the lambda. No warnings, function works:
>>> test2.test(10)
[15]
What I find interesting is that I can't make the above function
work in IDLE if I enter it at the command line, even if I enter
from __future__ import nested_scopes.
In other words, whereas adding this 2.1-only import statement to
the top of a module suppresses the warning and makes the code OK,
entering this import statement at the command line doesn't salvage
the code.
>>>>
>Speaking of scoping. If you get around to Lisp in Python, there's a
>section on dynamic scoping with an example.
>
>Chris
I did study the Lisp example for awhile. I'm always awed by LISP
and all that tail recursion. Yet the LISP _does_ have looping
syntax in the versions I've seen. It's Scheme that stays purist
about using only recursion for looping, no?
>From what I understand of all this, Python isn't really tail
recursive under the hood. Am I right about that?
Building more complicated circuits with your logic gates would
be fun. I've got this 'Beebop to the Boolean Boogie' book
that'd make a good guide for testing out some other circuits.
Dunno when/if I'll get to do it.
Kirby