DEV Community

Cover image for Python3 String Formatting Parametrized & Custom Objects
Fernando B πŸš€
Fernando B πŸš€

Posted on

Python3 String Formatting Parametrized & Custom Objects

It has been a while since my last written post, I think this might be useful for some people since examples and documentation is not quite clear. It also took me a few hours to figure it out, better late than never.

I will be mainly talking about formatting with parametrized values, and custom objects.

Alt Text

Problem Statement

I needed to align or add padding to the ls utility clone I built with python3, as you see in the above picture is perfect now. In the first few builds, I just manually added tons of padding to make it workable.

If you aren't very familiar with formatting, this is just adding 10 column spaces from where the first character is in the terminal. So third column adds 10, fourth 10, and fifth 8. In other words I am padding the columns so they are not crunched up together.

Github repo

print("{} {} {:10} {:10} {:8} {} {}".format(
numeric_chmod,
number_of_links,
user, group, 
size, 
mod_timestamp, 
file))
Enter fullscreen mode Exit fullscreen mode

The first problem with that is if a user name or the group name is longer than my character length, then columns will get uneven. It wasn't a pretty solution, and it bothered me. Second, later I found out, other columns have different sizes too. Some are pretty much the same, like file permissions. (Column 0).

Parametrized formatting to the rescue

The solution is to add the padding dynamically, as it changes depending on the length of the string. There is another part of the program where I calculate the longest strings, below is just one of them.

# find longest strings for calculating padding
    for file in files_info:

        if len(str(file.number_of_links)) > number_of_links_length:
            number_of_links_length = len(str(file.number_of_links))
Enter fullscreen mode Exit fullscreen mode
for file in files_info:
print("{} {:{links_padding}} {:{user_padding}} 
{:{group_padding}} {:{align}{size_padding}} {} {}".format(
            file.chmod,
            file.number_of_links,
            file.user,
            file.group,
            file.size,
            file.mod_timestamp,
            StringColorizer(file.filename, file.stats),
            links_padding=str(number_of_links_length),
            user_padding=str(user_length),
            group_padding=str(group_length),
            size_padding=str(size_lenght),
            align='>'   
            ))
Enter fullscreen mode Exit fullscreen mode
  • Keyword arguments need to go at the end
  • Parametrized format goes inside another set of curly braces, you can have as many as you want, but the order needs to be the same as if you weren't using parameters. Note where I used align in conjuntion with size_padding or :>6.
  • Strings that do not need any formatting is just an empty curly brace pair.

Custom Objects

The other feature I needed to implement was colors, as you've noticed terminals display colors for certain file types, or folders. I decided to use termcolor package, but the key item here is how we are using it with string format. And this is just an example you can of course do anything in the magic format method.

class StringColorizer:
    def __init__(self, string_to_print, stats):
        self.string_to_print = string_to_print
        self.stats = stats

    def __format__(self, format):
        default_color = 'white'
        image_extensions = ['.png', '.jpg','.jpeg', '.tif', '.tiff', '.bmp', '.gif', '.png', '.raw']

        for ext in image_extensions:
            if self.string_to_print.endswith(ext):
                return colored(self.string_to_print, 'magenta', attrs=['bold'])

    ... other colors
Enter fullscreen mode Exit fullscreen mode

then we can pass it to our string format as seen above:

StringColorizer(file.filename, file.stats),
Enter fullscreen mode Exit fullscreen mode

I hope you enjoyed this post, and learned something new, please feel free to comment and I welcome feedback. Thanks for reading!

Top comments (0)