5.9 Loops, Functions, Control Statements, and Comparisons

We have seen a few examples already of some common uses of for loops. In Python, a for loop has an indented structure, such as

>>> for i in range(5):
       print(i)
   
0
1
2
3
4
Note the colon at the end of the for statement (there is no ``do'' or ``od'' as in GAP or Maple), and the indentation before the ``body'' of the loop, namely print(i). This indentation is important. In Sage, the indentation is automatically put in for you when you hit enter after a ``:'', as illustrated below.

sage: for i in range(5):
          print(i)  # now hit enter twice
0
1
2
3
4
sage:

The symbol = is used for assignment. The symbol == is used to check for equality:

sage: for i in range(15):
          if gcd(i,15) == 1:
              print(i)
1
2
4
7
8
11
13
14
Keep in mind how indentation determines the block structure for if, for, and while statements:
sage: def legendre(a,p):
            is_sqr_modp=-1
            for i in range(p):
                if a % p == i^2 % p:
                    is_sqr_modp=1
            return is_sqr_modp
         
sage: legendre(2,7)
1
sage: legendre(3,7)
-1
Of course this is not an efficient implementation of the Legendre symbol! It is meant to illustrate various aspects of Python/Sage programming. The function kronecker, which comes with Sage, computes the Legendre symbol efficiently via a C-library call to PARI.

Finally, we note that comparisons, such as ==, !=, <=, >=, >, <, between numbers will automatically convert both numbers into the same type if possible:

sage: 2 < 3.1; 3.1 <= 1
True
False
sage: 2/3 < 3/2;   3/2 < 3/1
True
True
Almost any two objects may be compared; there is no assumption that the objects are equipped with a total ordering.
sage: 2 < CC(3.1,1)
True
sage: 5 < VectorSpace(QQ,3)   # output can be somewhat random
True
Use bool for symbolic inequalities:
sage: 3.1+2*I<4+3*I
2*I + 3.10000000000000 < 3*I + 4
sage: bool(3.1+2*I<4+3*I)
False
When comparing objects of different types in Sage, in most cases Sage tries to find a canonical coercion of both objects to a common parent, and if successful the comparison is performed between the coerced objects; if not successful the objects are considered not equal. For testing whether two variables reference the same object use is. For example:
sage: 1 is 2/2
False
sage: 1 is 1
False
sage: 1 == 2/2
True
In the following two lines the first equality is False because there is no canonical morphism $ \mathbf{Q}\to \mathbf{F}_5$ , hence no canonical way to compare the $ 1$ in $ \mathbf{F}_5$ to the $ 1 \in \mathbf{Q}$ . In contrast, there is a canonical map $ \mathbf{Z}\to \mathbf{F}_5$ , hence the second comparison is True. Note also that the order doesn't matter.
sage: GF(5)(1) == QQ(1); QQ(1) == GF(5)(1)
False
False
sage: GF(5)(1) == ZZ(1); ZZ(1) == GF(5)(1)
True
True
sage: ZZ(1) == QQ(1)
True

WARNING: Comparison in Sage is more restrictive than in Magma, which declares the $ 1 \in \mathbf{F}_5$ equal to $ 1 \in \mathbf{Q}$ .

sage: magma('GF(5)!1 eq Rationals()!1')            # optional magma required
true

See About this document... for information on suggesting changes.