Frustrated? Keep Digging. Don't Quit

 

I sometimes pontificate to others on Reddit's r/learnpython that frustration is good.

It makes you angry. Anger is a strong emotion. A motivating emotion. It nags at you all night long.

You wake up in the middle of the night thinking you finally have the answer. You run to the terminal and furiously type in your new idea.

Alas, no! That idea didn't work either! Damn.

Maybe I should just give up? 

Another day. Another night.

You scour the internet. Surely others have faced the same problem. If only I can properly phrase my Google search or AI prompt to find their solutions! (BTW, image on the right is from Easy-Peasy.AI

Well, today, I had to eat my own humbling pie.
The brilliant idea had occurred to me that I could dynamically attach COLORAMA commands into my string printing using a function call and a dictionary translation. The COLORAMA module (class?) has three objects named "Fore" (for foreground color), "Back" (for background color) and "Style" (for defining brightness). Each of these has attributes. For example, if you insert Fore.MAGENTA into your string (after importing Colorama), it will cause the on-screen printout to be of the magenta color.
(BTW, image on the right is again from Easy-Peasy.AI)

I thought I could simply concatenate a "Fore," string with a variable color-naming string (e.g. "MAGENTA") and that would invoke the desired COLORAMA method. Can't do that. So frustration hits me, the pontificator to others, right back in my own face. I'm banging my head against the wall. There must be a way. There must be a way. 

Long story, short. There is a way. It's called the getattr() function already built into Python (see here).

My relevant code is in the below:
(I'll explain it later below)

clr: dict = {'b':"BLACK", 'r':"RED", 'g':"GREEN", 'y':"YELLOW", 'u':"BLUE", 'm':"MAGENTA", 'c':"CYAN", 'w':"WHITE",
             'o':"RESET",
             'B':"LIGHTBLACK_EX", 'R':"LIGHTRED_EX", 'G':"LIGHTGREEN_EX", 'Y':"LIGHTYELLOW_EX", 'U':"LIGHTBLUE_EX",
             'M':"LIGHTMAGENTA_EX", 'C':"LIGHTCYAN_EX", 'W':"LIGHTWHITE_EX",
             'D':"DIM", 'N':"NORMAL", 'H':"BRIGHT", 'O':"RESET_ALL"}
#^^ in above, single letter for Fore color alone, 2 chars for Fore + Back, 3 chars for Style + Fore + Back in that order


def cj(chars: str = 'HWb', d: dict = clr):     #-- COLORAMA color commands generator using the clr dictionary
    numb = len(chars)
    if numb < 1:
        print(f'argument error in cj function call')
        return None
    elif numb < 2:
        sum: str = getattr(Fore, d[f'{chars[0]}'])    #-- if one char it is FORE color
        return sum                                    #-- add list of valid chars to check ?
    elif numb < 3:
        sum: str = getattr(Fore, d[f'{chars[0]}'])  + getattr(Back, d[f'{chars[1]}']) # -- if 2 chars
        return sum
    elif numb < 4:
        sum: str = getattr(Style, d[f'{chars[0]}'])  + getattr(Fore, d[f'{chars[1]}'])  + getattr(Back, d[f'{chars[2]}']) # -- if 3
        return sum
    else:
        print(f'arguments error in cj function call')
        return None


def slm(mssg="MID MESSAGE GOES HERE", filler="**", times=2):   #-- mid box messages
    outp: str = cj('HWb') + filler + cj('HMb') + mssg.center(90-4) +cj('HWb') + filler
    print(outp)


And finally the color coded outputs:

I hate deciphering other people's code. This post is supposed to be for others like me who are just starting to learn Python. So here is what is going on in the above panels.

The first panel creates a dictionary variable for converting single letters like "w", "b", "y" into longer strings like "WHITE", "BLACK", "YELLOW"; where the latter are attributes recognized by the Colorama objects, namely, Fore, Back and Style. Yes, I know this is inefficient because we could have skipped using Colorama and translated directly into the ANSI escape sequences. But that is not the goal of this exercise, The goal is to use a recognized module and to abbreviate its method calls.

The second panel shows the creation of a function called "cj" (for command jenerator -ha ha) that receives an input string ("chars') that can be either one character long, or two, or three. If just one, it is a Fore color. If two, it is Fore first followed by a Back color. If it is three chars long, it is a Style first, followed by Fore and then a Back color. So we test for length of the input chars string and then use the getattr() function to form the appropriate attribute call.

The third panel is one of several functions that are used to form a message box like the one shown in the fourth panel. This function, slm (for single line middle message) calls on the cj() color generator to define the desired colors (e.g. magenta for the center middle string) along the output line. We can reuse this and the other functions to generate other message boxes with desired colors.

My code (not shown) also has functions for taking in single keyboard presses (using the keyboard module) for activating next presentations. We'll leave that for another day.

Check out the below, "More to Explore" section.

More to Explore
If you're struggling to learn to code, you must watch this
This is Why Programming Is Hard
How to Not Get Frustrated When Stuck Coding
How to become a Python developer FAST
Python Tutorial for Beginners - Full Course in 11 Hours [2020]
Python dictionaries are easy

Comments

Popular posts from this blog

Links for Python Noobs

I Lied

Everything From Everywhere All At Once -- Doesn't Fly