Python3 String Formatting Parametrized & Custom Objects
Tags: python, strings, formatting
Published: 2020-04-23 19:44:31

---
title: Python3 String Formatting Parametrized & Custom Objects
published: true
description: 
tags: python, strings, formatting
cover_image: https://dev-to-uploads.s3.amazonaws.com/i/9r1yzjl7nvedyzcp0pzd.PNG
---

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.

- https://pyformat.info/#param_align
- https://pyformat.info/#custom_1
- https://www.digitalocean.com/community/tutorials/how-to-use-string-formatters-in-python-3

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/9r1yzjl7nvedyzcp0pzd.PNG)

## 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. {%youtube v3K3qi-wgfE%}

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](https://github.com/kodaman2/lspy)

```python
print("{} {} {:10} {:10} {:8} {} {}".format(
numeric_chmod,
number_of_links,
user, group, 
size, 
mod_timestamp, 
file))
```

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.

```python
# 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))
```

```python
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='>'   
            ))
```

- 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.

```python
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
```

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

```python
StringColorizer(file.filename, file.stats),
```

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