CS 115 Lab 9, Part B: Verify magic squares

[Back to lab instructions]


Overview

In this part of the lab, you will make sure that your magic square really is a magic square by calculating the sums of the numbers in each row, column, and diagonal.

In order to test your code, you'll also call a function to read magic squares from a user-specified file.

Instructions

  1. Make a copy of your lab09a.py file. Name it lab09b.py.
  2. You'll start by writing a function to calculate the sum of all values in a given row of this matrix. First, answer Question 1 in your writeup.
  3. Using what you learned, complete this function definition.
    def sum_row_values(matrix, row_number):
        """
        Sums the values of all entries in the row given by "row_number" 
        
        Parameters:
        matrix: a two dimensional (square) list
        row_number: an integer value in the range 0 and len(matrix)-1
    
        Returns: the sum of all values of the row indicated by "row_number"
        """  
        # Your code goes here
    
  4. You can test this code by adding the following lines to the end of main. Substitute your own magic square variable where indicated:
        sum_of_row_0 = sum_row_values(your_variable, 0)  
        print()
        print('The sum of values in row 0 is', sum_of_row_0)

    The output should look like this:

    Enter an odd integer to build a magic square: 5
    
      17  24   1   8  15
      23   5   7  14  16
       4   6  13  20  22
      10  12  19  21   3
      11  18  25   2   9
    
    The sum of values in row 0 is 65  
    

    Here is another example:

    Enter an odd integer to build a magic square: 7
    
      30  39  48   1  10  19  28
      38  47   7   9  18  27  29
      46   6   8  17  26  35  37
       5  14  16  25  34  36  45
      13  15  24  33  42  44   4
      21  23  32  41  43   3  12
      22  31  40  49   2  11  20
    
    The sum of values in row 0 is 175  
    
  5. Now modify your main function to print the sum of each row.

    Sample input/output:

    Enter an odd integer to build a magic square: 7
    
      30  39  48   1  10  19  28
      38  47   7   9  18  27  29
      46   6   8  17  26  35  37
       5  14  16  25  34  36  45
      13  15  24  33  42  44   4
      21  23  32  41  43   3  12
      22  31  40  49   2  11  20
    
    The sum of values in row 0 is 175
    The sum of values in row 1 is 175
    The sum of values in row 2 is 175
    The sum of values in row 3 is 175
    The sum of values in row 4 is 175
    The sum of values in row 5 is 175
    The sum of values in row 6 is 175
  6. Next, you'll write a function to sum the values in a given column. Answer Question 2 in your writeup.
  7. Using what you learned, complete this function definition.
    def sum_col_values(matrix, col_number):
        """
        Sums the values of all entries in the column given by "col_number" 
        
        matrix: a two dimensional (square) array
        col_number: an integer value in the range 0 and len(matrix)-1
    
        Returns the sum of all values in the column indicated by "col_number"
        """  
    
  8. In main, call your new function:
    Enter an odd integer to build a magic square: 5
    
      17  24   1   8  15
      23   5   7  14  16
       4   6  13  20  22
      10  12  19  21   3
      11  18  25   2   9
    
    The sum of values in column 0 is 65
    The sum of values in column 1 is 65
    The sum of values in column 2 is 65
    The sum of values in column 3 is 65
    The sum of values in column 4 is 65
    

    Another example:

    Enter an odd integer to build a magic square: 9
    
      47  58  69  80   1  12  23  34  45
      57  68  79   9  11  22  33  44  46
      67  78   8  10  21  32  43  54  56
      77   7  18  20  31  42  53  55  66
       6  17  19  30  41  52  63  65  76
      16  27  29  40  51  62  64  75   5
      26  28  39  50  61  72  74   4  15
      36  38  49  60  71  73   3  14  25
      37  48  59  70  81   2  13  24  35
    
    The sum of values in column 0 is 369
    The sum of values in column 1 is 369
    The sum of values in column 2 is 369
    The sum of values in column 3 is 369
    The sum of values in column 4 is 369
    The sum of values in column 5 is 369
    The sum of values in column 6 is 369
    The sum of values in column 7 is 369
    The sum of values in column 8 is 369  
    
  9. We are ready to calculate the sum of the diagonals. Let's start with the top-left to the bottom-right diagonal. For a 3x3 matrix, the indices of these values are (0, 0), (1, 1), (2, 2). Write a function to calculate the sum of values on this diagonal.
    def sum_top_left_bottom_right_diagonal(matrix):
        """  
        Calculates the sum of the values at matrix[0][0], matrix[1][1], etc.
    
        matrix: a two dimensional (square) matrix
        return value: the sum of values of the top-left to bottom-right
                      diagonal
        """  
    

    Add code to main to test this function before you proceed.

  10. Write a function to sum the value of the top-right to bottom-left diagonal. For a 3x3 matrix, these are: (0, 2), (1, 1), (2, 0).
    def sum_top_right_bottom_left_diagonal(matrix):
        """  
        Calculates the sum of the values at matrix[0][len(matrix)-1], matrix[1][len(matrix)-2], etc.
    
        matrix: a two dimensional (square) matrix
        return value: the sum of values of the top-right to bottom-left
                      diagonal
        """  
    

    This diagonal is harder than the previous one, but if you carefully study the indices of this diagonal of a few of the matrices above, you should see the pattern. Test this function before you proceed.

  11. Now you have everything you need to determine whether or not a given matrix is a magic square. Complete the function definition below.
    def is_magic_square(matrix):
        """
        returns True if the two dimensional array that "matrix" points to is a
        magic square. Otherwise, it returns False.
    
        matrix: a two dimensional (square) array.
        return value: True or False.
        """  
    
        # calculate the sum of the values of the top-left to
        # bottom-right diagonal. Call it tlbr_sum.
    
        # calculate the sum of the values of the top-right to
        # bottom-left diagonal. Call it trbl_sum.
    
        # if tlbr_sum is not equal to trbl_sum, return False. Otherwise,
        # proceed.
    
        # calculate the sum of each row of the matrix and compare it
        # with tlbr_sum. If the two sums are not equal, return False. 
        # Otherwise, proceed.
    
        # calculate the sum of each column of the matrix and compare it
        # with tlbr_sum. If the two sums are not equal, return False. 
        # Otherwise, proceed.
    
        # return True.
    
  12. Test the entire program:
    Enter an odd integer to build a magic square: 7
    
      30  39  48   1  10  19  28
      38  47   7   9  18  27  29
      46   6   8  17  26  35  37
       5  14  16  25  34  36  45
      13  15  24  33  42  44   4
      21  23  32  41  43   3  12
      22  31  40  49   2  11  20
    
    The above square is a magic square.
    
  13. Add some code that will print
    The above square is NOT a magic square.
    if the rows, columns, and diagonals do NOT all add to the same amount.
  14. The build_magic_square function always returns valid magic squares. To make sure that your code actually works, you'll need to test it on some values that are not magic squares. You'll read these in from the files you copied at the beginning of the lab. Start by copying this function definition into your code:
    def read_magic_square(filename):
        """
        Read values from a file into a 2D list
        
        Parameter:
        filename: the name of the file
    
        Returns a 2D list of integer values read.
        """
    
        infile = open(filename, "rt")    
        square = []  # start with an empty list
    
        for line in infile:  # read text from file
            row = []
            numbers = line.split()
    
            # Loop through the list of numbers.
            # Append each number to the row.
            for num in numbers:
                row.append(num)
    
            if len(row) > 0:  # Don't count blank lines
                square.append(row)  # Append the row to the 2D list
    
        return square
    
  15. In your main program, prompt the user for a filename after you have verified the original square. Sample output:
    Enter an odd integer to build a magic square: 7
    
      30  39  48   1  10  19  28
      38  47   7   9  18  27  29
      46   6   8  17  26  35  37
       5  14  16  25  34  36  45
      13  15  24  33  42  44   4
      21  23  32  41  43   3  12
      22  31  40  49   2  11  20
    
    The above square is a magic square.
    
    Enter the name of a file containing a matrix of numbers: ms1.txt
  16. Pass the filename to read_magic_square to create a magic square. Print the resulting magic square just like you did for the first one. Sample output:
    Enter an odd integer to build a magic square: 7
    
      30  39  48   1  10  19  28
      38  47   7   9  18  27  29
      46   6   8  17  26  35  37
       5  14  16  25  34  36  45
      13  15  24  33  42  44   4
      21  23  32  41  43   3  12
      22  31  40  49   2  11  20
    
    The above square is a magic square.
    
    Enter the name of a file containing a matrix of numbers: ms1.txt
    
       1   2   3
       4   5   6
       7   8   9
  17. Now call your function to verify the new magic square. It should crash with an error message that ends like this:
    TypeError: unsupported operand type(s) for +=: 'int' and 'str'
    Fix your read_magic_square function to eliminate this error by making sure that the elements of your list are all integers. You should only need to change one line.
  18. Test your program on all of the provided text files (ms1 through ms4). Of these files, only ms4 should be reported as a valid magic square.
  19. Sample output:
    Enter an odd integer to build a magic square: 7
    
      30  39  48   1  10  19  28
      38  47   7   9  18  27  29
      46   6   8  17  26  35  37
       5  14  16  25  34  36  45
      13  15  24  33  42  44   4
      21  23  32  41  43   3  12
      22  31  40  49   2  11  20
    
    The above square is a magic square.
    
    Enter the name of a file containing a matrix of numbers: ms1.txt
    
       1   2   3
       4   5   6
       7   8   9
    
    The above square is NOT a magic square.
  20. If you look back at the definition of magic square in Part A, there is one property of a magic square that we're not checking for. Answer Question 3 in your writeup.
  21. Make sure that the docstring includes your name, the assignment number, and a description of the current version of your program.
  22. Demo your code, and then continue to Part C.