DEV Community

mohamed Tayel
mohamed Tayel

Posted on

Article 1: Creating a Grid Formatter for Clean Data Display

Introduction

Displaying data in a clean and readable format is a fundamental task in software development. Whether you’re building a console application or exporting data to a file, organizing the data into a grid structure is often a necessity.

In this article, you’ll learn how to:

  1. Encapsulate data formatting logic in a reusable class.
  2. Dynamically calculate the number of columns based on the available width.
  3. Display data in a neatly formatted grid.

We’ll build a GridFormatter class from scratch and see it in action with step-by-step explanations.


Key Concepts

  1. Encapsulation:

    • The grid formatting logic will be wrapped inside the GridFormatter class, ensuring reusability and separation of concerns.
  2. Dynamic Column Calculation:

    • The number of columns will adjust dynamically based on the total width and the width of the data items.
  3. Flexibility:

    • The GridFormatter will work with any data type, making it generic and versatile.

Step-by-Step Implementation

Step 1: Define the GridFormatter Class

The GridFormatter class will:

  • Accept a collection of data items.
  • Format them into rows and columns based on the available width and the gap between columns.

Here’s the implementation:

using System;
using System.Collections.Generic;
using System.Linq;

namespace Utilities
{
    public class GridFormatter<T>
    {
        private readonly IList<T> _data;

        public GridFormatter(IEnumerable<T> inputData)
        {
            // Cache the input data in a list
            _data = inputData.ToList();
        }

        public IEnumerable<string> FormatGrid(int totalWidth, int gapWidth)
        {
            // Calculate the number of columns
            int columns = GetColumnCount(totalWidth, gapWidth);
            string gap = new string(' ', gapWidth);

            // Generate rows by taking the required number of items per row
            for (int i = 0; i < _data.Count; i += columns)
            {
                var row = _data.Skip(i).Take(columns)
                               .Select(item => item.ToString().PadRight(GetMaxItemWidth()));
                yield return string.Join(gap, row);
            }
        }

        private int GetColumnCount(int totalWidth, int gapWidth)
        {
            int maxItemWidth = GetMaxItemWidth();
            int columnWidth = maxItemWidth + gapWidth;
            return Math.Max(1, totalWidth / columnWidth);
        }

        private int GetMaxItemWidth()
        {
            return _data.Max(item => item.ToString()?.Length ?? 0);
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

Step 2: Use the GridFormatter Class in a Program

Now let’s see how to use the GridFormatter class in a real application.

using System;
using System.Collections.Generic;
using Utilities;

class Program
{
    static void Main(string[] args)
    {
        // Step 1: Input data
        var data = new List<string> { "Alice", "Bob", "Charlie", "Diana", "Eve" };

        // Step 2: Create an instance of GridFormatter
        var formatter = new GridFormatter<string>(data);

        // Step 3: Format the grid with a total width of 30 and a gap width of 3
        var grid = formatter.FormatGrid(30, 3);

        // Step 4: Display the formatted grid
        Console.WriteLine("Formatted Grid:");
        foreach (var row in grid)
        {
            Console.WriteLine(row);
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

Step 3: Run the Program

Input:

Data: Alice, Bob, Charlie, Diana, Eve
Total Width: 30
Gap Width: 3
Enter fullscreen mode Exit fullscreen mode

Output:

Formatted Grid:
Alice   Bob     Charlie
Diana   Eve
Enter fullscreen mode Exit fullscreen mode

How It Works

  1. Dynamic Column Calculation:

    • The GetColumnCount method calculates how many columns can fit within the given width. It takes into account the width of each item and the gap between columns.
  2. Row Generation:

    • Data is split into rows, each containing the appropriate number of items.
  3. Padding and Spacing:

    • Each item is padded to ensure consistent column alignment.

Takeaways

  1. Encapsulation:

    • The GridFormatter encapsulates all logic related to grid formatting, making it reusable across projects.
  2. Flexibility:

    • By using generics, the GridFormatter can work with any type of data.
  3. Dynamic Design:

    • The formatter adapts to the available width, making it highly versatile for different use cases.

Next Steps

In the next article, we’ll build a Shuffler class to randomize data efficiently using the Fisher-Yates Shuffle. This will complement the GridFormatter and allow us to create more dynamic applications, like randomized team assignments.

Stay tuned for Article 2: Building a Reusable Shuffler for Randomizing Data! 🚀

Heroku

Build apps, not infrastructure.

Dealing with servers, hardware, and infrastructure can take up your valuable time. Discover the benefits of Heroku, the PaaS of choice for developers since 2007.

Visit Site

Top comments (0)

Billboard image

The Next Generation Developer Platform

Coherence is the first Platform-as-a-Service you can control. Unlike "black-box" platforms that are opinionated about the infra you can deploy, Coherence is powered by CNC, the open-source IaC framework, which offers limitless customization.

Learn more

AWS Security LIVE!

Hosted by security experts, AWS Security LIVE! showcases AWS Partners tackling real-world security challenges. Join live and get your security questions answered.

Tune in to the full event

DEV is partnering to bring live events to the community. Join us or dismiss this billboard if you're not interested. ❤️