String formating and Tex rendering - python

I am running into some issues getting things to display correctly when combining string formating and tex rendering in python. I want to index a series of energy levels by integers. This works fine for single-digit integers, however when I try for example:
s = r"$E_{}$".format(10)
the result looks like E10 while I want it to look like E10. I have tried using double braces but this doesn't seem to work since
s = r"$E_{{}}$".format(10)
results in "E" without any subscript at all, and something like
s = r"$E_{{k}}$".format(k = 10)
predictably gives Ek.
To me it seems the problem here is that both the string formatting and Tex syntax make use of curly braces, and while doubling the braces does escape the formatting, this will not work for me, since I still want to insert the value of k somehow. Is there any way around this issue, or will I have to resort to the old school method of formatting strings?

Literal { can be included with {{ - and then you need another {} to get the formatting placeholder - so you need 3:
s = r"$E_{{{}}}$".format(10)
print(s)
Results in:
$E_{10}$
Which should be rendered into what you wanted.

Related

How can I write two letters with many spaces between them in Python?

I'm trying to make a pattern looking like this:
click here, it's a capital A made out of A's
I'm running into trouble getting the A's to space apart by four or five spaces (A____A). I have to use the format method, but I have no idea how to go about doing that. What is the easiest way? I tried to do something like this, but it says invalid syntax and I am very confused about how to do it right.
print('A',{:4d}.format('A'))
You need to wrap the format in a string, as in '{:4d}'.format(42).
Note that the d specifier expects an integer to be formatted, so '{:4d}'.format('A') would raise an error since 'A' is a string, not an int.
Instead, you remove the d:
print('A{:>4}'.format('A')) # or print(f'A{"A":>4}')
# A A
The > will right-align the 'A', so that the spaces go in the middle.
A simpler way, without bothering with the formatting mini-language, is to simply insert the spaces:
print('A' + ' '*3 + 'A')
You can try
print(f"{A:04}")

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'

How can I add spaces around a sub-string using Python formatted strings `(f'...')` without first creating a new variable?

Suppose, I want to convert the following .format()'ed string to a f'...' expression:
self.logger.debug('{:10} -- {}'.format('Jira', 'Scan: {} '.format(self.scan_id)))
I can do it easily as:
self.logger.debug(f'Jira -- {self.scan_id}`)
However, I don't want to add the spaces (width) around 'Jira' manually. How can I do that without first having to create a new variable as in:
s='Jira'
self.logger.debug(f'{s:10} -- {self.scan_id}`)
?
You can directly put your string in curly brackets like this:
self.logger.debug(f'{"Jira":10} -- {self.scan_id}')
Because an f-string expects an expression inside {} and a string itself is a valid expression.
You should generally avoid doing string formatting directly in logging calls as it can waste time formatting strings that are never emitted. Instead you should prefer to use the inbuilt formatting of the logger.
An example of how you might achieve your logging call would be:
logger.debug('% -10s -- %s', 'Jira', self.scan_id)
By default, the logging module uses percent formatting (documentation). If you are more familar with brace formatting (ie.using {}) and would prefer to use that, then this answer shows you how to set it up.

python .format including float formatting

I have been aware of .format for a long while now but when I tried to include float formatting in a string like below:
"ab_{}_cd{}_e_{}_{}_{}_val={0:.5f}_{}".format(string1,str(2),string2,string3,string4,str(0.12345678),string5)
In the above example string1-5 denote random strings included for this example.
Returned the following error ValueError: cannot switch from automatic field numbering to manual field specification
After some searching this question does seem to hold the solution Using .format() to format a list with field width arguments
The above link shows I need to format all of the {} in the string to achieve the formatting I want. I have glanced at official documentation https://docs.python.org/2/library/string.html and https://docs.python.org/2/library/stdtypes.html#str.format and there isn't much in the way of explaining what I'm looking for.
Desired output:
An explanation as to how I can convert the automatic field specification of the .format option to a manual field specification with only formatting the float variable I have supplied and leaving all other string1-5 variables unformatted. Whilst I could just use something like round() or a numpy equivalent this might cause issues and I feel like I would learn better with the .format example.
in your code remove the zero before the rounded digit
"ab_{}_cd{}_e_{}_{}_{}_val={:.5f}_{}".format(string1,str(2),string2,string3,string4,str(0.12345678),string5)
NOTE: why it did not work is , you can either mention index in {} as {0},{1} or leave all of them, but you cannot keep few {} with index and few without any index.

Why is escaping of single quotes inconsistent on file read in Python?

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.

Categories

Resources