So I know how to color text, I am using a class to define colors and then using that in a print statements -
class color:
purple = '\033[95m'
cyan = '\033[96m'
darkcyan = '\033[36m'
blue = '\033[94m'
green = '\033[92m'
yellow = '\033[93m'
end = '\033[0m'
print(color.green + This makes the text green! + color.end)
But I am working on a project for CSE class and there will lots of text to read, and eventually all the white just blends together, so using colored text makes things easier so I was wondering if there was an easier, less time consuming, way of doing things?
You could implement your own function that accepts the text and color, inserts the necessary codes, and prints. If you want to use a class, like you're doing, I'd recommend subclassing Enum, and naming the colors themselves in all caps, which is the Python convention for constants. (Also if you haven't seen f-strings before, I'd recommend giving them a look.)
from enum import Enum
class Color(Enum):
PUPLE = 95
CYAN = 96
DARK_CYAN = 36
BLUE = 94
GREEN = 92
YELLOW = 93
# (Add any further colors you want to use...)
def color_print(text, color):
"""Print text in the specified color."""
if color not in Color:
raise KeyError(f'Invalid text color: {color}')
print(f'\033[{color.value}m{text}\033[0m')
Which you can use like so:
color_print('This text should be blue.', Color.BLUE)
You could also accomplish the same thing with a dictionary. I'm not sure one method is any better or cleaner than the other, so you could pick whichever reads better to you and seems like it would be more convenient to use.
COLORS = {
'purple': 95,
'cyan': 96,
'dark_cyan': 36,
'blue': 94,
'green': 92,
'yellow': 93,
# (Add any further colors you want to use...)
}
def color_print(text, color):
"""Print text in the specified color."""
try:
code = COLORS[color]
except KeyError:
raise KeyError(f'Invalid text color: {color}')
print(f'\033[{code}m{text}\033[0m')
For this approach, you'd specify the color as a string rather than as a member of the Enum:
color_print('This text should be blue.', 'blue')
If you'd like a readymade solution, there's also the Rich package. It has an impressive list of capabilities, including but certainly not limited to printing in specified colors. Probably the simplest way to replicate the above in it would look like this:
from rich.console import Console
console = Console()
console.print('This text shoudl be blue', style="blue")
Rich can also do things like wrap and justify text, set foreground and background colors, make text blink, include emojis, and (perhaps most usefully, in my opinion) intelligently color-code data output with syntax highlighting right in the terminal. I just discovered this library myself, and I recommend giving it a look.
Related
im trying to set a report default background color but it appears black instead of blue, can anyone help?
Why is that? do i need to use another format that is not hex? iv tryied with other format and still nothing.
docpath="/Users/ricardosimoes/Desktop/DESKTOP/Jira/my_word_file.docx"
mydoc = docx.Document()
section_h = mydoc.sections[0]
header = section_h.header
styles = mydoc.styles
style = styles.add_style('Tahoma',WD_STYLE_TYPE.PARAGRAPH)
style.font.name = 'Tahoma'
style.font.size = Pt(11)
shd = OxmlElement('w:background')
# Add attributes to the xml element
shd.set(qn('w:color'), '#0000FF')
shd.set(qn('w:themeColor'), 'text1')
shd.set(qn('w:themeTint'), 'F2')
# Add background element at the start of Document.xml using below
mydoc.element.insert(0, shd)
# Add displayBackgroundShape element to setting.xml
shd1 = OxmlElement('w:displayBackgroundShape')
mydoc.settings.element.insert(0, shd1)
paragraph_h = header.paragraphs[0]
runheader = paragraph_h.add_run()
runheader.add_picture("client_report/report_img/titulo.png", width=docx.shared.Inches(5), height=docx.shared.Inches(1))
mydoc.add_picture("client_report/report_img/bottom.png", width=docx.shared.Inches(5),
height=docx.shared.Inches(1))
mydoc.save(docpath)
The snippet seems to supply all three of the w:color, w:themeColor and w:themeTint attributes, and the latter two override the first one. The ECMA-376 standard says about the w:color attribute:
If the background specifies the use of a theme color via the themeColor attribute, this value is ignored. [Note: Applications are discouraged from specifying both the color and themeColor attributes on the same parent element. end note]
I haven't tested this, but removing themeColor and themeTint (and dropping the # from 0000FF) should cause the blue color to show up.
Is there a way to access the value of a variable without taking the variables name?
I am trying to write a project which has an external constants file for colour definitions which I will use in the various programs to de-clutter my code.
The colours are set as RGB with the colour name such as:
BLACK = (0,0,0)
An example of the class which will use the colour is:
class Window:
def __init__(self,w_width,w_height,w_colour,fps=60):
pygame.init()
self.w_width = w_width
self.w_height = w_height
self.fps = fps
self.w_colour = w_colour
self.screen = pygame.display.set_mode((self.w_width,self.w_height))
self.clock = pygame.time.Clock()
self.screen.fill(constants.self.w_colour)
And am coming into the error where constants.self.w_colour doesn't exist (which I understand as i'm assuming it is looking for a self.w_colour within the constants file which I know doesn't exist). But the value of self.w_colour could be BLACK or some other value which I know is contained in the constants file.
I was wondering if there is a way to call the constants.self.w_colour by taking the value of self.w_colour and not python trying to follow it as a path?
Apologies if it doesn't make much sense but i've tried to describe it in the best way I can.
I'm assuming you're throwing all of your constants in a file called constants.py somewhere. If so, the quick-and-dirty solution is to use __dict__.
import constants
my_favorite_color = constants.__dict__[color_name]
but that's messy and would confuse folks reading the code. If you intend that constants be accessed as a dictionary, then it would be best to make that explicit. In constants.py, consider
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
# ... more colors
# Then at the bottom
COLORS = {
'BLACK': BLACK,
'WHITE': WHITE,
}
Then you can use it as
from constants import COLORS
my_favorite_color = COLORS[color_name]
It's a bit more verbose, but in the words of a wise man, "explicit is better than implicit".
I'd like to find the window background color in HEX format. Looking for a solution that works on all platforms... Windows/Linux/Mac...
The following code print (self.cget('bg')) just prints SystemButtonFace but I'd like to get the actual HEX format. The reason is that I need to use this color as a base to create a new slightly darker color shade.
The winfo_rgb method on all widgets will accept a color name and return the r, g, and b components as integers in the range of 0-65535 (16 bits). You can then convert those to hex using standard python string formatting.
Thanks to Bryan Oakley's answer wrote this method:
def get_widget_hex_color_by_known_name(w, knwon_system_color):
"""
w is a tkinter widget i.e. tk.Button() or self
knwon_system_color can be any known color name like white, green, SystemButtonFace
"""
rgb = w.winfo_rgb(knwon_system_color)
r,g,b=[x>>8 for x in rgb]
return '#{:02x}{:02x}{:02x}'.format(r,g,b)
Note that self.cget('bg') returns something like SystemButtonFace on Windows, but on Linux it actually return the hex color code.
So I only need to call the function above if the self.cget('bg') call does not return a hex color code (string length 7 starting with #).
For generating PDF files with reportlab / python, it is possible to define very easily the color of a text (and lot other things) by using the so called "Paragraph XML Markup Tags". For example a green text:
rapport.append(Paragraph('<font size = 14 color = "green" > <b> Toto is a naugthy boy </b></font>', styles['Left']))
But, is it possible to define our own color (for example by using RGB code) ?
It is actually really straightforward, you can just replace green with any hex RGB color like #424242. So in your example it will look like this:
rapport.append(Paragraph('<font size=14 color="#424242"><b>Toto is a naugthy boy</b></font>', styles['Left']))
But it is also possible to use most of the HTML colors like:
rapport.append(Paragraph('<font size=14 color="rgb(191, 255, 0)"><b>Toto is a naugthy boy</b></font>', styles['Left']))
rapport.append(Paragraph('<font size=14 color="hsl(75, 100%, 50%)"><b>Toto is a naugthy boy</b></font>', styles['Left']))
From this question I learned how to color Python. I figured out all the color codes, don't worry.
Anyway, the answer that worked for me was the ctypes one by orip. It's a bit tiresome to have to have to type ctypes.windll.kernel32.SetConsoleTextAttribute(handle, AQUA) every time I want to color text. Is there a way to convert it into a function? I'm not sure how to send variables through functions, and not sure how to implement them, even if I did.
Thanks in advance! -ghostmancer
All that matters for me is that it works for me - I'm not planning to give my script away.
My colors:
BLACK = 0x0000
BLUE = 0x0001
GREEN = 0x0002
RED = 0x0004
PURPLE = 0x0005
YELLOW = 0x0006
WHITE = 0x0007
GRAY = 0x0008
GREY = 0x0008
AQUA = 0x0009 #Very Blue
ummm... if i understand right ...
def a_func(handle,color):
ctypes.windll.kernel32.SetConsoleTextAttribute(handle, color)
a_func(handle,AQUA)
or even better
colorFunc = ctypes.windll.kernel32.SetConsoleTextAttribute
colorFunc(handle,AQUA)
no need to create a new function with def or lambda, just assign the function with a long name to a shorter name, e.g:
textcolor = ctypes.windll.kernel32.SetConsoleTextAttribute
textcolor(handle, color)
One way is
def textcolor(handle, color):
ctypes.windll.kernel32.SetConsoleTextAttribute(handle, color)
which you call like so:
textcolor(handle, AQUA)
You can use:
f=lambda handle,color:ctypes.windll.kernel32.SetConsoleTextAttribute(handle, color)
and, call f(<Actual handle object>, <color>) wherever you want.
e.g. f(handle, AQUA) would be the required call
Because I see the variable 'handle' everywhere without being defined and for anyone who wonders, here is a way to get it, as far as stdout is concerned, so that we can used it with ctypes.windll.kernel32.SetConsoleTextAttribute(handle, color):
STD_OUTPUT_HANDLE = -11
handle = ctypes.windll.kernel32.GetStdHandle(-STD_OUTPUT_HANDLE)