I have been testing printing colors and characters in VS Code (version 1.69) using python 3.+. To print colored text in VS code you would use:
print("\033[31mThis is red font.\033[0m")
print("\033[32mThis is green font.\033[0m")
print("\033[33mThis is yellow font.\033[0m")
print("\033[34mThis is blue font.\033[0m")
print("\033[37mThis is the default font. \033[0m")
Special characters would be like the following:
print("\1\2\3\4\05\06\07\016\017\013\014\020")
print("\21\22\23\24\25\26\27\36\37\31\32\34\35")
Part 1 of my question: How would you print special characters from a loop? What I tried is:
for i in range(1, 99):
t = "\\" + str(i)
print(t)
Part 2: Is there a way to print dark text with a colored highlighted background?
The first example is showing ansi escape sequences, the second example is using a common convention in many languages, including Python, to include non-standard characters in a string by escaping their character value, but in your example, you may not be realising that you're escaping octal values, instead of decimal ones.
Printing them is no different from printing any character though - I think you may be confusing printing strings representing values and the actual values of variables, a very common mistake/confusion for beginning programmers. If you want to be able to print ('\21') without writing out the string, you could just print(chr(17)), because 17 is the decimal equivalent of octal 21.
Have a look at the documentation for string literals for more detail.
The loop you're trying to create would be something like:
for i in range(1, 99):
print(chr(i))
But you have to keep in mind that if i gets to 21, it's not printing '\21', but '\25' since 25 is the octal representation of the decimal value 21.
Note: also, you're asking specifically about VSCode, but that's a different question altogether. Whether or not the console in VSCode supports printing ANSI escape sequences depends on the type of terminal, it doesn't really have that much to do with what you do in your code. However, if you want ANSI escape sequences to render in text files, there's extensions for that.
Related
The following python code has some weird behavior which I don't understand
print('\x1bZ')
when I run this code whether in a file or in the interpreter I have a wierd outcome:
actual values as displayed when you write this value to a file as bytes:
Discoveries at time of posting this question:
whether single quotes or double quotes make a difference (they don't)
0x1b is hex for 27 which in ascii is ESC which matches as displayed with the second picture. This lead me to theorize that the letter Z in the string literal can be replaced but as per my test in point number 3 it cant be reproduced with other letters
instead of \x1bZ (ESC and then Z) trying ESC and then some other letter (I haven't checked all possibilities) yielded no apparent result except from replacing Z with c which seems to clear the terminal
Hypothesis that I came up with:
This page may be relevant to the answer: https://pypi.org/project/py100/ because I have found a pattern there that resembles weird result: Esc[?1;Value0c where Value would be replaced by something. also ^[[?1;<n>0c appears in https://espterm.github.io/docs/VT100%20escape%20codes.html
Is this some encoding problem?
Is this related to ANSI character escaping? [?1;0c vs [38;2; which is used when changing background color of text
Questions:
Why is this particular sequence of characters results in this output?
What is VT100 and how it is related if it is related? (I visited it's Wikipedia page)
whether it is possible to print a string that contains this specific sequence without that weird outcome as displayed in the first picture
all help and knowledge about this will be appreciated!!
I am wondering if I can have print() outputs such as
in a terminal and/or an IPython/Jupyter Notebook. I want to develop a library working with toleranced dimensions and these types of pretty-printed outputs will come quite handy during development and testing.
What I know so far:
There are escape characters such as Carriage Return \r that goes to the beginning of the line without erasing the existing characters and the Backspace \b that deletes the last character. For example print("some text\bsome other text \rbingo", end="") should give me bingotexsome other text. Anyway, when printing a new character the previous one is erased.
I also know how to use Unicode characters to have superscripted/subscripted digits and plus/minus signs. For example, the print('1.23\u207a\u2074\u2027\u2075\u2076') will give me something like 1.23+4.56 and print('1.23\u208b\u2087.\u2088\u2089') outputs close to 1.23-7.89. Although what unicode characters should be used for superscript/subscript decimal delimiters (in this case period/dot/point) is still debatable. There are multiple options for superscipted dot including also \u0387 and \u22c5. However, AFIK there are no unicode characters suitable for subscripted dot. (more info here)
what I don't know
if there is an escape character or Unicode one that replicates the left arrow ← key on the keyboard?
how to print without erasing the pixels in the terminal? Is there a way to print/display characters on top of each other?
and if none of the above is possible in a terminal, if/how I can control the HTTP/CSS outputs in a Jupyter Notebook to print both superscript and subscript at the same time?
In Jupyter Notebook/Lab this should work:
from IPython.display import Math
Math(r"1.23^{+4.56}_{-7.89}")
For convenience, you can package it in a class:
from IPython.display import Math
class PPrint:
def __init__(self, base, sub, sup):
self.base = base
self.sub = sub
self.sup = sup
def _ipython_display_(self):
display(Math(f"{{{self.base}}}^{{{self.sub}}}_{{{self.sup}}}"))
Then you can create an instance e.g.:
x = PPrint("1.23", "+4.56", "-7.89")
and if you execute in a notebook either x or display(x), it should appear as in your example.
In Python 3.4.3, I was trying to width-align some fields using the string.format() operator, and it appears to count zero-length control characters against the width total. Sample code:
ANSI_RED = "\033[31m"
ANSI_DEFAULT="\033[39m\033[49m"
string1 = "12"
string2 = ANSI_RED+"12"+ANSI_DEFAULT
print("foo{:4s}bar".format(string1))
print("foo{:4s}bar".format(string2))
This will output:
foo12 bar
foo12bar
(with the second output having '12' in red, but I can't reproduce that in SO)
In the second case, I've lost my field width, I assume because Python saw that the total number of chars in the string was larger than the width, despite most of those chars resulting in zero-length on an ANSI-conforming terminal.
What's a clean way of having ANSI colors and working field widths?
What's a clean way of having ANSI colors and working field widths?
Unfortunately, you will have to strip the escape sequences to get a displayed field width.
The len() function returns the number of bytes in a Python 2 str type and the number of code points in a Python 3 str type. That length has never been guaranteed to match the display width (which is a more challenging problem):
>>> s = 'abc\bde'
>>> print s
abcde
>>> len(s)
6
In general, you can't know the display width for certain unless you know something about how the display will interpret the codes (i.e. the width is different depending on whether the device supports ANSI escape sequences).
I don't know if it will qualify as "clean" but something in the vain of the following is workable:
print("foo{0}{1:4s}{2}bar".format(ANSI_RED, string1, ANSI_DEFAULT))
Getting terminal control codes right is really difficult (as seen below, not all of them have a well-defined width), so your best bet is probably to use explicit column movement.
# string2 defined as above
def col(n): return "\033[{:d}G".format(n)
print("foo{:s}{:s}bar".format(string2,col(8)))
Output:
foo12 bar
Given two nearly identical text files (plain text, created in MacVim), I get different results when reading them into a variable in Python. I want to know why this is and how I can produce consistent behavior.
For example, f1.txt looks like this:
This isn't a great example, but it works.
And f2.txt looks like this:
This isn't a great example, but it wasn't meant to be.
"But doesn't it demonstrate the problem?," she said.
When I read these files in, using something like the following:
f = open("f1.txt","r")
x = f.read()
I get the following when I look at the variables in the console. f1.txt:
>>> x
"This isn't a great example, but it works.\n\n"
And f2.txt:
>>> y
'This isn\'t a great example, but it wasn\'t meant to be. \n"But doesn\'t it demonstrate the problem?," she said.\n\n'
In other words, f1 comes in with only escaped newlines, while f2 also has its single quotes escaped.
repr() shows what's going on. first for f1:
>>> repr(x)
'"This isn\'t a great example, but it works.\\n\\n"'
And f2:
>>> repr(y)
'\'This isn\\\'t a great example, but it wasn\\\'t meant to be. \\n"But doesn\\\'t it demonstrate the problem?," she said.\\n\\n\''
This kind of behavior is driving me crazy. What's going on and how do I make it consistent? If it matters, I'm trying to read in plain text, manipulate it, and eventually write it out so that it shows the properly escaped characters (for pasting into Javascript code).
Python is giving you a string literal which, if you gave it back to Python, would result in the same string. This is known as the repr() (short for "representation") of the string. This may not (probably won't, in fact) match the string as it was originally specified, since there are so many ways to do that, and Python does not record anything about how it was originally specified.
It uses double quotes around your first example, which works fine because it doesn't contain any double quotes. The second string contains double quotes, so it can't use double quotes as a delimiter. Instead it uses single quotes and uses backslashes to escape the single quotes in the string (it doesn't have to escape the double quotes this way, and there are more of them than there are single quotes). This keeps the representation as short as possible.
There is no reason for this behavior to drive you crazy and no need to try to make it consistent. You only get the repr() of a string when you are peeking at values in Python's interactive mode. When you actually print or otherwise use the string, you get the string itself, not a reconstituted string literal.
If you want to get a JavaScript string literal, the easiest way is to use the json module:
import json
print json.dumps('I said, "Hello, world!"')
Both f1 and f2 contain perfectly normal, unescaped single quotes.
The fact that their repr looks different is meaningless.
There are a variety of different ways to represent the same string. For example, these are all equivalent literals:
"abc'def'ghi"
'abc\'def\'ghi'
'''abc'def'ghi'''
r"abc'def'ghi"
The repr function on a string always just generates some literal that is a valid representation of that string, but you shouldn't depend on exactly which one it generate. (In fact, you should rarely use it for anything but debugging purposes in the first place.)
Since the language doesn't define anywhere what algorithm it uses to generate a repr, it could be different for each version of each implementation.
Most of them will try to be clever, using single or double quotes to avoid as many escaped internal quotes as possible, but even that isn't guaranteed. If you really want to know the algorithm for a particular implementation and version, you pretty much have to look at the source. For example, in CPython 3.3, inside unicode_repr, it counts the number of quotes of each type; then if there are single quotes but no double quotes, it uses " instead of '.
If you want "the" representation of a string, you're out of luck, because there is no such thing. But if you want some particular representation of a string, that's no problem. You just have to know what format you want; most formats, someone's already written the code, and often it's in the standard library. You can make C literal strings, JSON-encoded strings, strings that can fit into ASCII RFC822 headers… But all of those formats have different rules from each other (and from Python literals), so you have to use the right function for the job.
In Python v2.6 I can get hexadecimal for my integers in one of two ways:
print(("0x%x")%value)
print(hex(value))
However, in both cases, the hexadecimal digits are lower case. How can I get these in upper case?
Capital X (Python 2 and 3 using sprintf-style formatting):
print("0x%X" % value)
Or in python 3+ (using .format string syntax):
print("0x{:X}".format(value))
Or in python 3.6+ (using formatted string literals):
print(f"0x{value:X}")
Just use upper().
intNum = 1234
hexNum = hex(intNum).upper()
print('Upper hexadecimal number = ', hexNum)
Output:
Upper hexadecimal number = 0X4D2
print(hex(value).upper().replace('X', 'x'))
Handles negative numbers correctly.
By using uppercase %X:
>>> print("%X" % 255)
FF
Updating for Python 3.6 era: Just use 'X' in the format part, inside f-strings:
print(f"{255:X}")
(f-strings accept any valid Python expression before the : - including direct numeric expressions and variable names).
The more Python 3 idiom using f-strings would be:
value = 1234
print(f'0x{value:X}')
'0x4D2'
Notes (and why this is not a duplicate):
shows how to avoid capitalizing the '0x' prefix, which was an issue in other answers
shows how to get variable interpolation f'{value}'; nobody actually ever puts (hardcoded) hex literals in real code. There are plenty of pitfalls in doing variable interpolation: it's not f'{x:value}' nor f'{0x:value}' nor f'{value:0x}' nor even f'{value:%x}' as I also tried. So many ways to trip up. It still took me 15 minutes of trial-and-error after rereading four tutorials and whatsnew docs to get the syntax. This answer shows how to get f-string variable interpolation right; others don't.