Skip to main content
Engineering LibreTexts

15.4: More Generalization

  • Page ID
    15252
  • \( \newcommand{\vecs}[1]{\overset { \scriptstyle \rightharpoonup} {\mathbf{#1}} } \) \( \newcommand{\vecd}[1]{\overset{-\!-\!\rightharpoonup}{\vphantom{a}\smash {#1}}} \)\(\newcommand{\id}{\mathrm{id}}\) \( \newcommand{\Span}{\mathrm{span}}\) \( \newcommand{\kernel}{\mathrm{null}\,}\) \( \newcommand{\range}{\mathrm{range}\,}\) \( \newcommand{\RealPart}{\mathrm{Re}}\) \( \newcommand{\ImaginaryPart}{\mathrm{Im}}\) \( \newcommand{\Argument}{\mathrm{Arg}}\) \( \newcommand{\norm}[1]{\| #1 \|}\) \( \newcommand{\inner}[2]{\langle #1, #2 \rangle}\) \( \newcommand{\Span}{\mathrm{span}}\) \(\newcommand{\id}{\mathrm{id}}\) \( \newcommand{\Span}{\mathrm{span}}\) \( \newcommand{\kernel}{\mathrm{null}\,}\) \( \newcommand{\range}{\mathrm{range}\,}\) \( \newcommand{\RealPart}{\mathrm{Re}}\) \( \newcommand{\ImaginaryPart}{\mathrm{Im}}\) \( \newcommand{\Argument}{\mathrm{Arg}}\) \( \newcommand{\norm}[1]{\| #1 \|}\) \( \newcommand{\inner}[2]{\langle #1, #2 \rangle}\) \( \newcommand{\Span}{\mathrm{span}}\)\(\newcommand{\AA}{\unicode[.8,0]{x212B}}\)

    The previous version of printTable always displays six rows. We can generalize it by replacing the literal 6 with a parameter:

    public static void printTable(int rows) {
        int i = 1;
        while (i <= rows) {
            printRow(i);
            i = i + 1;
        }
    }
    

    Here is the output with the argument 7:

        1   2   3   4   5   6
        2   4   6   8  10  12
        3   6   9  12  15  18
        4   8  12  16  20  24
        5  10  15  20  25  30
        6  12  18  24  30  36 
        7  14  21  28  35  42

    That’s better, but it still has a problem: it always displays the same number of columns. We can generalize more by adding a parameter to printRow:

     public static void printRow(int n, int cols) {
         int i = 1;
         while (i <= cols) {
             System.out.printf("%4d", n * i);
             i = i + 1;
         }
         System.out.println();
     }

    Now printRow takes two parameters: n is the value whose multiples should be displayed, and cols is the number of columns. Since we added a parameter to printRow, we also have to change the line in printTable where it is invoked:

     public static void printTable(int rows) {
         int i = 1;
         while (i <= rows) {
             printRow(i, rows);
             i = i + 1;
         }
     }

    When this line executes, it evaluates rows and passes the value, which is 7 in this example, as an argument. In printRow, this value is assigned to cols. As a result, the number of columns equals the number of rows, so we get a square 7x7 table:

        1   2   3   4   5   6   7
        2   4   6   8  10  12  14
        3   6   9  12  15  18  21
        4   8  12  16  20  24  28
        5  10  15  20  25  30  35
        6  12  18  24  30  36  42
        7  14  21  28  35  42  49

    When you generalize a method appropriately, you often find that it has capabilities you did not plan. For example, you might notice that the multiplication table is symmetric; since ab = ba, all the entries in the table appear twice. You could save ink by printing half of the table, and you would only have to change one line of printTable:

    printRow(i, i); 

    In words, the length of each row is the same as its row number. The result is a triangular multiplication table.

        1
        2   4
        3   6   9
        4   8  12  16
        5  10  15  20  25
        6  12  18  24  30  36
        7  14  21  28  35  42  49

    Generalization makes code more versatile, more likely to be reused, and sometimes easier to write.


    This page titled 15.4: More Generalization is shared under a CC BY-NC-SA 3.0 license and was authored, remixed, and/or curated by Allen B. Downey (Green Tea Press) .

    • Was this article helpful?