Re: #define (from C) in Python

2009-11-15 Thread Santiago Romero
> Python IS slower than perl, especially since you are dealing with
> objects. However, I'd suggest go the cPickle route - have a Z80Cpu
> module, and its C equivalent, cZ80, and use that one if available. This
> way, the emulator will be actually usable everywhere.

 Thanks for the advice but ... my (currently working) emulator is
already written in C, I don't see the point of calling it from a
python module. I had 2 options: port the emulator from C+Allegro to C
+SDL or port it to Python+Pygame+SDL...

 And the fun is trying to write it in pure python with pygame, without
external C :-)

 I'll do a quick test, if I see that I can't achieve 100% speed in my
other computer (DualCore2 1.82Ghz, the basic-standard-minimum computer
nowadays), then I'll give up, but at least I want to try it X-D

 Today or tomorrow I'm finishing the pyinliner.py preprocessor X-D.
I'll paste the results here :-)

 Thanks for your answer :-)
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: #define (from C) in Python

2009-11-13 Thread Santiago Romero
> Hey, I got 100% with ASM ZX Spectrum emulator on a low end 386 :-) (I do
> not remember the CPU freqeuncy anymore, maybe 25MHz).

 Yes, in ASM a simple 25 or 33Mhz 386 computer was able to emulate
the
Spectrum. At least, under MSDOS, like did Warajevo, Z80, x128 and
"Spectrum"
from Pedro Gimeno.

> First emulator in C that appeared on the emu-scene (I guess it
> was x128) needed 486 (~80MHz?) to run at realtime. Pentium and
> Pentium II was A LOT of  power :-)

 x128 was not pure C. The first emulator written in pure C was
Aspectrum,
although Philip Kendall "finished" FUSE (Free UNIX Spectrum Emulator)
before my emulator was able to emulate 128K models.

 But currently only FUSE and ASpectrum can be compiled in lost of
platforms
(Wii, Dreamcast, PocketPC, NDS...) just by translating the O.S.
dependent
functions or if the destination platform supports the Allegro
library...

 And at least a P1-P2 is needed for that :-)

> http://perl-spectrum.sourceforge.net/
>
> It is quite fast IMHO.

 It does not run 100% in my 1.8Ghz centrino computer :-(, but almost.
At least, is a good start to see that is possible, at least no current
DualCore computers :-)

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


Re: #define (from C) in Python

2009-11-13 Thread Santiago Romero

> > #define STORE_nn_rr(dreg) \
> >                         r_opl = Z80ReadMem(r_PC); r_PC++;\
> >                         r_oph = Z80ReadMem(r_PC); r_PC++; \
> >                         r_tmp = dreg; \
> >                         Z80WriteMem((r_op),r_tmpl, regs); \
> >                         Z80WriteMem((r_op+1),r_tmph, regs)
>
> Someone writing such code and calling it C should be taken
> behind the barn and shot.

 That code is mine and maybe you should look the context
before doing such kind of affirmations.

 In the Intel Pentium and P-II ages, I started to wrote the
very first Spectrum emulator in C. With that "cpu power", emulators
had to be written in ASM to be capable to emulate the destination
machines at 100% full speed in multitasking systems.

 In the emulation world, every CPU cycle you can save is gold,
and writing the above code as inline code saved lots of CALLS,
PUSHs/POPs (parameters to stack), and RETs. That allowed ASpectrum
to run 100% speed on old computers and even to be ported to the
Sega Dreamcast's 200Mhz CPU.

 Think that Z80ReadMem() can be called up to 6 times in each
emulated CPU-cycle. Saving 6 CALLs, 6 PUSHes, 6 POPs, and 6 RETs
in each cycle of the 3.500.000 of Hz **did** make the difference
that allow Aspectrum to run at 100% speed in ancient machines.

 Obviously, I prefer to write well structured code but I had to
sacrifize SIZE by SPEED (size as inline code is included in the
binary executable file).

 Each coding technique has their application environment and using
inline macros, like loop unrolling or using "register" variables
fall bellow all the techniques needed to write a fast emulator.

 Now I'm porting the emulator to a scripted language, so I need
even more previous design ideas before starting to code, so that
I can achieve (I hope I'll be able to do it with this group's help)
100% cpu speed in an standard desktop PC.

> >  But it seems that is not possible :-(
>
> Thank getenv("DEITY") not!

 Well, I don't agree with that, "constants" and "macros" wouldn't
hurt python, when using them in the right situations.

 Thanks a lot anyway for all your help :-)

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


Re: Writing an emulator in python - implementation questions (for performance)

2009-11-13 Thread Santiago Romero

 I'm going to quote all the answers in a single post, if you all don't
mind:

> [greg]
> But keep in mind that named "constants" at the module level
> are really global variables, and therefore incur a dictionary
> lookup every time they're used.
>
> For maximum speed, nothing beats writing the numeric literals
> directly into the code, unfortunately.

 So, finally, there are not constants available in python? (Like:)

#define  R1   1


> Generally, I think you're going to have quite a battle on
> your hands to get a pure Python implementation to run as
> fast as a real Z80, if it's even possible at all.

 Well... I'm trying to emulate the basic Z80, clocked at 3.5Mhz..
I hope python in a 2Ghz computer can emulate a 3.5Mhz machine ...

 Finally, if it's not possible... well, then I would just
have some fun... :-)



> [Steven D'Aprano]
> The shift and mask are a little faster on my machine, but that's
> certainly what I would call a micro-optimization. Unless the divmod call
> is the bottleneck in your code -- and it almost certainly won't be --

 It can be a real bottleneck.

 An emulator executes continously machine code instructions.
Those machine code instructions are read from memory, and operands are
read from memory too. The minimum opcode (00h -> NOP) requires 1
memory read, and the CPU task is read from mem & decode & execute.

 My problem is that I would need to "encapsulate" Memory reads and
Memory Writes in functions. In C I use #define so that:

 - No function call is done (¿code unrolling?)
 - I can "call" my function so I don't have to manually repeat my code
 - I can optimize my "#define" macro just once and all the "calls" are
   optimized too.

 This way (in C) I can write readable code and the compiler replaces
my
"readable macros" with the final code.

> I don't think it's worth the obfuscation to use shift/mask.

 An idea.

 I think I'm going to write a layer previous to my python program, to
allow to use macros in my emulator, and generate the final .py program
with a script.

 VERY SIMPLE EXAMPLE:

My program:

File emulator.pym:

==
#!/usr/bin/python
import blah
import sys

MACRO BEGIN Z80WriteMem( address, value )
  blablablah
  inc blah
  p = p + x
MACRO END

MACRO BEGIN Z80ReadMem( address )
  ( memory[address>>4][blah] )
MACRO END


(more code)

pepe = @@@Z80ReadMem( reg_A )
(more code)
@@@Z80WriteMem( 0x121212, value )
==

 And then, use a script to replace macro calls @@@ by the
final code.

 This way I could write my emulator with "macros" and
my "preprocessor" would rewrite the final .py files
for the "binary" releases. While I can keep the .pym
files as the "real" source (because .py files would be
generated from .pym macro-files).

 Can the above be easily done with another already-existing
application? (example: can m4 do this job)?
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Writing an emulator in python - implementation questions (for performance)

2009-11-13 Thread Santiago Romero

> How about
>     page, index = divmod(address, 16384)

 Surely, much better and faster :-)

 Thanks a lot.

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


Re: Writing an emulator in python - implementation questions (for performance)

2009-11-12 Thread Santiago Romero

 Oops, numpy arrays start with index=0 :-)


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


Re: Writing an emulator in python - implementation questions (for performance)

2009-11-12 Thread Santiago Romero
> You can do clever memory slicing like this with numpy.  For instance:
>
> breg = numpy.zeros((16,),numpy.uint8)
> wreg = numpy.ndarray((8,),numpy.uint16,breg)
>
> This causes breg and wreg to share the same 16 bytes of memory.  You
> can define constants to access specific registers:

 What I'm doing wrong?

[srom...@compiler:~]$ cat test.py
#!/usr/bin/python

import numpy

# Register array
breg = numpy.zeros((16,),numpy.uint8)
wreg = numpy.ndarray((8,), numpy.uint16, breg )

reg_A   = 1
reg_F   = 2
reg_AF  = 1
reg_B   = 3
reg_C   = 4
reg_BC  = 3

breg[reg_B] = 5
breg[reg_C] = 10
print breg[reg_B]
print breg[reg_C]
print wreg[reg_BC]


[srom...@compiler:~]$ python test.py
5
10
0

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


Re: #define (from C) in Python

2009-11-12 Thread Santiago Romero
On 12 nov, 18:16, Stefan Behnel  wrote:
> Santiago Romero, 12.11.2009 17:43:
>
> > Is there a Python version of C's language #define statements?
>
> > Example:
>
> > #define ReadMem( (x) )    memory[ (x) ]
>
> Yes:
>
>         ReadMem = memory.__getitem__
>
> Stefan


 Well, In the above concrete example, that would work, but I was
talking for multiple code lines, like:


#define LD_r_n(reg) (reg) = Z80ReadMem(r_PC++)

#define LD_rr_nn(reg)   r_opl = Z80ReadMem(r_PC); r_PC++; \
r_oph = Z80ReadMem(r_PC); r_PC++; \
reg = r_op

#define LOAD_r(dreg, saddreg)   (dreg)=Z80ReadMem((saddreg))

#define LOAD_rr_nn(dreg)   r_opl = Z80ReadMem(r_PC); r_PC++; \
   r_oph = Z80ReadMem(r_PC); r_PC++; \
   r_tmpl = Z80ReadMem(r_op); \
   r_tmph = Z80ReadMem((r_op)+1); \
   dreg=r_tmp

#define STORE_nn_rr(dreg) \
r_opl = Z80ReadMem(r_PC); r_PC++;\
r_oph = Z80ReadMem(r_PC); r_PC++; \
r_tmp = dreg; \
Z80WriteMem((r_op),r_tmpl, regs); \
Z80WriteMem((r_op+1),r_tmph, regs)


 But it seems that is not possible :-(
-- 
http://mail.python.org/mailman/listinfo/python-list


#define (from C) in Python

2009-11-12 Thread Santiago Romero

Is there a Python version of C's language #define statements?

Example:

#define ReadMem( (x) )memory[ (x) ]

 Instead of using a function, when you call to ReadMem(), the code is
INCLUDED, (no function is called, the "compiler" just substitues the
ReadMem( expression ) with memory[ (expression) ] .

 I want to avoid function calls to speed up a program by sacrifizing
the resulting size ...

 Is that possible?
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Writing an emulator in python - implementation questions (for performance)

2009-11-12 Thread Santiago Romero
> >  I'm trying to port (just for fun), my old Sinclair Spectrum emulator,
> > ASpectrum, from C to Python + pygame.
>
> The answer to your question is, "Use numpy".  More details below.

 Let's see :-)

> >  How can I implement this in Python, I mean, define a 16 byte variable
> > so that high and low bytes can be accessed separately and changing W,
> > H or L affects the entire variable? I would like to avoid doing BIT
> > masks to get or change HIGH or LOW parts of a variable and let the
> > compiled code to do it by itself.
>
> You can do clever memory slicing like this with numpy.  For instance:
>
> breg = numpy.zeros((16,),numpy.uint8)
> wreg = numpy.ndarray((8,),numpy.uint16,breg)
>
> This causes breg and wreg to share the same 16 bytes of memory.  You
> can define constants to access specific registers:
>
> R1L = 1
> R1H = 2
> R1 = 1
>
> breg[R1H] = 2
> print wreg[R1]

 And how about speed?

Assuming a 16 bit register named BC which contains 2 8 bit regiters (B
and C)...

 Will the above be faster than shifts and bit operations (<<, and,
>> ) with new B and C values to "recalculate" BC when reading or
changing either B, C or BC?

> >  Is python's array module the best (and fastest) implementation to
> > "emulate" the memory?
>
> I'd use numpy for this as well.  (I doubt the Z80 had a 16-bit bus,
> but if it did you could use the same memory sharing trick I showed you
> with the registers to simulate word reads and writes.)

 Z80 has a 16 bit ADDRESS bus, 8 bit DATA bus. This means you can
address from 0 to 65535 memory cells of 8 bytes. Z80 has 16 bit bus
operations, but currently in C I write 16 bit values as two 8 bit
consecutive values without using (unsigned short *) pointers. But it
seems that numpy would allow me to do it better than C in this case...

> Note that, when performing operations on single values, neither numpy
> nor array module are necessarily a lot faster than Python lists, might
> even be slower.  But they use a LOT less memory, which is important
> for largish arrays.

 Well, we're talking about a 128KB 1-byte array, that's the maximum
memory size a Sinclair Spectrum can have, and always by using page
swapping of 16KB blocks in a 64KB addressable space...

 If you really think that python lists can be faster that numpy or
array modules, let me know.

 Maybe I'll make a "benchmark test", by making some millions of read /
write operations and timing the results.

 I wan't to write the emulator as "pythonic" as possible...

> >  I don't know how to emulate paging in python...
>
> numpy again.  This would mean you'd have to fiddle with addresses a
> bit, but that shouldn't be too big a deal.  Create the physical
> memory:
>
> mem = numpy.zeros((128*1024,),numpy.uint8)

 A 128K array of zeroes...

> Then create the pages.  (This is a regular Python list containing
> numpy slices. numpy slices share memory so there is no copying of
> underlying data.)
>
> page = [mem[0:16*1024],
>         mem[16*1024:32*1024],
>         mem[32*1024:48*1024],
>         mem[48*1024:64*1024]]

 Those are just like pointers to the "mem" numpy array, pointing to
concrete start indexes, aren't they?

> To access the byte at address 42432, you'd have use bit operations to
> get a page number and index (2 and 9664 in this case), then you can
> access the memory like this:

 Do you mean:

page = address / 16384
index = address MOD 16384

 ?

 Or, better, with:

  page = address >> 14
  index = address & 16383

 ?


> page[2][9664] = 33
> p = page[3][99]
>
> To swap a page, reassign the slice of main memory,
>
> page[2] = mem[96*1024:112*1024]
>
> Now, accessing address 42432 will access a byte from a different page.

 But the above calculations (page, index) wouldn't be slower than a
simple play 64KB numpy array (and make no paging mechanism when
reading or writing) and copy memory slices when page swappings are
requested?

> If you don't want to fiddle with indirect pages and would just rather
> copy memory around when a page swap occurs, you can do that, too.
> (Assigning to a slice copies the data rather than shares.)  I don't
> know if it's as fast as memset but it should be pretty quick.

 That's what I was talking about.
 With "page and index" I'm slowing down EACH memory read and write,
and that includes opcode and data fetching...

 With "memory copying in page swaps", memory is always read and write
quickly, and if "slice copies" are fast enough, the emulation will be
>100% of speed (I hope) for a 3.5Mhz system ...

> Hope these brief suggestions help.  If you don't want third party
> libraries, then numpy will be of no use.  But I guess if you're using
> pygame third party modules are ok.  So get numpy, it'll make things a
> lot easier.  It can be a bit daunting to learn, though.

 Yes, you've been very helpful!

 How about numpy portability? Is array more portable?

 And finally, do you think I'm doing right by using global variables
for registers, memory, and so, or should I put ALL into

Writing an emulator in python - implementation questions (for performance)

2009-11-12 Thread Santiago Romero

 Hi.

 I'm trying to port (just for fun), my old Sinclair Spectrum emulator,
ASpectrum, from C to Python + pygame.

 Although the Sinclair Spectrum has a simple Z80 8 bit 3.5Mhz
microprocessor, and no aditional hardware (excluding the +2/+3 model's
AYsound chip), I'm not sure if my loved scripted language, python,
will be fast enought to emulate the Sinclair Spectrum at 100% speed.
There are Java Spectrum emulators available, so it should be possible.

 Anyway, this message is directed to prepare the DESIGN so that the
code can run as fast as possible. I mean, I want to know the best way
to do some emulation tasks before starting to write a single line of
code.

 My questions:


 GLOBAL VARIABLES VS OBJECTS:
==

 I need the emulation to be as fastest as possible. In my C program I
have an struct called "Z80_Processor" that contains all the registers,
memory structures, and so on. I pass that struct to the Z80Decode(),
Z80Execute() or Z80Dissassemble() functions, i.e.. This allows me (in
my C emulator) to emulate multiple z80 processors If I want.

 As Python is scripted and I imagine that emulation will be slower
than the emulator written in C, I've thought of not creating a
Z80_Processor *object* and declare global variables such as reg_A,
reg_B, reg_PC, array main_memory[] and so on, and let the z80
functions to directly access that global variables.

 I'm doing this to avoid OOP's extra processing... but this makes the
program less modular. Do you think using processor "objects" would
make the execution slower, or I'm doing right using global variables
and avoiding objects in this type of program?

 Should I start writing all the code with a Z80CPU object and if
performance is low, just remove the "object" layer and declare it as
globals, or I should go directly for globals?



 HIGH AND LOW PART OF REGISTERS:
=

- In C, I have the following structs and code for emulating registers:

typedef union
{
  struct
  {
unsigned char l, h;
  } B;

  unsigned short W;
} eword;

eword reg_A;

 This means that reg_A is a 16 bit "variable" that I can directly
access with reg_A.w=value, and I can access also the LOW BYTE and HIGH
BYTES with reg_A.B.h and reg_A.B.l. And more importante, changing W
modifies l and h, and changing l or h modifies W.

 How can I implement this in Python, I mean, define a 16 byte variable
so that high and low bytes can be accessed separately and changing W,
H or L affects the entire variable? I would like to avoid doing BIT
masks to get or change HIGH or LOW parts of a variable and let the
compiled code to do it by itself.

 I know I can write an "object" with set and get methods that
implement that (that could be done in C too), but for emulation, I
need the FASTEST implementation possible (something like the C's Union
trick).


 MEMORY (ARRAYS):
===

 To emulate Spectrum's memory in C, I have a 64KB array like: unsigned
char memory_array[65535]. Then I can access memory_array[reg_PC] to
fetch the next opcode (or data for an opcode) and just increment
reg_PC.

 Is python's array module the best (and fastest) implementation to
"emulate" the memory?


 MEMORY (PAGES):
=

 The Sinclair Spectrum 8 bit computer can address 64KB of memory and
that memory is based on 16KB pages (so it can see 4 pages
simultaneously, where page 0 is always ROM). Programs can change
"pages" to point to aditional 16KB pages in 128KB memory models.

 I don't know how to emulate paging in python...

 My first approach would be to have eight 16KB arrays, and "memcpy()"
memory to the main 64KB array when the user calls page swapping. I
mean (C + pseudocode):


 main_memory[65536];
 memory_blocks[8][16384];

 // Initial settings
 current_pages[4] = [0, 1, 2, 3]

 // User swaps last memory page (3) to block 7, so I:
 page_to_swap_from = 3
 page_to_map = 7

 // Save the contents of current page (page being unmapped):
 memcpy( main_memory, // Source
 16384*page_to_swap_from, // Starting
at
 memory_blocks[current_pages[page_to_swap_from],  // To
 16384 ); // 16K

 // Now map page 7 to memory block 3:
 memcpy( memory_blocks[page_to_map],  // Source
 0,   // Starting
at
 main_memory[page_to_swap_from*16384],// To
 16384 ); // 16K
 current_pages[page_to_swap_from] = page_to_map;



 Memcpy is very fast in C, but I don't know if doing the same in
python with arrays would be fast enough, or if there is a better
approach to simulate paging of 16KB blocks in a 64KB memory windows (4
mappable memory blocks).

 Maybe another approach based in pointers or something like that?

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


Re: Read binary file and dump data in

2009-01-14 Thread Santiago Romero

> If you are reading arbitrary bytes then it will likely not always "look"
> like integers. What you probably meant is:
>
> for i in data:
>    print "%d, " % ord(i)

 That's it! :-)

 Thanks a lot.
--
http://mail.python.org/mailman/listinfo/python-list


Read binary file and dump data in

2009-01-13 Thread Santiago Romero

 Hi.

 Until now, all my python programs worked with text files. But now I'm
porting an small old C program I wrote lot of years ago to python and
I'm having problems with datatypes (I think).

 some C code:

 fp = fopen( file, "rb");
 while !feof(fp)
 {
value = fgetc(fp);
printf("%d", value );
 }

 I started writing:

 fp = open(file, "rb")
 data = fp.read()
 for i in data:
   print "%d, " % (int(i))

 But it complains about i not being an integer... . len(data) shows
exactly the file size, so maybe is a "type cast" problem... :-?

 What's the right way to work with the binary data (read 1 byte values
and work with them, dumping them as an integer in this case)?

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


Re: How to ignore the first line of the text read from a file

2008-08-28 Thread Santiago Romero
> I want to read text line-by-line from a text file, but want to ignore
> only the first line. I know how to do it in Java (Java has been my
> primary language for the last couple of years) and following is what I
> have in Python, but I don't like it and want to learn the better way
> of doing it.

 Why don't you read and discard the first line before processing the
rest of the file?

 file = open(filename, 'r')
 file.readline()
 for line in file: print line,

 (It works).
--
http://mail.python.org/mailman/listinfo/python-list


Re: What Python looks like

2008-08-05 Thread Santiago Romero

> I'm curious, what did Python code look like to those of you who have
> seen a bunch of Python code for the first time before k

 Clean and readable.
--
http://mail.python.org/mailman/listinfo/python-list


Re: How to access object attributes given a string

2008-02-14 Thread Santiago Romero
> >> You are using a scripting language.. why not use python directly?
>
> > I just want to execute an small set of commands (PLAYSOUND, PLAYMUSIC,
> > WALKTO, PLAYERSAY, SLEEP and a couple more) ... do you think I can
> > write python code inside my object.exec (list attribute) loaded from a
> > file?
>
> Something like that.
>
> Build a dictionary -that will be used as the script global namespace-
> (...)
>
> Warning: this is unsafe!!!. Malicious users could execute arbitrary code;
> although this may not be an issue if the game runs on the user's own
> system.
>
> The advantage is that you let them use all the power of Python as a
> scripting language.

 That's why I was trying to write my own "small" scripting
language :-).

 It works, but I would like to know how to write it better or safer.
That's why I posted the source code.

 Thanks.

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


Re: How to access object attributes given a string

2008-02-12 Thread Santiago Romero

 This is faster:

http://www.sromero.org/python/zx_parseexec.py
http://www.sromero.org/python/test.par

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


Re: How to access object attributes given a string

2008-02-12 Thread Santiago Romero

 And the rest of the code:


#
def ExecParser_Exec( exec_type, code, game, debug=0 ):
   """
   Execute the previously "compiled" code:
   """
   code_level = 0

   #player = game.player
   #world = game.world

   # Take only opcodes for EXEC or EXEC2, deppending on exec_type
   exec_code = filter( lambda x : x[0] == exec_type, code )

   i = -1
   while 1:

  i += 1
  cmd_level, cmd, params = exec_code[i][1:4]
  spaces = " "*((code_level+1)*3)

  # End of script (appended by the compiler)


  if code_level == cmd_level:
 if cmd.startswith("IF ") or cmd.startswith("ELIF "):
# Get boolean funtion and evaluate it
# IF true:
#remove all ELIF/ELSE blocks until next ENDIF at the
same code level
#increase codelevel
# IF false:
#remove all code until next ELIF/ELSE/ENDIF at the
same code level
booleanf = cmd.split(" ")[1]
if debug: print "Checking ", spaces, cmd, params,
" (returned",
if ExecParser_CheckBoolean(booleanf, params):
   if debug: print "TRUE)"
   # Ignore lines until we find an ENDIF at the same code
level:
   done = 0
   j = i

   # Ignore all lines until we found the same code level
(next ELIF/ELSE/ENDIF):
   while not done:
  j += 1
  next_cmd_level, next_cmd = exec_code[j][1:3]
  if next_cmd_level==cmd_level or
next_cmd.startswith("END"):
 done = 1

   nextcond_line = j
   # Next branch is an endif, do nothing:
   if exec_code[nextcond_line][2].startswith("ENDIF") or \
  exec_code[nextcond_line][2] == "END":
  pass
   # Next branch is ELIF or ELSE: delete all until ENDIF
+cmd_level found
   else:
  done = 0
  while not done:
 if exec_code[nextcond_line]
[2].startswith("ENDIF") or \
exec_code[nextcond_line][2] == "END":
done = 1
 else:
del exec_code[nextcond_line]

   #  - Endif -> stop here
   code_level += 1
   i -= 1
else:
   if debug: print "FALSE)"
   done = 0
   # Ignore all lines in the current
   while not done:
  i += 1
  next_cmd_level, next_cmd = exec_code[i][1:3]
  if (next_cmd.startswith("ELIF ") or
next_cmd.startswith("ELSE")):
 i -= 1
 done = 1
  elif next_cmd.startswith("ENDIF") and
(next_cmd_level == code_level):
 done = 1
continue

  if cmd.startswith("ELSE") and cmd_level != -1:
 if debug: print "Entering ", spaces, "ELSE"
 code_level += 1

  elif cmd.startswith("ENDIF") and cmd_level != -1:
 if code_level > 0: code_level -= 1

  else:
 if code_level == cmd_level:
if cmd == "END":
   if debug: print "Executing", spaces, cmd
   return 1
else:
   if debug: print "Executing", " "*((code_level+1)*3),
cmd, params
   ExecParser_ExecOpcode( cmd, params, game, debug )
   return 1



#
def ExecParser_PrintCode( code, formatted=0 ):
   """
   Print code compiled/parsed by ExecParser_Parse().

   Prints opcodes (formatted=0) or indented source code (formatted=1)
   from a previously compiled/parsed opcode list.
   """

   if not formatted:
  # Print opcodes:
  print "\n> Compiled opcodes: <"
  print "\nExecType  CodeLevel  Opcode"
  print
"--"
  for c in code:
 print "%-8s %-8s" % (c[0],c[1]),
 for f in c[2:]:
if f != []: print f,
 print

   else:
  # Display source code indented
  print "\n> Formatted code (parsing opcodes): <"
  print "\nMain:"
  for i in code:
 spaces = " " * 3*(1+i[1])
 func = i[2]
 params = [ str(x) for x in i[3] ]
 if func == "REM":
print "%s%s %s" % (spaces, func, i[3][0])
 else:
if params != []:
   print "%s%s(" % (spaces, func),
   for i,p in enumerate(params):
  if i == len(params)-1: print "%s )" % (p)
  else:  print "%s," % (p),
else   :
   print "%s%s" % (spaces, func)



 That's all. I can put the .py and test.par files online if anyone
wants to test it and point me to the right direction on "how to code
your own small scripting language written in python scriptin

Re: How to access object attributes given a string

2008-02-12 Thread Santiago Romero

 And the big functions:

 I imagine that the following is HORRIBLE in the pythonic-vision and
surely can be rewriten with a single map+reduce+filter + 200 lambdas
functions X-D, but I come from C and any advice on how to implement my
"simple scripting language" without using lex or yacc is welcome :)



#
def ExecParser_Parse( key, value, line, file ):
   """
   Parses an exec or exec2 line, generating a list of "opcodes".

   This function takes an exec= line from a OBJ file and parses it
   generating a list of "executable opcodes" in a format executable
   by ExecParser_Exec().

   The rules for this "small" language are:
   - Spaces and tabs are stripped.
   - Comments (starting by REM) are ignored.
   - A simple set of commands is available. Those commands modify
 some game variables or objects. As an example: PLAYSOUND(snd),
 plays the sound identified by the sound_tag "snd".
   - Commands must be separated by ";" characters.
   - Commands can receive parameters enclosed between ( and ) of
 types INT or STR.
   - Programmer can use "self" to refer to the current object in
 functions that accept an object or enemy text id.
   - Simple control flow is present with IF, ELIF, ELSE and ENDIF
 statements.
   - IF and ELIF statemens are followed by a BOOLEAN command, which
 will return 0 or 1.

   Example ('\' character wraps lines in the OBJ file):

  KILLOBJECT(coin);\
  REM Wait 5 seconds;\
  IF FLAG(5);\
 SLEEP(5);\
 PLAYERSAY(test,5);\
 SETMAP(10,10,top,5);\
 IF FLAG(6);\
NOP();\
SLEEP(7);\
 ELIF FLAG(7);\
NOP();\
SLEEP(9);\
 ELSE;\
SLEEP(999);\
 ENDIF;\
 IF FLAG_VALUE(7,1);\
CHANGESCREEN(start,10,100);\
PLAYERFACING(0);\
 ENDIF;\
  ENDIF;\
  SLEEP(12);\
  SLEEP(11);

   This function will parse the exec line and produce as output
opcodes in
   this format:

   [ type_of_exec, if_level, opcode, parameters ]

   type_of_exec = 1 for exec= lines, and 2 for exec2= lines.
   if_level is the current code "level" or scope. IF statements
increase
if_level and ENDIF statements decrease it.
   opcode and parameters are the function_name and the params for this
command.

   Example:

 ExecType  CodeLevel  Opcode and params
  --
  10KILLOBJECT ['coin']
  00REM ['Wait 5 seconds']
  10IF FLAG [5]
  11SLEEP [5]
  11PLAYERSAY ['test', 5]
  11SETMAP [10, 10, 'top', 5]
  11IF FLAG [6]
  12NOP
  12SLEEP [7]
  11ENDIF
  10ENDIF
  10END


   The function makes some small checkings, like:
count(IF)==count(ENDIFs),
   check number of arguments, argument type checking, validate command
   functions, and some others, but it does not cover all possible
syntax
   errors or typing mistakes.
   """

   reserved_words = {
   "SETMAP" : ( 4, "int", "int", "str", "int" ),
   "KILLOBJECT" : ( 1, "str" ),
   "ENABLEOBJECT" : ( 1, "str" ),
   "DISABLEOBJECT" : ( 1, "str" ),
   "PLAYSOUND" : ( 1, "str" ),
   "PLAYMUSIC" : ( 1, "str" ),
   "SLEEPCYCLES" : ( 1, "int" ),
   "SLEEP" : ( 1, "int" ),
   "SHOWTEXT" : ( 1, "str" ),
   "SHOWTEXTTIMED" : ( 2, "str", "int" ),
   "SHOWSCREEN" : ( 2, "str", "int" ),
   "CHANGESCREEN" : ( 3, "str", "int", "int" ),
   "ADDINVENTORY" : ( 1, "str" ),
   "REMOVEINVENTORY" : ( 1, "str" ),
   "OBJECTFACING" : ( 2, "str", "int" ),
   "PLAYERFACING" : ( 1, "int" ),
   "PLAYERSAY" : ( 2, "str", "int" ),
   "OBJECTSAY" : ( 3, "str", "str", "int" ),
   "SETFLAG" : (2, "int", "int" ),
   "INCFLAG" : (1, "int" ),
   "DECFLAG" : (1, "int" ),
   "DELEXEC" : (1, "int" ),
   "REM" : ( 0, ),
   "NOP" : ( 0, ),
   "END" : ( 0, ),
   "TRUE" : ( 0, ),
   "FALSE" : ( 0, ),
   "IF" : ( 0, ),
   "ELIF" : ( 0, ),
   "ELSE" : ( 0, ),
   "ENDIF" : ( 0, ),
   "FLAG" : ( 1, "int" ),
   "NOT_FLAG" : ( 1, "int" ),
   "FLAG_VALUE" : ( 2, "int", "int" ),
   "PLAYER_HAS" : ( 1, "str" ),
   "PLAYER_HAS_NOT" : ( 1, "str" ),
   "SCREEN_IS" : ( 1, "str" ),
   "SCREEN_IS_NOT" : ( 1, "str" )
   }


   #input is something like: "exec=COMMAND;COMMAND;COMMAND..."

   if key.upper() == "EXEC":  exec_type = 1
   code = []  # Resulting code

   if ";" in value:  commands = value.split(";")
   else: commands = list( value )

   # Filter empty lines
   commands = filter( lambda x: len(x) > 1, commands )

   code_level = level_inc = 0 # Current scope level
   found_if = found_elif = 0

   # Parse all commands in the input script
   for cmd_counter, cmd in enumerate(commands):

  if cmd == '': continue
  

Re: How to access object attributes given a string

2008-02-12 Thread Santiago Romero

 Before I reinvent the wheel, I'm going to post the code.

 Feel free to give any advice, and think that I'm new to python, it's
only 1 month since I began programming in python "seriously" (up to
that moment, I wrote just a few log-text parsing system administration
scripts to speed up some old bash scripts).

 First of all, my currently test file:

KILLOBJECT(coin);\
REM Wait 5 seconds;\
IF FLAG(5);\
   SLEEP(5);\
   PLAYERSAY(test,5);\
   SETMAP(10,10,top,5);\
   IF FLAG(6);\
  NOP();\
  SLEEP(7);\
   ELIF FLAG(7);\
  NOP();\
  SLEEP(9);\
   ELSE;\
  SLEEP(999);\
   ENDIF;\
   IF FLAG_VALUE(7,1);\
  CHANGESCREEN(start,10,100);\
  PLAYERFACING(0);\
   ELSE;\
  PLAYERFACING(1);\
   ENDIF;\
ENDIF;\
SLEEP(12);\
SLEEP(11)

 And the parse code:


if __name__ == "__main__":
   """
   To test: create an example file test.par with language commands.
   """

   numline = 0
   try:
  fp = open("test.par")
   except:
  print "Error, cant open test.par"
  import sys
  sys.exit(0)

   while 1:
  # Read line, ignore comments and stop with EOF
  numline += 1
  line = fp.readline()
  if line == '': break

  line = line.strip()
  startline = numline
  # Join lines splitted with \ in the text file
  while line.endswith("\\"):
 next_line = fp.readline()
 if next_line == '': break
 if next_line.strip() == '': continue
 numline += 1
 next_line = next_line.strip()
 line = line[:-1] + next_line

  code = ExecParser_Parse( "exec", line, startline, "test.par" )

   for i in 0, 1:
  ExecParser_PrintCode( code, i )
  print
   ExecParser_Exec( 1, code, 0, debug=1 )


 And this is the output:

> Compiled opcodes: <

ExecType  CodeLevel  Opcode
--
10KILLOBJECT ['coin']
00REM ['Wait 5 seconds']
10IF FLAG [5]
11SLEEP [5]
11PLAYERSAY ['test', 5]
11SETMAP [10, 10, 'top', 5]
11IF FLAG [6]
12NOP
12SLEEP [7]
11ELIF FLAG [7]
12NOP
12SLEEP [9]
11ELSE
12SLEEP [999]
11ENDIF
11IF FLAG_VALUE [7, 1]
12CHANGESCREEN ['start', 10, 100]
12PLAYERFACING [0]
11ELSE
12PLAYERFACING [1]
11ENDIF
10ENDIF
10SLEEP [12]
10SLEEP [11]
10END


> Formatted code (parsing opcodes): <

Main:
   KILLOBJECT( coin )
   REM Wait 5 seconds
   IF FLAG( 5 )
  SLEEP( 5 )
  PLAYERSAY( test, 5 )
  SETMAP( 10, 10, top, 5 )
  IF FLAG( 6 )
 NOP
 SLEEP( 7 )
  ELIF FLAG( 7 )
 NOP
 SLEEP( 9 )
  ELSE
 SLEEP( 999 )
  ENDIF
  IF FLAG_VALUE( 7, 1 )
 CHANGESCREEN( start, 10, 100 )
 PLAYERFACING( 0 )
  ELSE
 PLAYERFACING( 1 )
  ENDIF
   ENDIF
   SLEEP( 12 )
   SLEEP( 11 )
   END

Executing KILLOBJECT ['coin']
Checking  IF FLAG [5]  (returned TRUE)
ExecutingSLEEP [5]
ExecutingPLAYERSAY ['test', 5]
ExecutingSETMAP [10, 10, 'top', 5]
Checking IF FLAG [6]  (returned FALSE)
Checking ELIF FLAG [7]  (returned FALSE)
Entering ELSE
Executing   SLEEP [999]
Checking IF FLAG_VALUE [7, 1]  (returned FALSE)
Entering ELSE
Executing   PLAYERFACING [1]
Executing SLEEP [12]
Executing SLEEP [11]
Executing END
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: How to access object attributes given a string

2008-02-12 Thread Santiago Romero
> > def ChangeAttribute( object, attribute, value ):
>help(setattr)
>
> Help on built-in function setattr in module __builtin__:
>
> setattr(...) setattr(object, name, value)
>
> Set a named attribute on an object; setattr(x, 'y', v) is
> equivalent to`x.y = v''.

and

> Gary Herron write:
> You want getattr and setattr:

 Thanks a lot, that's what I was looking for.

> Dennis Kempin wrote:
> You are using a scripting language.. why not use python directly?

 Well, I have a .OBJ with something like:

# exec is the code executed when the player gets the object
ADDOBJECT:coin:x=10:y=10:screen=200:exec=\
   SETMAP(10,10,1);\
   SLEEP(1);\
   PLAYSOUND(get_coin);\
   IF FLAG(10);\
  SETLOOKING(left);\
  PLAYERSAY(blah);\
  SLEEP(2);\
   ELSE;\
  PLAYERSAY(blahblah);\
  SLEEP(3);\
   ENDIF;\

 That's a simple example of the language I've wrote for my game. Now
it's being "compiled" nicely and it works.

I just want to execute an small set of commands (PLAYSOUND, PLAYMUSIC,
WALKTO, PLAYERSAY, SLEEP and a couple more) ... do you think I can
write python code inside my object.exec (list attribute) loaded from a
file?

 Currently I'm compiling the above in a ( scope_level, function,
parameters ) list:

object.exec = [
[ 0, "SETMAP", [10, 10, 1] ],
[ 0, "SLEEP", [1] ],
[ 0, "PLAYSOUND", ["get_coin"] ],
[ 0, "IF FLAG", [10] ],
[ 1, "SETLOOKING", ["left"] ],
(...) ]

 I make some checks (as many resulting opcodes as input commands,
check of IF/ELIF/ELSE/ENDIF statements to see if all are correct,
right parameter types (currently only integer or strings), right
parameter number, and so on.

 Do you mean that I can replace my "language" by just python (defining
SETMAP, SLEEP and all those functions somewhere in my main source
code).

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


How to access object attributes given a string

2008-02-12 Thread Santiago Romero
 Hi...

 I'm trying to guess how to access attributes of an existing object
given the attribute name in a string. I mean:

class Object:
self.x = 12
self.y = 20
self.name = "blah"

def ChangeAttribute( object, attribute, value ):
  # Insert here the code for object.attribute = value
  X

 Allowing this kind of calls:

 ChangeAttribute( object, "x", 200 )
 ChangeAttribute( object, "name", "my name" )

 Thanks.

PS: I need it for a concrete case in a game scripting language I'm
writing, so that I can call functions like "CHANGE_PLAYER_VALUES( "x",
100 )".
-- 
http://mail.python.org/mailman/listinfo/python-list


Why not a Python compiler?

2008-02-05 Thread Santiago Romero

 ( Surely if this question has been asked for a zillion of times... )
 ( and sorry for my english! )

 I'm impressed with python. I'm very happy with the language and I
find Python+Pygame a very powerful and productive way of writing 2D
games. I'm not, at this moment, worried about execution speed of the
small game I'm working on (it runs at full 60 fps even in an old AMD-
K6 450 Laptop computer), but I continue asking me the same question:

 Why not a Python COMPILER?

 It would be very nice to be able to output Linux, MAC or Windows
binaries of compiled (not bytecompiled) code. It would run faster, it
will be smaller in size (I think) and it will be easy to distribute to
people not having python installed. Yes, I know about py2exe, but I'm
not sure if that's the right aproach.

 So, what's wrong with compiling python?

 Maybe is not possible due to nature of the language? Is just a
decision?

 What do you think about this?
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Removal of element from list while traversing causes the next element to be skipped

2008-01-30 Thread Santiago Romero
On 30 ene, 08:09, Paul Rubin <http://[EMAIL PROTECTED]> wrote:
> Santiago  Romero <[EMAIL PROTECTED]> writes:
>
> > > >>> li = [1,2,3,4,5]
> > > >>> filter(lambda x: x != 3, li)
> > > [1, 2, 4, 5]
>
> >  I haven't measured it, but this should be the fast solution in all
> > the thread ...
>
> li.remove(3) is probably faster.

 But that only removes the first ocurrence of item==3.

 In  a = [1, 2, 3, 3, 3, 4, 3, 3, 2, 3], the filter solution will
efectively remove all items with value == 3 while li.remove(3) will
only remove the first ocurrence.

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


Re: Removal of element from list while traversing causes the next element to be skipped

2008-01-29 Thread Santiago Romero
> how about
>
> >>> li = [1,2,3,4,5]
> >>> filter(lambda x: x != 3, li)
> [1, 2, 4, 5]

 I haven't measured it, but this should be the fast solution in all
the thread ...

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


Re: Removal of element from list while traversing causes the next element to be skipped

2008-01-29 Thread Santiago Romero
> Look at this -- from Python 2.5.1:
>
> >>> a = [1, 2, 3, 4, 5]
> >>> for x in a:
> ... if x == 3:
> ... a.remove(x)
> ... print x

 Well ... you could use:

>>> for i in range(len(a)-1, -1, -1):
...print a[i]
...if a[i] == 3: del a[i]
...
5
4
3
2
1
>>> print a
[1, 2, 4, 5]


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


Re: Sorting a list depending of the indexes of another sorted list

2008-01-21 Thread Santiago Romero

 Thanks all for the answers ... I'll use a tuple as you said :)

 Anyway, is interesting to know how to sort 2 lists when you dont want
to use tuples, so thanks also to Peter :)

> Then one have to split the list twice.Given the list is large,it's maybe
> not good for performance.Is it a more effective split way?

 Well, I just use:

 rows = i.split(' ')
 a = rows[3]
 b = rows[5]

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


How to use py2exe ...

2008-01-20 Thread Santiago Romero

 Hi...

 I'm a Linux user, and I would like some windows-friends to test a
game I'm writing with python+pygame without they needing to install
python, pygame, and so on.

 I've heard about py2exe and pygame2exe, but I'm not sure on how to
use them to create:

a.- standalone exe files with a single .py program.
Example: myprogram.py

or

b.- exe files containing all my source code + data directories (png
files, data files, and so).
Example: main.py, doc/README, src/*.py and data/*


 The problem is I'm not sure on how to use py2exe and pygame2exe to
build the executables...

 And finally, a question: if I want to provide source code
separately ... can I include .pyc files instead of .py files?
-- 
http://mail.python.org/mailman/listinfo/python-list


Sorting a list depending of the indexes of another sorted list

2008-01-20 Thread Santiago Romero

 Hi ...

 I have the following DNS MX records info:

domain.com
preference 10 host mx1.domain.com
preference 30 host anotherhost.domain.com
preference 20 host mx2.domain.com

 I'm storing this info in 2 lists:

preferences = [10, 30, 20]
hosts = [ "mx1.domain.com", "anotherhost.domain.com",
"mx2.domain.com"]

 (I was about to use a dict of  preferences : domain, but it's
possible to find 2 mx records with the same preference, so keys
wouldnt be unique).

 I'm trying to sort both lists so that they end like this:

preferences = [10, 20, 30]
hosts = [ "mx1.domain.com", "mx2.domain.com",
"anotherhost.domain.com" ]

 I want to sort hosts list depending on the numeric order of
"preferences".


 And finally ... do you think there is a better python structure to
store this data and sort it in a more easy way?

 Thanks.

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


Re: Converting a bidimensional list in a bidimensional array

2008-01-11 Thread Santiago Romero
> > - Speed Performance: Do you think that changing from list to Array()
> > would improve speed? I'm going to do lots of tilemap[y][x] checks (I
> > mean, player jumping around the screen, checking if it's falling over
> > a non-zero tile, and so).

> First of all: if you have enough memory to use a python list, then I
> suggest you to use a list.
>
> Often python lists are faster than array.array (maybe because python
> lists actually contain pyobjects).


 My problem is that, in my game, each screen is 30x20, and I have
about 100 screens, so my tilemap contains 32*20*100 = 6 python
objects (integers).

 If each integer-python-object takes 16 bytes, this makes 6 * 16 =
almost 1MB of memory just for the tilemaps...

 Using array of type H (16 bits per item = 2 bytes), my maps take just
6*2 = 120KB of memory.

 After that, I just will access tilemap data for reading (i.e.  value
= tilemap.GetTile(x,y)) ...

 Do you think I should still go with lists instead of an H-type array?
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: How to get memory size/usage of python object

2008-01-10 Thread Santiago Romero

> Would you care to precisely define "REAL size" first? Consider:
>
> >>> atuple = (1, 2)
> >>> mylist = [(0, 0), atuple]
>
> Should sizeof(mylist) include sizeof(atuple) ?

 No, I'm talking about "simple" lists, without REFERENCES to another
objects into it.

 I mean:

lists = [ 0, 1, 2, 3, 4, (1,2), 3]

 or

array = [ [0,0,0,0,0,0,0], [1,1,1,1,2,1,2], ... ]

 Maybe I can "pickle" the object to disk and see the filesize ... :-?

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


Re: Converting a bidimensional list in a bidimensional array

2008-01-10 Thread Santiago Romero

> C:\> \python25\python -m -s

 :-)

 Thanks a lot :-)
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: printing dots in simple program while waiting

2008-01-09 Thread Santiago Romero
On 9 ene, 17:48, John <[EMAIL PROTECTED]> wrote:
> i want to print something like:
>
> (1sec) working...
> (2sec) working
> (3sec) working.
>
> where the 'working' line isn't being printed each second, but the dots
> are being added with time.
>
> something like:
>
> import time
> s = '.'
> print 'working'
> while True:
> print s
> time.sleep(1)
>
> however, this doesn't work since it prints:
>
> working
> .
> .

 Change

> print s

 to

> print s,

 (With the ending ",", which sends NO linefeed to stdout)

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


How to get memory size/usage of python object

2008-01-09 Thread Santiago Romero

 Is there a way to check the REAL size in memory of a python object?

 Something like

> print sizeof(mylist)

 or

> print sizeof(myclass_object)

 or something like that ...

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


Re: Converting a bidimensional list in a bidimensional array

2008-01-09 Thread Santiago Romero
> >  This is how I create the tilemap (and the clipboard, a copy of my
> > tilemap):
>
> > def __init__( self, bw, bh, tiles ):
> >   self.tilemap = []
> >   (...)
> >   for i in range(bh):
> >  self.tilemap.append([0] * bw)

>def __init__( self, bw, bh, tiles ):
>  self.width, self.height = bw, bh
>  self.tilemap = array.array('b', [0]) * bw * bh
>
> Gives a pure linearization (you do the math for lines).

 Do you mean : tilemap[(width*y)+x] ?

>def __init__( self, bw, bh, tiles ):
>  self.width, self.height = bw, bh
>  self.tilemap = [array.array('b', [0]) * bw for row in range(bh)]
>
> Gives a list of arrays.  I punted on the type arg here; you should make
> a definite decision based on your data.

 What do you think about:

- Memory Performance: Of course, my maps will take ( 16 bytes / 2-4
bytes ) = 8 or 4 times less memory (32 / 64 bit processores) ...
right?

- Speed Performance: Do you think that changing from list to Array()
would improve speed? I'm going to do lots of tilemap[y][x] checks (I
mean, player jumping around the screen, checking if it's falling over
a non-zero tile, and so).

 And thanks a lot for your answer :-)
-- 
http://mail.python.org/mailman/listinfo/python-list


Converting a bidimensional list in a bidimensional array

2008-01-08 Thread Santiago Romero

 Hi :)

 First of all, I must apologize for my poor english :)

 I'm starting with python and pygame and for testing (and learning)
purposes I wrote an small "Map Editor" for a small game project I'm
going to start next month.

 The tilemap editor is working fine, but reading Guido's Van Rossum
PYTHON TUTORIAL I found that my game map is "wasting" memory by using
about 16 bytes for each item in it, because every item in a python
list takes 16 bytes in memory. In the same tutorial, I found
references to the "array()" function of the "array" module.

 I'm trying to change my current working source code so that it works
with an array instead of using a list, but I'm not managing to do it.

 My tilemap is something like (think on 0=empty, 1=floor, 2=rock, and
so...):

[
[0 ,0, 0, 0, 0, 0, 0, 0 ,0],
[0 ,0, 0, 0, 0, 0, 0, 0 ,0],
[2 ,0, 0, 0, 0, 2, 2, 0 ,0],
(...)
[2 ,2, 0, 0, 2, 2, 2, 0 ,0],
[1 ,1, 1, 1, 1, 1, 1, 1 ,1],
]

 This is how I create the tilemap (and the clipboard, a copy of my
tilemap):

def __init__( self, bw, bh, tiles ):
  self.width, self.height = bw, bh
  self.tilemap = []
  self.clipboard = []
  (...)
  for i in range(bh):
 self.tilemap.append([0] * bw)
 self.clipboard.append([0] * bw)


 And that's how I'm using it (the functions I'm having trouble to
convert to use the array):

   #-
   def CopyToClipboard( self ):
  for j in range( self.height ):
 self.clipboard[j][:] = self.tilemap[j][:]

   #-
   def Draw( self, clear=1 ):
  screen = pygame.display.get_surface()
  if clear: self.Clear()

  for j in range(self.GetHeight()):
 for i in range(self.GetWidth()):
self.DrawBlock( i, j )

   #-
   def DrawBlock( self, x, y ):
  screen = pygame.display.get_surface()
  xd = (x * self.TileWidth()) + self.originx;
  yd = (y * self.TileHeight()) + self.originy;
  b = self.tilemap[y][x]
  self.tileset.tiles[b].Draw( screen, xd, yd )

   #-
   def ResizeWidth( self, new ):
  bw, bh = self.GetWidth(), self.GetHeight()

  if new > bw:
 for j in range(bh):
for i in range(new-bw):
   self.tilemap[j].append( 0 )
   self.clipboard[j].append( 0 )
 self.SetWidth( new )

  elif new < bw:
 for j in range(bh):
for i in range(bw-new):
   del self.tilemap[j][-1]
   del self.clipboard[j][-1]
 self.SetWidth( new )

   #-
   def ResizeHeight( self, new ):
  bw, bh = self.GetWidth(), self.GetHeight()

  if new > bh:
 for i in range(new-bh):
self.tilemap.append([0] * bw)
self.clipboard.append([0] * bw)
 self.SetHeight( new )

  elif new < bh:
 for i in range(1,bh-new):
 del self.tilemap[-1]
 self.SetHeight( new )



In fact, I'm even unable to create the array correctly:


 I've tried:

  self.tilemap = array('H', [])

  for i in range(bh):
 self.tilemap.append([0] * bw)

 and:

  for i in range(bh):

 for j in range(bw):
self.tilemap[i].append(0)


 But I receive errors like (either defining or using the array):

 b = self.tilemap[y][x]
TypeError: 'int' object is unsubscriptable

 or:

self.tilemap.append( [0] * bw )
TypeError: an integer is required



 So ... please ... any idea on how to convert my "python object" array
of lists to a bidimensional array and how to use it to index [y][x]
elements, or even resize it with the ResizeWidth() and Height()
functions?

 Thanks everybody.


PS: Please, think that I come from C/C++ so I still have some "C ways
of doing things" while there are better/faster ways to do the same in
Python. Feel free also to correct any "C-Style" programming way that
you can find in my source code above... :-)
-- 
http://mail.python.org/mailman/listinfo/python-list