"""
Recommended Python Style Guide:
https://peps.python.org/pep-0008/#introduction
"""

"""
Check if the Matrix is Square.
"""

# Define a matrix
matrix = [[-2, 5, 3, 2], [9, -6, 5, 1], [3, 2, 7, 3], [-1, 8, -4, 8]]
print(f"Original matrix = {matrix}")

# Check if the matrix is square
is_square = True  # Initialize a flag to check if the matrix is square
for row in matrix:  # Iterate through each row of the matrix
    if len(row) != len(matrix):  # Check if the number of columns equals the number of rows
        is_square = False  # If not, update the flag

# Display the result of the check
if not is_square:
    print("Error: The matrix is not square.")
else:
    print("The matrix is square.")

print()
print()

"""
Extracting the Anti-Diagonal.
"""

# Define a matrix
matrix = [[-2, 5, 3, 2], [9, -6, 5, 1], [3, 2, 7, 3], [-1, 8, -4, 8]]
print(f"Original matrix = {matrix}")

n = len(matrix)  # Get the size of the matrix (number of rows)

# Extract the anti-diagonal using a list comprehension
anti_diagonal = [matrix[i][n - i - 1] for i in range(n)]

print(f"Anti-diagonal = {anti_diagonal}")
# Output: Anti-diagonal = [2, 5, 2, -1]

print()
print()

"""
Flatten a Nested List.
"""

# Define a matrix
matrix = [[1, 2, 3], [4, 5], [6, 7, 8, 9]]
print(f"Original matrix = {matrix}")

# Solution 1: Using list comprehension
flat_list = [item for sublist in matrix for item in sublist]
print("Solution 1: Using list comprehension")
print(f"Flattened list = {flat_list}")

# Solution 2: Using nested loops
flat_list = []
for row in matrix:
    for item in row:
        flat_list.append(item)
print("Solution 2: Using nested loops")
print(f"Flattened list = {flat_list}")

# Output: Flattened list = [1, 2, 3, 4, 5, 6, 7, 8, 9]

print()
print()

"""
Count Occurrences of a Specific Element in a Nested List.
"""

# Define a nested matrix
matrix = [[1, 2, 3], [2, 4, 2], [5, 2, 6]]
print(f"Original matrix = {matrix}")

target = 2  # The element we want to count occurrences of

count = 0  # Initialize the counter
for row in matrix:  # Iterate through each row of the matrix
    # Add the number of occurrences of the target element in the row
    count += row.count(target)
print(f"The element {target} appears {count} times.")
# Output: The element 2 appears 4 times.

# Note that the loop can be replaced by a single line:
# count = sum(row.count(target) for row in nested_list)

print()
print()

"""
Multiply Elements of Two Matrices.
"""
# Define two matrices
matrix1 = [[1, 2, 3], [4, 5, 6]]
matrix2 = [[7, 8, 9], [10, 11, 12]]

print(f"Original matrix 1= {matrix1}")
print(f"Original matrix 2 = {matrix2}")

# Multiply the matrices element-wise

# Solution 1: Using list comprehension
result = [[matrix1[i][j] * matrix2[i][j]  # Multiply the element from the first matrix by the element from the second
           for j in range(len(matrix1[0]))]  # For each column
          for i in range(len(matrix1))]  # For each row

print("Solution 1: Using list comprehension")
print(f"Element-wise product = {result}")

# Solution 2: Using nested loops
for i in range(len(matrix1)):  # For each row
    for j in range(len(matrix1[0])):  # For each column
        result[i][j] = matrix1[i][j] * matrix2[i][j]

print("Solution 2: Using nested loops")
print(f"Element-wise product = {result}")

# Output: Element-wise product = [[7, 16, 27], [40, 55, 72]]

print()
print()

"""
Transpose a Matrix.
"""
# Define the matrix to be transposed
matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
# Initialize an empty list to hold the transposed matrix
transposed = []

# Loop through the columns of the original matrix
for i in range(len(matrix[0])):  # Number of columns in the original matrix
    # Create a new row for the transposed matrix
    new_row = []

    # Loop through the rows of the original matrix
    for row in matrix:
        new_row.append(row[i])  # Append the element at the current column
    transposed.append(new_row)  # Add the new row to the transposed matrix

# Display the transposed matrix
print(f"Original matrix = {matrix}")
print(f"Transposed matrix = {transposed}")