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
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.
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.
# 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))
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 withsize_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
then we can pass it to our string format as seen above:
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!
Top comments (0)