Re: creating class objects inside methods

2009-10-04 Thread horos11
Carl,

Thanks for the info, but a couple of points:

1. it wasn't meant to be production code, simply a way to teach
python.

2. this should either be a compile time or a runtime error.

'Actions at a distance' like this are deadly both to productivity and
to correctness - not only is this a runtime error, it is a *silent*
runtime error. Any other language I know would catch this, whether it
be lua, java, or perl.

Saying that 'whoa, this coding error should be handled by naming
convention' may be the only practical way of getting around this
limitation, but it is a limitation nonetheless, and a pretty big one.

Ed



O
-- 
http://mail.python.org/mailman/listinfo/python-list


defaults for function arguments bound only once(??)

2009-10-04 Thread horos11
All,

Another one, this time a bit shorter.

It looks like defaults for arguments are only bound once, and every
subsequent call reuses the first reference created. Hence the
following will print '[10,2]' instead of the expected '[1,2]'.

Now my question - exactly why is 'default_me()' only called once, on
the construction of the first object? And what's the best way to get
around this if you want to have a default for an argument which so
happens to be a reference or a new object?

 code begins here ---

import copy
class A:

def default_me():
return [1,2]

def __init__(self, _arg=default_me()):
self.arg = _a


a = A()
a.arg[0] = 10
b = A()

print b.arg  # prints [10,2]
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: creating class objects inside methods

2009-10-04 Thread horos11

 It's not a bug.  In Python classes and global variables share the same
 namespace.

 Don't you think you should learn a bit more about how Python manages
 objects and namespaces before going around calling things bugs?

 Carl Banks

No, I don't think so..

Say you went to another country, where the people wore lead shoes,
hence not only going slower, but getting lead poisoning from time to
time.

Pointing out that shoes made of fabric might just be better should not
be heresy.

In this case, I think the overall goal was syntax simplicity, but it
sure as hell makes things confusing. No warning, or anything. The sane
behavior IMO would be to disallow the assignment unless put through a
special function, something like:

class(state) = ...

After all, python does have a precedent when you try to join, when:

:.join([1,2])

does not work because [1,2] is an array of ints, whereas

: . join( str(x) for x in [1,2])

does.

Ed
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: creating class objects inside methods

2009-10-04 Thread horos11


  Thanks for the info, but a couple of points:

      1. it wasn't meant to be production code, simply a way to teach
  python.

 Speaking as someone who does teach Python, Ew, no!  If you start by
 teaching people bad habits, every educator who comes along afterwards
 will curse your name.  That includes teaching yourself.

 --
 Rhodri James *-* Wildebeest Herder to the Masses

No offense, but I disagree. By programming without regards to pre-
existing style or convention I learned far more than I otherwise would
have if I had simply mimicked someone else.

And I still think that unbridled assignment - especially assignment
that can change the operational semantics of surrounding terms, at a
distance no less - is a horrid thing.

It gets even worse because the way python handles assignment. To go
back to my original program: why isn't the state variable that I
defined local to that 'if' loop?

while len(dq):

...
if curstate.is_answer():
...
else:
for state in ...


The answer? Because you can't explicitly declare it. It therefore
looks globally, finds the 'class state:' statement, and runs with it.
I should be able to say:

for my state in curstate.next_states():

to show explicitly what I'm doing.


Anyways, maybe I got off to a bad start, but I'm a bit leery of the
language. In my estimation it's trying to be 'too clever by half', and
this coming from a veteran bash/perl programmer. I mean, free form is
one thing, but too much of a good thing can be harmful to your
programming health. Maybe PyChecker or PyLint will help, I don't know.

Ed

(
ps - an aside, but what was the rationale behind only displaying one
error at a time on trying to run a script? I typically like to run a
compilation phase inside my editor (vim), get a list of errors, and
then go to each one and fix them.

And how do you just check a script's syntax without running it
anyways?
)
-- 
http://mail.python.org/mailman/listinfo/python-list


creating class objects inside methods

2009-10-03 Thread horos11
All,

I've got a strange one..

I'm trying to create a class object inside another class object by
using the code template below (note.. this isn't the exact code.. I'm
having difficulty reproducing it without posting the whole thing)

Anyways, the upshot is that the first time the Myclass() constructor
is called, the __init__ function gets executed.. The second time, it
calls the '__call__' method (and dies, because I don't have a call
method defined).

To get around this, I've made __call__ a synonym of __init__, which is
a horrid hack, and doesn't help me much (since I don't have a good
idea what's going on).

So - anyone have an idea of what's going on here? It looks like the
second time, the Myclass() call is interpreted as a class instance,
not a  class object, but that seems odd to me.. Is this a python bug?
I'm seeing it in 2.6..If necessary, I can post the whole piece of
code..

Ed

class Myclass:

def __init__(self, b='default1', c='default2'):

self.b = b;
self.c = c;

def function(self):

 other = Myclass();
 return(other)

a = Myclass();

b = a.function()
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: creating class objects inside methods

2009-10-03 Thread horos11

  a

 __main__.Myclass instance at 0x95cd3ec b

 __main__.Myclass instance at 0x95cd5ac

 What's the problem?

Like I said, the code was a sample of what I was trying to do, not the
entire thing.. I just wanted to see if the metaphor was kosher.

It sounds to me from your answer that this is unexpected behavior, so
I'll go ahead and post the whole thing. My guess is that it is a
python bug..

Run it (a simple puzzle game solved by breadth first search), and the
first time state() is called inside the method, it calls __init__.
Second time, and therafter, it calls __call__. I've highlighted where
the code fails by putting a pdb.set_trace().

Anyways, I've got a workaround (simply pass in any new objects needed
from the caller), but it is truly annoying that python is either
misleading or broken in this way.

Attached find code, does not work vs. 2.6..


Ed



from collections import deque
import copy
import pdb

class state:

def default_board():

return [
  [ 1, 'x', 'x', 0 ],
  [ 2, 2,  3,  4 ],
  [ 5, 6,  6,  7 ],
  [ 5, 6,  6,  7 ],
  [ 8, 9, 10, 10 ],
  [ 0, 'x', 'x', 0 ]
]

def default_types():

return {
1  : [ 0, 0 ],
2  : [ 0, 0, 0, 1 ],
3  : [ 0, 0 ],
4  : [ 0, 0 ],
5  : [ 0, 0, 1, 0 ],
6  : [ 0, 0, 1, 0, 0, 1, 1, 1 ],
7  : [ 0, 0, 1, 0 ],
8  : [ 0, 0 ],
9  : [ 0, 0 ],
10 : [ 0, 0, 0, 1 ]
}

def default_moves():

return []

def print_move(self, moveno, move):
print str(moveno) + :  + str(move) + \n


def __init__(self, _board=default_board(), _moves=default_moves(),
_types=default_types()):

self.board = _board
self.moves = _moves
self.types = _types

def possible_moves(self):

moves_so_far = set()
moves_so_far.add('x')
moves_so_far.add(0)
ret = []
for y_idx in range(0, len(self.board)):
for x_idx in range(0, len(self.board[y_idx])):

piece = self.board[y_idx][x_idx]

if not piece in moves_so_far:

moves = self.legal_moves(y_idx, x_idx)
moves_so_far.add(piece)

if moves:
ret.extend(moves)

return ret

def is_answer(self):

if self.board[5][3] == 1:
return True
else:
return False

def legal_moves(self, ycoord, xcoord):

ret = []
for dir in [ [ 0, 1 ], [ 0, -1 ], [ 1, 0 ], [ -1, 0 ] ]:
ret.extend(self.addmove(dir[0], dir[1], ycoord, xcoord))

return ret

def empty(self, type, ycoord, xcoord, pieceno):

for itr in range(0, len(type), 2):

yy = type[itr]
xx = type[itr+1]

if not (len(self.board)  (yy+ycoord) = 0)  or not (len
(self.board[yy+ycoord])  xx+xcoord = 0):
return False

if not self.board[yy+ycoord][xx+xcoord] in [ 0, pieceno ]:
return False

return True

def addmove(self, ymult, xmult, ycoord, xcoord):

ret = []
pieceno = self.board[ycoord][xcoord]
type= self.types[pieceno]

if xmult != 0:
for xx in range(xcoord + xmult, -1 if xmult  0 else 4, -1
if xmult  0 else 1):
#   if xx == 0:
#   continue
if self.empty(type, ycoord, xx, pieceno):
ret.append(self.newmove(ycoord, xcoord, ycoord,
xx ))
else:
break

if ymult != 0:
for yy in range(ycoord + ymult, -1 if ymult  0 else 6, -1
if ymult  0 else 1):
#   if yy == 0:
#   continue
if self.empty(type, yy, xcoord, pieceno):
ret.append(self.newmove(ycoord, xcoord, yy,
xcoord))
else:
break

return ret

def newmove(self, fromy, fromx, toy, tox):

move = {
'fromx' : fromx,
'fromy' : fromy,
'toy'   : toy,
'tox'   : tox,
'piece' : self.board[fromy][fromx]
}

return move

def printout_path(self):

#   print self
pdb.set_trace()
answer = state()

moveno = 0
print \n==\n

for moveno in range(0, len(self.moves)):
move = self.moves[moveno]
self.print_move(moveno, move)
answer.apply_move(move)
answer.print_board()
print \n==\n

def print_board(self):

for xx in self.board:

print : .join([ %2s % str(ii) for ii in xx ])

def to_string(self):

return str(self.board)

def apply_move(self, move):

  

Re: creating class objects inside methods

2009-10-03 Thread horos11
Anyways, I see what's going on here:

With the line,

for state in curstate.next_states():
if not state.to_string() in seen_states:
dq.append(state)

Inadvertently using the name of a module as a variable seems to be
causing this.

In any case, this shouldn't cause issues with constructors, so I'd
call this a bug..

Ed
-- 
http://mail.python.org/mailman/listinfo/python-list


importing fully qualified scripts to check syntax

2009-08-07 Thread horos11
hey all,

I'm trying to make a syntax checker, where I say:

python -c import /path/to/script

to check the syntax of the script named '/path/to/script' (note: no py
extension needed). Of course this doesn't work because the
functionality for import is bundled up with the environment..

So - is there any simple, generic way in python to import a python
file without worrying about naming convention or environment? Sort of
like require in perl?

Ed

-- 
http://mail.python.org/mailman/listinfo/python-list


syntax checker in python

2009-08-07 Thread horos11
ps - I just realized that it isn't enough to do:

python -c 'import /path/to/script'

since that actually executes any statement inside of the script
(wheras all I want to do is check syntax)

So - let me reprhase that - exactly how can you do a syntax check in
python? Something like perl's -c:

 perl -c script_name.p

Ed
-- 
http://mail.python.org/mailman/listinfo/python-list