print out list of the relation between variables in python?
Question: I'm an absolute beginner with python and my professor is sort of doing a trial
of fire approach to teaching us the language. The goal is to list the triples
in the relation {(a,b,c) : a, b, and c are integers with 0 < a < b < c < 5}.
Use range(5) as the source for values of a, b, and c.

I think i understand the general concept of what it is, i set the values of
a,b,c fine, but I don't quite get how I can print out variables like that? I
was thinking of using some sort of while loop of like while a < b < c print
out (a,b,c) or something but I can't get it to work with the syntax.

Thanks so much for the help!


Answer: So you need to vary each of `a`, `b`, and `c` in the range 0-4 (which is what
`range(5)` produces). For this you can use three nested `for` loops.

    
    
    for a in range(5):
        for b in range(5):
            for c in range(5):
    

This will ensure that for each possible value of `a`, all possible values of
`b` are tried, and similarly, for each possible value of `b`, all possible
values of `c` are tried. In other words, the innermost (bottom-most, as
they're written) loop `c` will go through 0-4 for each value of `b`, which is
also going through 0-4 for each value of `a`, which is _also_ going through
0-4.

Now inside these loops, you just need to check to see if the criterion your
prof has given is true, and if so, print the numbers. Fortunately, the syntax
your prof has given works fine in Python:

    
    
    if 0 < a < b < c < 5:
        print(a, b, c)
    

Putting it all together, then, we have:

    
    
    for a in range(5):
        for b in range(5):
            for c in range(5):
                if 0 < a < b < c < 5:
                    print(a, b, c)
    

Now, this works fine, and will undoubtedly satisfy your professor, but there
are some simple improvements you can make to this program. First, the
variables each go from 0-4, but the value 0 is never going to pass the `if`
test, because it will never be less than 0! So why even try it? You could save
a bit of work by writing each range as `range(1, 5)`.

But... there's also the fact that if `a` is 1, `b` can never be 1 (because `a
< b` must be true, and if `a` is 2, `b` can likewise never be 2, and so on.
And also, from the other end of the range, if `c` is 4, `b` can never be 4 and
satisfy the test. We can write the ranges accordingly, so that the range for
`b` starts 1 past `a` and leaves off one _before_ `c`, so that those
combinations of values need never be tested.

Finally, your `if` statement can also be simplified: because of the ranges
being used, you don't need to make sure 0 is less than `a`; that will always
be true because `a` starts at 1. At the same time, you know that `c` will
always be less than 5 because the `range()` makes it that way, so you can
remove that test too.

So you will get identical results, while doing less work, by writing it like
this:

    
    
    for a in range(1, 3):
        for b in range(a+1, 4):
            for c in range(b+1, 5):
                if a < b < c:
                    print(a, b, c)
    

In this case, the extra work is not that important... both versions are so
fast you will never notice the extra time the first approach took. But it's
always worth thinking about how a problem can be rethought to do less work;
sometimes it's the difference between a usable program and an unusable one.

In this case, the initial version goes through 125 tests. The second, more
efficient version? **Four.** Which happens to be exactly the same as the
number of correct results!

So we can take out the `if` statement entirely, and just print every
combination, because the loops we've written make sure that _only numbers that
pass the test are used to begin with._

And we've done less than 1/30th of the work in the process!

