Python 3.6 literal strings - python

I'm having a hard time finding what can be put inside literal strings.
For example, I've seen this code on the PEP above, yet I didn't find any information above about what it does.
>>> value = 1234
>>> f'input={value:#06x}'
'input=0x04d2'
Is there a tutorial for understanding string literals better?

What's new here is that you can just literally write value inside the f-string and Python will insert it.
The #06x part is nothing new and just a way to format numbers in hexadecimal representation. Python2:
>>> value = 1234
>>> '{:#06x}'.format(value)
'0x04d2'
# says to prefix the output (here with 0x).
06 says pad left with zeroes such that the output has at least length 6.
x is the hex format specifier.
You can read all about it here.

Related

F-string error in Python - What does the equals sign mean? [duplicate]

The usage of {} in Python f-strings is well known to execute pieces of code and give the result in string format (some tutorials here). However, what does the '=' at the end of the expression mean?
log_file = open("log_aug_19.txt", "w")
console_error = '...stuff...' # the real code generates it with regex
log_file.write(f'{console_error=}')
This is actually a brand-new feature as of Python 3.8.
Added an = specifier to f-strings. An f-string such as f'{expr=}'
will expand to the text of the expression, an equal sign, then the
representation of the evaluated expression.
Essentially, it facilitates the frequent use-case of print-debugging, so, whereas we would normally have to write:
f"some_var={some_var}"
we can now write:
f"{some_var=}"
So, as a demonstration, using a shiny-new Python 3.8.0 REPL:
>>> print(f"{foo=}")
foo=42
>>>
From Python 3.8, f-strings support "self-documenting expressions", mostly for print de-bugging. From the docs:
Added an = specifier to f-strings. An f-string such as f'{expr=}' will
expand to the text of the expression, an equal sign, then the
representation of the evaluated expression. For example:
user = 'eric_idle'
member_since = date(1975, 7, 31)
f'{user=} {member_since=}'
"user='eric_idle' member_since=datetime.date(1975, 7, 31)"
The usual f-string format specifiers allow more control over how the
result of the expression is displayed:
>>> delta = date.today() - member_since
>>> f'{user=!s} {delta.days=:,d}'
'user=eric_idle delta.days=16,075'
The = specifier will display the whole expression so that calculations
can be shown:
>>> print(f'{theta=} {cos(radians(theta))=:.3f}')
theta=30 cos(radians(theta))=0.866
This was introduced in python 3.8. It helps reduce a lot of f'expr = {expr} while writing codes. You can check the docs at What's new in Python 3.8.
A nice example was shown by Raymond Hettinger in his tweet:
>>> from math import radians, sin
>>> for angle in range(360):
print(f'{angle=}\N{degree sign} {(theta:=radians(angle))=:.3f}')
angle=0° (theta:=radians(angle))=0.000
angle=1° (theta:=radians(angle))=0.017
angle=2° (theta:=radians(angle))=0.035
angle=3° (theta:=radians(angle))=0.052
angle=4° (theta:=radians(angle))=0.070
angle=5° (theta:=radians(angle))=0.087
angle=6° (theta:=radians(angle))=0.105
angle=7° (theta:=radians(angle))=0.122
angle=8° (theta:=radians(angle))=0.140
angle=9° (theta:=radians(angle))=0.157
angle=10° (theta:=radians(angle))=0.175
...
You can also check out this to get the underlying idea on why this was proposed in the first place.
As mention here:
Equals signs are now allowed inside f-strings starting with Python 3.8. This lets you quickly evaluate an expression while outputting the expression that was evaluated. It's very handy for debugging.:
It mean it will run the execution of the code in the f-string braces, and add the result at the end with the equals sign.
So it virtually means:
"something={executed something}"
f'{a_string=}' is not exactly the same as f'a_string={a_string}'
The former escapes special characters while the latter does not.
e.g:
a_string = 'word 1 tab \t double quote \\" last words'
print(f'a_string={a_string}')
print(f'{a_string=}')
gets:
a_string=word 1 tab double quote \" last words
a_string='word 1 tab \t double quote \\" last words
I just realised that the difference is that the latter is printing the repr while the former is just printing the value. So, it would be more accurate to say:
f'{a_string=}' is the same as f'a_string={a_string!r}'
and allows formatting specifications.

Is it possible to use format() function with a string in format's place?

I'm using a format() in python and I want to use a variable pokablelio so that the person could choose how many numbers to output after the dot. When I try to put the variable alone after the comma it outputs: ValueError: Invalid format specifier. I tried replacing some characters or making the whole string in a parentheses but that didn't work.
Right now I'm wondering: Can I even use a variable as a string to put it in format's place?
(note: The machine should have a "'.10f'" string in the variable)
Error and the code
It is possible to use variables as part of the format specifier, just include them inside additional curly braces:
>>> n_places = 10
>>> f'{1.23:.{n_places}f}'
'1.2300000000'

Import string that looks like a list "[0448521958, +61439800915]" from JSON into Python and make it an actual list?

I am extracting a string out of a JSON document using python that is being sent by an app in development. This question is similar to some other questions, but I'm having trouble just using x = ast.literal_eval('[0448521958, +61439800915]') due to the plus sign.
I'm trying to get each phone number as a string in a python list x, but I'm just not sure how to do it. I'm getting this error:
raise ValueError('malformed string')
ValueError: malformed string
your problem is not just the +
the first number starts with 0 which is an octal number ... it only supports 0-7 ... but the number ends with 8 (and also has other numbers bigger than 8)
but it turns out your problems dont stop there
you can use regex to fix the plus
fixed_string = re.sub('\+(\d+)','\\1','[0445521757, +61439800915]')
ast.literal_eval(fixed_string)
I dont know what you can do about the octal number problem however
I think the problem is that ast.literal_eval is trying to interpret the phone numbers as numbers instead of strings. Try this:
str = '[0448521958, +61439800915]'
str.strip('[]').split(', ')
Result:
['0448521958', '+61439800915']
Technically that string isn't valid JSON. If you want to ignore the +, you could strip it out of the file or string before you evaluate it. If you want to preserve it, you'll have to enclose the value with quotes.

ZWNJ not shown properly in python 3.3

I am trying to replace the space between two tokens written in the Arabic alphabet with a ZWNJ but what the function returns is not decoded properly on the screen:
>>> nm.normalize("رشته ها")
'رشته\u200cها'
\u200 should be rendered as a half-space that would be placed between 'رشته' and 'ها' here, but it gets messed up like that. I am using Python 3.3.3
The function returned a string object with the \u200c character as part of it, but Python shows you the representation. The \uxxxx syntax is used to make the representation useful as a debugging value, you can now copy that representation and paste it back into Python and get the exact same value.
In other words, the function worked exactly as advertised; the space was indeed replaced by a U+200C ZERO WIDTH NON-JOINER codepoint.
If you wanted to write the string to your terminal or console, use print():
print(nm.normalize("رشته ها"))
Demo:
>>> result = 'رشته\u200cها'
>>> len(result)
7
>>> result[4]
'\u200c'
>>> print(result)
رشته‌ها
You can see that character 5 (index 4) is a single character here, not 6 separate characters.

How can I get Python to use upper case letters when printing hexadecimal values?

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.

Categories

Resources