This script won't work due to a type error. Can you help analyse it? \n\n import mpmath
from PIL import Image, ImageDraw, ImageFont
import math
import os
from itertools import islice

def get_pi_digits(n):
    """
    Calculate n digits of pi using mpmath.

    Args:
        n (int): Number of pi digits to calculate (including the initial '3').

    Returns:
        str: A string containing n digits of pi (including the initial '3').
    """
    mpmath.mp.dps = n  # Set decimal places to n
    pi_str = str(mpmath.mp.pi)
    pi_digits = pi_str.replace('.', '')[:n]  # Include the initial '3'
    return pi_digits

def find_optimal_font_size(font_path, big_width, big_height, grid_cols, grid_rows, min_font_size=6, max_font_size=100):
    """
    Find the optimal font size that allows the text to fit within the big image dimensions
    and ensures that the characters and lines are divisible by the grid dimensions.

    Args:
        font_path (str): Path to the TTF font file.
        big_width (int): Width of the big image in pixels.
        big_height (int): Height of the big image in pixels.
        grid_cols (int): Number of columns in the grid.
        grid_rows (int): Number of rows in the grid.
        min_font_size (int, optional): Minimum font size to consider. Defaults to 6.
        max_font_size (int, optional): Maximum font size to consider. Defaults to 100.

    Returns:
        tuple: (font, chars_per_sub_image_line, lines_per_sub_image)
            font (ImageFont.FreeTypeFont): Loaded font object with the optimal size.
            chars_per_sub_image_line (int): Number of characters per line in each grid sub-image.
            lines_per_sub_image (int): Number of lines per grid sub-image.
    """
    best_font_size = None
    best_chars_per_sub_image_line = 0
    best_lines_per_sub_image = 0
    best_font = None

    for font_size in range(max_font_size, min_font_size - 1, -1):
        try:
            font = ImageFont.truetype(font_path, font_size)
        except IOError:
            print(f"Failed to load font at size {font_size}. Skipping.")
            continue

        # Measure a representative character
        bbox = font.getbbox('0')
        char_width = bbox[2] - bbox[0]
        char_height = bbox[3] - bbox[1]

        if char_width == 0 or char_height == 0:
            continue

        # Calculate how many characters and lines fit in the big image
        chars_per_line = big_width // char_width
        lines_per_page = big_height // char_height

        # Ensure that the number of characters per line and lines are divisible by grid dimensions
        if chars_per_line < grid_cols or lines_per_page < grid_rows:
            continue  # Not enough space to divide

        if chars_per_line % grid_cols != 0 or lines_per_page % grid_rows != 0:
            # Adjust to make it divisible by grid dimensions
            adjusted_chars_per_sub_image_line = chars_per_line // grid_cols
            adjusted_lines_per_sub_image = lines_per_page // grid_rows

            # Recalculate the exact number of characters and lines per sub-image
            exact_chars_per_line = adjusted_chars_per_sub_image_line * grid_cols
            exact_lines_per_page = adjusted_lines_per_sub_image * grid_rows

            digits_per_page = exact_chars_per_line * exact_lines_per_page

            if digits_per_page <= 0:
                continue  # Invalid configuration

            # Update characters per sub-image line and lines per sub-image
            chars_per_sub_image_line = adjusted_chars_per_sub_image_line
            lines_per_sub_image = adjusted_lines_per_sub_image

            # Select the largest font size that meets the criteria
            if font_size > best_font_size or best_font_size is None:
                best_font_size = font_size
                best_chars_per_sub_image_line = chars_per_sub_image_line
                best_lines_per_sub_image = lines_per_sub_image
                best_font = font

        else:
            # Perfectly divisible
            chars_per_sub_image_line = chars_per_line // grid_cols
            lines_per_sub_image = lines_per_page // grid_rows

            if font_size > best_font_size or best_font_size is None:
                best_font_size = font_size
                best_chars_per_sub_image_line = chars_per_sub_image_line
                best_lines_per_sub_image = lines_per_sub_image
                best_font = font

    if best_font is None:
        raise ValueError("Unable to find a suitable font size with the given parameters.")

    return best_font, best_chars_per_sub_image_line, best_lines_per_sub_image

def split_image_into_grid(big_image, grid_cols, grid_rows):
    """
    Split the big image into a grid of smaller images.

    Args:
        big_image (PIL.Image.Image): The large image to split.
        grid_cols (int): Number of columns in the grid.
        grid_rows (int): Number of rows in the grid.

    Returns:
        list: A list of PIL.Image.Image objects representing each grid section.
    """
    big_width, big_height = big_image.size
    sub_width = big_width // grid_cols
    sub_height = big_height // grid_rows
    grid_images = []

    for row in range(grid_rows):
        for col in range(grid_cols):
            left = col * sub_width
            upper = row * sub_height
            right = left + sub_width
            lower = upper + sub_height
            bbox = (left, upper, right, lower)
            sub_image = big_image.crop(bbox)
            grid_images.append(sub_image)

    return grid_images

def save_grid_images(grid_images, output_folder):
    """
    Save the grid images to the specified output folder.

    Args:
        grid_images (list): List of PIL.Image.Image objects.
        output_folder (str): Directory where images will be saved.
    """
    if not os.path.exists(output_folder):
        os.makedirs(output_folder)

    for idx, img in enumerate(grid_images, start=1):
        img_path = os.path.join(output_folder, f'pi_digits_grid_{idx}.png')
        img.save(img_path, 'PNG', dpi=(300, 300))
        print(f"Saved {img_path}")

def main():
    """
    Main function to execute the pi digit image generation and grid splitting.
    """
    # User-configurable parameters
    n_digits = 100000  # Total number of pi digits to calculate (including '3')
    font_path = 'DejaVuSansMono.ttf'  # Ensure the font file is in the same directory
    single_width = 3508  # A4 landscape width in pixels at 300 DPI
    single_height = 2480  # A4 landscape height in pixels at 300 DPI
    grid_cols = 2  # Number of columns in the grid
    grid_rows = 2  # Number of rows in the grid
    output_folder = 'pi_images_grid'  # Output directory for grid images

    # Step 0: Ensure the font file exists
    if not os.path.isfile(font_path):
        print(f"Font file '{font_path}' not found. Please ensure it is in the current directory.")
        return

    # Step 1: Calculate pi digits
    print(f"Calculating {n_digits} digits of pi (including the initial '3')...")
    pi_digits = get_pi_digits(n_digits)
    print("Pi digit calculation complete.")

    # Step 2: Calculate big image dimensions
    big_width = single_width * grid_cols
    big_height = single_height * grid_rows
    print(f"Creating a big image of size {big_width}x{big_height} pixels to accommodate the grid.")

    # Step 3: Find optimal font size
    print(f"Determining optimal font size for {grid_cols}x{grid_rows} grid...")
    try:
        font, chars_per_sub_line, lines_per_sub_image = find_optimal_font_size(
            font_path, big_width, big_height, grid_cols, grid_rows, min_font_size=6, max_font_size=100
        )
    except ValueError as ve:
        print(str(ve))
        return

    # Calculate characters per line and lines per page for big image
    chars_per_line_big = chars_per_sub_line * grid_cols
    lines_per_page_big = lines_per_sub_image * grid_rows
    digits_per_page_big = chars_per_line_big * lines_per_page_big

    print(f"Optimal font size: {font.size}")
    print(f"Characters per sub-image line: {chars_per_sub_line}")
    print(f"Lines per sub-image: {lines_per_sub_image}")
    print(f"Total characters per line in big image: {chars_per_line_big}")
    print(f"Total lines per page in big image: {lines_per_page_big}")
    print(f"Total digits per big image: {digits_per_page_big}")

    # Step 4: Calculate total digits needed and pad if necessary
    total_digits = len(pi_digits)
    total_digits_needed = digits_per_page_big
    if total_digits > total_digits_needed:
        # Handle multiple big images if necessary
        # For simplicity, assuming n_digits fits into one big image
        print(f"Warning: Number of digits ({total_digits}) exceeds digits per big image ({total_digits_needed}).")
        print("Consider increasing the grid size or reducing the number of digits.")
        return
    elif total_digits < total_digits_needed:
        padding_digits = total_digits_needed - total_digits
        pi_digits += ' ' * padding_digits  # Pad with spaces
    else:
        padding_digits = 0

    print(f"Total digits present: {total_digits}")
    print(f"Total digits needed: {total_digits_needed}")
    print(f"Padding digits added: {padding_digits}")

    # Step 5: Create the big image
    print("Creating the big image with all pi digits...")
    big_image = Image.new('RGB', (big_width, big_height), color='white')
    draw = ImageDraw.Draw(big_image)

    # Draw digits sequentially
    print("Drawing digits onto the big image...")
    y = 0
    char_height = font.getbbox('0')[3] - font.getbbox('0')[1]
    for line_num in range(lines_per_page_big):
        start_idx = line_num * chars_per_line_big
        end_idx = start_idx + chars_per_line_big
        line_text = pi_digits[start_idx:end_idx]
        draw.text((0, y), line_text, font=font, fill='black')
        y += char_height

    print("Drawing complete.")

    # Step 6: Split the big image into grid
    print(f"Splitting the big image into a {grid_cols}x{grid_rows} grid...")
    grid_images = split_image_into_grid(big_image, grid_cols, grid_rows)
    print(f"Total grid images created: {len(grid_images)}")

    # Step 7: Save grid images
    print(f"Saving grid images to '{output_folder}' folder...")
    save_grid_images(grid_images, output_folder)
    print("All grid images have been saved successfully.")

if __name__ == "__main__":
    main()