[Tutor] stopping a loop

Daniel Yoo dyoo@hkn.eecs.berkeley.edu
Sat, 5 May 2001 13:37:37 -0700 (PDT)


On Sat, 5 May 2001, Julieta Rangel wrote:

> Here I am, bugging you guys ...AGAIN!.  As some of you might remember, I'm 

Don't worry about it; we're tough, we can handle it.  *grin* 

Seriously, you don't need to apologize about asking questions; just have
fun, play around with Python, and talk to us when things look weird.  
We're all here voluntarily, so if it makes you feel better, we should be
apologizing to you for writing such boring, long sentences about feeling
unjustifiably embarrased about hurting our feelings about a difficult
subject that's quite enormously unintuitive at the beginning but gets
easier as you learn more about it.


> for x in set:
>     for y in set:
>        prompt ="%s %s %s = ? "%(x,op,y)
>        z= raw_input(prompt)
> 
>        product[x,y] = z
>     print " "


> set, the computer would inform me that the set is not a group because 
> closure fails; however, the result was not what I was looking for, the 
> computer would keep asking me for the rest of the table values.  I read that 
> to break a loop I must insert a break statement, but I could not figure out 
> where to place it.  I tried placing it in different places, but it wouldn't 

Using break is the right idea; however, break will pull us out of any
innermost loop: because we're in a nested loop though, we're still within
the body of the outside loop when we do a break.  Here's an example that
shows this behavior:

###
>>> for x in range(5):
...     for y in range(5):
...         print x,y
...         if y == 0: break
...
0 0
1 0
2 0
3 0
4 0
###

So even though we did a break, we didn't break out of the outermost loop.  
If we want to break out of the whole loop, one approach we can use is to
"cascade" the break, so that we continue breaking until we're out.

###
>>> unsuccess = 0
>>> for x in range(5):
...     for y in range(5):
...         print x, y
...         if y == 0:
...             unsuccess = 1
...             break
...     if unsuccess == 1:
...         break
...
0 0
###

Domino effect.  Another way to organize this is to have your Cayley table
input routine be itself a small function.  For example, we can write a
small helper function like this:

###
def getCayleyTable(op, set):
    product = {}
    for x in set:
        for y in set:
            prompt ="%s %s %s = ? "%(x,op,y)
            z= raw_input(prompt)
            product[x,y] = z
            if z not in set:
                return product     # jump out entirely from the function
        print
    return product
###


Writing a helper function might be good because it allows us to
concentrate on a small part of your program.  Because it's a complete
function, we can do testing on it, even if we're not done with the rest of
the program yet.  For example, if we have the getCayleyTable function
written above, we might be curious to see if it works at all:

###
>>> mytable = getCayleyTable('+', [0, 1, 2])
0 + 0 = ? 0
>>> mytable
{(0, 0): '0'}
>>> mytable = getCayleyTable('+', ['0', '1', '2'])
0 + 0 = ? 0
0 + 1 = ? 1
0 + 2 = ? 2

1 + 0 = ? 1
1 + 1 = ? 2
1 + 2 = ? 0

2 + 0 = ? 2
2 + 1 = ? 0
2 + 2 = ? 1

>>> mytable
{('1', '0'): '1', ('1', '1'): '2', ('1', '2'): '0',
 ('0', '0'): '0', ('0', '2'): '2', ('2', '1'): '0',
 ('0', '1'): '1', ('2', '0'): '2', ('2', '2'): '1'}
###

Our first run through getCayleyTable shows us that we need to make sure
our set elements are strings.  This sort of testing becomes difficult when
our programs balloon to larger sizes, so it's a good idea to get in the
habit of organizing conceptually simple tasks into helper functions.


Again, feel free to ask questions.  Hope this helps!