[Tutor] Tutor Digest, Vol 86, Issue 12

Mateusz Koryciński mat.korycinski at gmail.com
Sun Apr 3 12:47:51 CEST 2011


Hi,

Thanks for all yout responses! I will answer below each one (I hope it
wouldn't be a problem).


>
>
> Message: 1
> Date: Sat, 2 Apr 2011 23:45:49 +0100
> From: "Alan Gauld" <alan.gauld at btinternet.com>
> To: tutor at python.org
> Subject: Re: [Tutor] 'for' iteration stop problem
> Message-ID: <in88v0$75e$1 at dough.gmane.org>
> Content-Type: text/plain; format=flowed; charset="iso-8859-1";
>        reply-type=original
>
>
> "Mateusz Korycinski" <mat.korycinski at gmail.com> wrote
>
> > My problem is simple for sure, but unfortunately I'm a bit beginner
> > and I've
> > stucked in it. I hope it is not a problem since as I understand this
> > mailing
> > list is for beginners.
>
> No problem, we try to answer questions such as this here.
>
> > I have some problem with 'for' loop in algorithm.
> > Code and description for this problem could be find here:
> >
> http://stackoverflow.com/questions/5520145/how-to-stop-iteration-when-if-statement-is-true
>
> There are several ways to get out of a loop, the most common are:
>
> a) To exit a single level of loop use break
>
>
> for n in range(500):
>    if n == 200: break
>    else; pass
>
> b) To break out of a set of nested loops such as you have then
> use break combined with a sentinal and check the sentinal at
> each level:
>
> exitLoop = False
> for x in range(20):
>    if exitLoop : break
>    for y in range(50):
>        if exitLoop: break
>        for z in range(500):
>            if z == 200:
>              exitLoop = True
>              break
>
> c) Use an exception:
>
> class ExitLoopException(Exception): pass
>
> try:
>  for x in range(20):
>    for y in range(50):
>        for z in range(500):
>            if z == 200:
>               raise ExitLoopException
> except ExitLoopException: pass
>
>
> There are other ways but those should cover most eventualities.
>
> HTH,
>
> --
> Alan Gauld
> Author of the Learn to Program web site
> http://www.alan-g.me.uk/
>
>
>
>
Thanks for advices, I will try to use it that way, but first I must test it
on small examples to get better know how it is working.



>
> ------------------------------
>
> Message: 2
> Date: Sat, 2 Apr 2011 18:38:12 -0500
> From: Wayne Werner <waynejwerner at gmail.com>
> To: Alan Gauld <alan.gauld at btinternet.com>
> Cc: tutor at python.org
> Subject: Re: [Tutor] 'for' iteration stop problem
> Message-ID:
>        <AANLkTinxcr=ayESK9C_opAgNWwBygXssq8oSJrpcLucb at mail.gmail.com>
> Content-Type: text/plain; charset="iso-8859-1"
>
> On Sat, Apr 2, 2011 at 5:45 PM, Alan Gauld <alan.gauld at btinternet.com
> >wrote:
>
> >
> > There are other ways but those should cover most eventualities.
>
>
> I find that my preferred way when the loops are nested is to move the loops
> into a function and then return:
>
> def do_something(collection, collection2):
>    for x in  collection:
>        for y in collection 2:
>             if someCase(x,y):
>                 return
>
> It seems (at least to me) a little nicer than sentinel values or throwing
> an
> exception.
>
> Just my $.02
> -Wayne
>

I've tried it that way, but I haven't succed. Perhaps I'm doing sth wrong, I
will check one more time.

Hi,

I will answer your questions below ech one.

> Message: 3
> Date: Sun, 03 Apr 2011 10:59:08 +1000
> From: Steven D'Aprano <steve at pearwood.info>
> To: tutor at python.org
> Subject: Re: [Tutor] 'for' iteration stop problem
> Message-ID: <4D97C65C.6070002 at pearwood.info>
> Content-Type: text/plain; charset=UTF-8; format=flowed
>
> Mateusz Koryci?ski wrote:
> > I have some problem with 'for' loop in algorithm.
> > Code and description for this problem could be find here:
> >
> http://stackoverflow.com/questions/5520145/how-to-stop-iteration-when-if-statement-is-true
>
> Other people have answered your question about exiting nested loops, but
> that's not your real problem. Your real problem is that the piece of
> code shown is unreadable and unmaintainable!
>
> (1) Python has functions: please use them to break your code into small,
> easily understandable pieces.
>
> (2) You have a *mess* of unreadable variable names. You have:
>
>     w.steps w.x w.y w.world data.c data.n data.e data.s data.w data.cc
>
> (yes, you have data.c AND data.cc!!!) plus loop variables z i j and r,
> and z is never used! How is anyone supposed to understand what this
> does? Even if you solve this problem *today*, in a week you will have
> forgotten what the code does and you won't understand it.
>
>
It's an objects from another classes. Variable z is used because there is a
need to provide number of steps to execute by user. Variable c mean central
cell in array whe are considering right now, other one is neighbours but cc,
cc means new state (couse basing on central cell and its neighbors we want
to change value to cc).


> (3) w.steps is never used except to needlessly(?) repeat the same
> calculations over and over again.
>

Described above.


> (4) w.x and w.y at least seem to be fairly obvious, although the names
> are terrible.
>

x - row numbers provided by user and in other class, which creates array
(from NumPy).
y - the same but cols


>
> (5) What are w.world and all the data.* variables? Are they "north",
> "south", "east", "west"?
>

w.World is a NumPy 2D array, c is central cell,  next four is neighbours,
'cc' is value which we want to place in array instead of 'c'.


>
> (6) You give an example of some output, but you don't show the *input*
> that is used to generate that data, so it is meaningless.
>

The input is 2D array, and list of rules, where each rule looks like this:

[
[  [2] [3] [4,5] [6] [7] [8]  ]
[  [9] [13] [14,15] [16] [17,19] [18]  ]
]
>From this I'm creating separate lists for each position so for example:
data.c = [ [2],[9] ]
data.e = [ [4,5],[14,15] ]


>
> (7) You seem to be re-writing the data in place. That's *usually* a
> mistake (not always, but, say, 95% of the time).
>
> It will help if you can describe what problem you are trying to solve.
> Not the algorithm you have already chosen, but the actual problem --
> what to you hope to do? There is probably a much better way.
>

The problem is self-replicating loop - Perrier's Loop (Langton's Loop
modification). It has a rule list, which is parsed from file by function
obtained from Golly's source code (GPL License). As a parsing result I have
sth like described above, where the order is:

C1,N,E,S,W,C2
C1 - present cell state (int)
N - north neigbour
E - east neigbour
S - south neigbour
W - west neigbour
C2 - state value to change

So result of this algorithm should be changing value from central cell (C1)
into new value (C2), but only if central cell state is equal to 1st value
from rule and neighbours values are equal to relevant values from rule list.
The format description could be find here:
http://code.google.com/p/ruletablerepository/wiki/TheFormat


>
> But for now, let me see if I can help refactor the code. You have:
>
> for z in range(w.steps):
>     for i in range(1,w.x-1):
>         for j in range(1,w.y-1):
>             print (i, j)
>             for r in data.c:
>                 if w.world[i][j] in r:
>                     print r
>                     ind = data.c.index(r)
>                     print ind
>                     if w.world[i-1][j] in data.n[ind]:
>                         if w.world[i][j+1] in data.e[ind]:
>                             if w.world[i+1][j] in data.s[ind]:
>                                 if w.world[i][j-1] in data.w[ind]:
>                                     w.world[i][j] = data.cc[ind]
>
>
>
> * make it a function that takes meaningfully named arguments, not just
> global variables;
>
> * throw away the top level loop, because z never gets used -- you're
> just needlessly repeating the same calculation w.steps times;
>
> * use helper functions to make your code more readable and to allow for
> future changes to the data structure;
>
> * comment your code!
>
>
>
> def get_neighbours(data, i, j):
>     """Return the four nearest neighbours of data[i,j].
>     Returns the north, south, east, west neighbours in that order:
>
>     [ [ ............. ]
>       [ ... . n . ... ]
>       [ ... w X e ... ]
>       [ ... . s . ... ]
>       [ ............. ] ]
>
>     """
>     return data[i-1][j], data[i+1][j], data[i][j+1], data[i][j-1]
>
>
>
> def match_item(item, values):
>     """Given a list of lists "values", match item against the items
>     in the sublists, returning the index of the first matching value
>     found.
>
>     ("values" is a terrible name, but since I don't know what the
>     problem you are solving is, I can't give it a more meaningful
>     name.)
>
>     >>> match_item(42, [[1, 2, 3], [11, 23, 37, 42, 55], [100, 200]])
>     (1, 3)
>
>     """
>     for i, sublist in enumerate(values):
>         if item in sublist:
>             return (i, sublist.index(item))
>     # If we never match at all, it is an error.
>     raise ValueError('item not in values')
>
>
>
> def iterate_data(data, values, north, south, east, west):
>     """Iterate over data, doing something to it, I don't know what.
>
>     data is a 2D array of numbers.
>     values is a list of lists. I don't know why.
>     north, south, east, west are four lists of numbers. They must
>     all have the same number of items.
>     """
>     assert len(north) == len(south) == len(east) == len(west)
>     directions = (north, south, east, west)
>     # Sorry, that is a poor, undescriptive name.
>
>     # Skip the first and last row and column.
>     for i in range(1, num_rows-1):
>         for j in range(1, num_cols-1):
>             cell = data[i][j]
>             # Find a match with values (whatever that is!)
>             x,y = match_item(cell, values)
>             # Now compare that cell's neighbours.
>             neighbours = get_neighbours(data, i, j)
>             if any(a in b[y] for (a,b) in zip(neighbours, directions)):
>                 print "Matched neighbour (now what?)"
>
>
>
>
> I hope this helps.
>
>
>
>
> --
> Steven
>
>
I hope that answer is good enough. ;)

Cheers,
Mateusz
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20110403/a9ef9590/attachment-0001.html>


More information about the Tutor mailing list