Python Forum
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
f-strings and termcolor
#1
Hi!

This problem came up when I was searching for ways to colour and give styles to strings:
https://python-forum.io/Thread-colouring-strings?page=2

The f-string formatting seems to be the advisable choice since Python 3.6, so I want to be able to learn properly about them.
I want to compare different packages applying the same formatting (f-strings) to the same string with all the packages, to be fair in the comparison.

With all the other packages in the comparison group, I managed finally to make them work, but not with termcolor. Due to the way the attributes are applied, I cannot make it work with f-strings. It works if I don't use f-strings, but for the comparison, I'd really like to use them. Please, is there a way to do it?

This is the little program I use with the string to be formatted (I commented out the two lines that I tried with f-strings). The program works, but I wanted to apply f-strings to the coding. What am I doing wrong?:
# strings_compared_EXTRA_01.py
#

import sys
from termcolor import colored, cprint

# str1 = "dangerous", "RED", attrs=["bold", "underline"]
# cprint(f'\nThis is  {str1} ... for my mental health!\n\n')

cprint('\nThis is ', end='')
cprint('dangerous', 'green', attrs=['bold', 'underline'], end='')
cprint('... for my mental health!', end='\n\n')
It works, but I wanted to make it work with f-strings:
[Image: dangerous.png]

Could you help me, please?

All the best,
newbieAuggie2019

"That's been one of my mantras - focus and simplicity. Simple can be harder than complex: You have to work hard to get your thinking clean to make it simple. But it's worth it in the end because once you get there, you can move mountains."
Steve Jobs
Reply
#2
Well no, the commented out code doesn't make any sense, does it? str1 on line 7 is a tuple of three values and on line 8, that's used in the f-string, so you'll be printing that tuple. On line 11, the string that's displayed is 'dangerous' and the colour and other things are arguments to the function. Why would you think you'd put the arguments to the function inside the string you want to print (as you've done in line 7)?
Reply
#3
(Sep-21-2019, 03:42 PM)ndc85430 Wrote: Well no, the commented out code doesn't make any sense, does it? str1 on line 7 is a tuple of three values and on line 8, that's used in the f-string, so you'll be printing that tuple. On line 11, the string that's displayed is 'dangerous' and the colour and other things are arguments to the function. Why would you think you'd put the arguments to the function inside the string you want to print (as you've done in line 7)?
Thank you for your time and answer!
Yes, I understand that, this was just one of my last attempts at it. I tried nesting inside {}, just beside dangerous (instead of {str1}), the characteristics {'RED'} and {attrs=['bold', 'underline']}, that is, trying to include everything in one-liner:
cprint(f'\nThis is  {dangerous, {'RED'}, {attrs=['bold', 'underline']}} ... for my mental health!\n\n')
I've tried with commas, without commas, with square brackets, without square brackets, with quotation marks, without quotation marks ... and of course, I've gotten all kinds of errors ...

I'm a newbie, and I find strange the way, on the line
cprint('dangerous', 'green', attrs=['bold', 'underline'], end='')
'green' is giving characteristics to 'dangerous' and followed by 'attrs' with an equal sign, with two more styles inside a pair of square brackets, and separated by a comma. I don't understand the logic in that process and how I can turn it into an f-string format.

As a last resort, I use the brute "trial and error method", that in some cases, provides me with the solution, and then it helps me, 'a posteriori', to understand the logic in it.
Cry

All the best,
newbieAuggie2019

"That's been one of my mantras - focus and simplicity. Simple can be harder than complex: You have to work hard to get your thinking clean to make it simple. But it's worth it in the end because once you get there, you can move mountains."
Steve Jobs
Reply
#4
I would suggest you look into the termcolor package and investigate how cprint() works.

termcolor is found here

The file termcolor.py looks like this and with a little bit of work you can achieve what you want.
# coding: utf-8
# Copyright (c) 2008-2011 Volvox Development Team
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
#
# Author: Konstantin Lepa <[email protected]>

"""ANSII Color formatting for output in terminal."""

from __future__ import print_function
import os


__ALL__ = [ 'colored', 'cprint' ]

VERSION = (1, 1, 0)

ATTRIBUTES = dict(
        list(zip([
            'bold',
            'dark',
            '',
            'underline',
            'blink',
            '',
            'reverse',
            'concealed'
            ],
            list(range(1, 9))
            ))
        )
del ATTRIBUTES['']


HIGHLIGHTS = dict(
        list(zip([
            'on_grey',
            'on_red',
            'on_green',
            'on_yellow',
            'on_blue',
            'on_magenta',
            'on_cyan',
            'on_white'
            ],
            list(range(40, 48))
            ))
        )


COLORS = dict(
        list(zip([
            'grey',
            'red',
            'green',
            'yellow',
            'blue',
            'magenta',
            'cyan',
            'white',
            ],
            list(range(30, 38))
            ))
        )


RESET = '\033[0m'


def colored(text, color=None, on_color=None, attrs=None):
    """Colorize text.

    Available text colors:
        red, green, yellow, blue, magenta, cyan, white.

    Available text highlights:
        on_red, on_green, on_yellow, on_blue, on_magenta, on_cyan, on_white.

    Available attributes:
        bold, dark, underline, blink, reverse, concealed.

    Example:
        colored('Hello, World!', 'red', 'on_grey', ['blue', 'blink'])
        colored('Hello, World!', 'green')
    """
    if os.getenv('ANSI_COLORS_DISABLED') is None:
        fmt_str = '\033[%dm%s'
        if color is not None:
            text = fmt_str % (COLORS[color], text)

        if on_color is not None:
            text = fmt_str % (HIGHLIGHTS[on_color], text)

        if attrs is not None:
            for attr in attrs:
                text = fmt_str % (ATTRIBUTES[attr], text)

        text += RESET
    return text


def cprint(text, color=None, on_color=None, attrs=None, **kwargs):
    """Print colorize text.

    It accepts arguments of print function.
    """

    print((colored(text, color, on_color, attrs)), **kwargs)


if __name__ == '__main__':
    print('Current terminal type: %s' % os.getenv('TERM'))
    print('Test basic colors:')
    cprint('Grey color', 'grey')
    cprint('Red color', 'red')
    cprint('Green color', 'green')
    cprint('Yellow color', 'yellow')
    cprint('Blue color', 'blue')
    cprint('Magenta color', 'magenta')
    cprint('Cyan color', 'cyan')
    cprint('White color', 'white')
    print(('-' * 78))

    print('Test highlights:')
    cprint('On grey color', on_color='on_grey')
    cprint('On red color', on_color='on_red')
    cprint('On green color', on_color='on_green')
    cprint('On yellow color', on_color='on_yellow')
    cprint('On blue color', on_color='on_blue')
    cprint('On magenta color', on_color='on_magenta')
    cprint('On cyan color', on_color='on_cyan')
    cprint('On white color', color='grey', on_color='on_white')
    print('-' * 78)

    print('Test attributes:')
    cprint('Bold grey color', 'grey', attrs=['bold'])
    cprint('Dark red color', 'red', attrs=['dark'])
    cprint('Underline green color', 'green', attrs=['underline'])
    cprint('Blink yellow color', 'yellow', attrs=['blink'])
    cprint('Reversed blue color', 'blue', attrs=['reverse'])
    cprint('Concealed Magenta color', 'magenta', attrs=['concealed'])
    cprint('Bold underline reverse cyan color', 'cyan',
            attrs=['bold', 'underline', 'reverse'])
    cprint('Dark blink concealed white color', 'white',
            attrs=['dark', 'blink', 'concealed'])
    print(('-' * 78))

    print('Test mixing:')
    cprint('Underline red on grey color', 'red', 'on_grey',
            ['underline'])
    cprint('Reversed green on red color', 'green', 'on_red', ['reverse'])
Reply
#5
(Sep-21-2019, 03:37 PM)newbieAuggie2019 Wrote: The f-string formatting seems to be the advisable choice since Python 3.6, so I want to be able to learn properly about them.
You should learn f-string without mixing in termcolor cprint().
cprint() takes different argument to function,not so much sense with all arguments to try to make it in one line.
>>> help(cprint)
Help on function cprint in module termcolor:

cprint(text, color=None, on_color=None, attrs=None, **kwargs)
    Print colorize text.
    
    It accepts arguments of print function.
The text part can manipulate with f-sting,the other arguments to make it all in line dos not make so much sense here.
import sys
from termcolor import colored, cprint

cprint('\nThis is ', end='')
cprint(f'{"dangerous".upper():~^20}', 'green', attrs=['reverse', 'blink'], end='')
cprint('... for my mental health!', end='\n\n')
[Image: S32I8x.png]
Reply
#6
(Sep-21-2019, 05:08 PM)ThomasL Wrote: I would suggest you look into the termcolor package and investigate how cprint() works.
Hi!
Thank you for your answer!
The problem is that I'm a newbie, so I understand what a simple print command does, like:
a = 5
b = 7

print(a + b)
producing a simple output:
12 so seeing this in the file termcolor.py, that you kindly included:
print((colored(text, color, on_color, attrs)), **kwargs)
made me get really lost on many sites, trying to understand what *args and **kwargs are and how to handle them ... Cry

When I looked at the file termcolor.py and saw these lines (I left out the ones not suitable for my problem):
from __future__ import print_function
import os

print('Test attributes:')
cprint('Bold grey color', 'grey', attrs=['bold'])
cprint('Underline green color', 'green', attrs=['underline'])
cprint('Bold underline reverse cyan color', 'cyan', attrs=['bold', 'underline', 'reverse'])

print('Test mixing:')
cprint('Underline red on grey color', 'red', 'on_grey', ['underline'])
cprint('Reversed green on red color', 'green', 'on_red', ['reverse'])
where commands in the format:
cprint('Underline green color', 'green', attrs=['underline'])
could be simplified to the format:
cprint('Underline red on grey color', 'red', 'on_grey', ['underline'])
I thought that I could imitate the expression where attrs=['underline'] was simplified to ['underline'] and modify it to adapt it to the f-formatting with ['underline'] and ['bold'] (two characteristics, instead of just one), but when I tried some combinations, I got error messages like:
Error:
SyntaxError: invalid syntax
Error:
SyntaxError: keyword argument repeated
Error:
TypeError: unhashable type: 'list'
Error:
KeyError: 'underline'
and many more ... Think

All the best,

(Sep-21-2019, 07:32 PM)snippsat Wrote: cprint() takes different argument to function, not so much sense with all arguments to try to make it in one line.

I'm beginning to understand and accept that.

(Sep-21-2019, 07:32 PM)snippsat Wrote: The text part can manipulate with f-string, the other arguments to make it all in line dos not make so much sense here.

I think now that it was just a stupid wish of mine to compare the packages on the same ground while at the same time, applying a topic that I wanted to learn more about (f-strings).

[Image: S32I8x.png]
cprint(f'{"dangerous".upper():~^20}', 'green', attrs=['reverse', 'blink'], end='')
Dance Thank you! I've just learned another interesting bit of Python!

All the best,
newbieAuggie2019

"That's been one of my mantras - focus and simplicity. Simple can be harder than complex: You have to work hard to get your thinking clean to make it simple. But it's worth it in the end because once you get there, you can move mountains."
Steve Jobs
Reply
#7
I was able to get f-strings to work with termcolor using :

print(f"been idle for", colored(f"{total}", 'cyan'), "seconds !! - lets sync now...")

been idle for 6 seconds !! - lets sync now...
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Trying to understand strings and lists of strings Konstantin23 2 696 Aug-06-2023, 11:42 AM
Last Post: deanhystad
  Splitting strings in list of strings jesse68 3 1,702 Mar-02-2022, 05:15 PM
Last Post: DeaD_EyE
  Finding multiple strings between the two same strings Slither 1 2,478 Jun-05-2019, 09:02 PM
Last Post: Yoriz
  colorama/termcolor not returning coloured lines kapilan15 3 6,709 Jan-14-2019, 12:57 PM
Last Post: buran
  lists, strings, and byte strings Skaperen 2 4,181 Mar-02-2018, 02:12 AM
Last Post: Skaperen

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020