I want to output something that looks like this (with 20 items per line, and two variables are needed, one for indexing, i, and one for the book name, bookname, in this case "Psalm"
):
\hyperlink{Psalm1}{1} & \hyperlink{Psalm2}{2} & \hyperlink{Psalm3}{3} ...
Using Python (simplification of my loop, but enough to show the key error) I attempted:
for indx in range(1, 150, 20):
line = r""" \\hline
\\hyperlink{{{bn}{i}}}{{{i}}} & \\hyperlink{{{bn}{i+1}}}{{{i+1}}} & \\hyperlink{{{bn}{i+2}}}{{{i+2}}} ...
""".format( i=indx, bn = bookname)
What's the best way to recode to avoid the i+1
key error ?
Here is example of string generation (\hyperlink{Psalm1}{1}
) using different methods:
i = 1
# string concatenation
formatted = r"\hyperlink{Psalm" + str(i) + "}{" + str(i) + "}"
# old-style formatting
formatted = r"\hyperlink{Psalm%d}{%d}" % (i, i))
# str.format
formatted = r"\hyperlink{{Psalm{0}}}{{{0}}}".format(i)
# f-string
formatted = rf"\hyperlink{{Psalm{i}}}{{{i}}}"
For this particular case I find old-style formatting more "clean" as it doesn't require doubling curly brackets.
To print 20 strings in each line you can pass generator which will produce formatted strings into str.join()
.
Full code:
stop = 150
step = 20
for i in range(1, stop + 1, step):
print(
" & ".join(
r"\hyperlink{Psalm%d}{%d}" % (n, n)
for n in range(i, min(i + step, stop + 1))
)
)
Or you can also use "one-liner":
stop = 150
step = 20
print(
"\n".join( # use " &\n".join(...) if you need trailing '&'
" & ".join(
r"\hyperlink{Psalm%d}{%d}" % (n, n)
for n in range(i, min(i + step, stop + 1))
)
for i in range(1, stop + 1, step)
)
)