Related
This question already has answers here:
python order of elements in set
(2 answers)
Does Python have an ordered set?
(15 answers)
Closed 3 months ago.
I face a strange problem where set comprehension won't work as intended.
b=[[2,9,10],[3,7,15],[5,12,12],[15,20,10],[19,24,8]]
print({(R, 0, 0) for _, R, _ in b})
We have output
{(12, 0, 0), (9, 0, 0), (7, 0, 0), (20, 0, 0), (24, 0, 0)}
Not the desired answer
{(9, 0, 0), (7, 0, 0), (12, 0, 0), (20, 0, 0), (24, 0, 0)}
What went wrong? For list comprehension, it works fine.
b=[[2,9,10],[3,7,15],[5,12,12],[15,20,10],[19,24,8]]
print([(R, 0, 0) for _, R, _ in b])
We have output
[(9, 0, 0), (7, 0, 0), (12, 0, 0), (20, 0, 0), (24, 0, 0)]
It is natural to have sets comprehension looks like this. Based on Iain and juanpa's comment, sets are not ordered. The order is not preserved. So that's why we have "unintended" print value.
On the other hand, if you want to preserve the order, you should use lists.
I'm watching a tutorial on how to make Tetris and I'm completely lost trying to understand how to represent the different rotations of pieces.
The tutorial references the 2009 Tetris Design Guide, particularly the slide on Tetrimino Facings:
Relevant Code in the video starts at 1:10:27
The below code represent tuples indicating coordinates at which every piece rotates around.
Kind::O => &[(0, 0), (0, 1), (1, 0), (1, 1)],
Kind::I => &[(-1, 0), (0, 0), (1, 0), (2, 0)],
Kind::T => &[(-1, 0), (0, 0), (1, 0), (0, 1)],
Kind::L => &[(-1, 0), (0, 0), (1, 0), (1, 1)],
Kind::J => &[(-1, 1), (-1, 0), (0, 0), (1, 0)],
Kind::S => &[(-1, 0), (0, 0), (0, 1), (1, 1)],
Kind::Z => &[(-1, 1), (0, 1), (0, 0), (1, 0)],
Can someone explain to me this representation system please?
Example with J [(-1, 1), (-1, 0), (0, 0), (1, 0)]:
(y)
3
2
1 A
0 B C D
-1
-1 0 1 2 (x)
where
A = (-1, 1)
B = (-1, 0)
C = ( 0, 0)
D = ( 1, 0)
(0,0) (here C) is the center of rotation.
To rotate, do this transform for each block :
clockwise: (x, y) => (-y, x)
anticlockwise: (x, y) => (y, -x)
raise LayoutError(ident)
reportlab.platypus.doctemplate.LayoutError:
Flowable <Table#0x7FA13491B898 1 rows x 1 cols(tallest row 900)> with cell(0,0) containing
'<Table#0x7FA1349110B8 1 rows x 1 cols(tallest row 894)> with cell(0,0) containing\n\'<Table#0x7FA1349894E0 1 rows x 1 cols(tallest row 24)> with cell(0,0) containing\\n"<Table#0x7FA134989438 1 rows x 1 cols(tallest row 18)> with cell(0,0) containing\\\\n\\\'Vulnerability ( Virustotal Domain Report )\\\'"\''(583.2755905511812 x 900), tallest cell 900.0 points, too large on page 6 in frame 'normal'(583.2755905511812 x 794.8897637795277*) of template 'Later'
I make a PDF(A4) size for it and got the error, while Ienter code here make A3 for it the problem is solved, i want the solution for A4 size.
def getToolsTables(data, tname):
doc = SimpleDocTemplate(
"somefilename.pdf",
pagesize=A2,
topMargin=25,
bottomMargin=0,
)
main_header = []
h_arr1 = []
h_arr1.append(tname)
main_header.append(h_arr1)
mainHeader = Table(main_header, colWidths="*")
finalTable = []
main_table_header_Style = TableStyle(
[
("BACKGROUND", (0, 0), (-1, 0), "#D3D3D3"),
("TEXTCOLOR", (0, 0), (-1, -1), colors.black),
("ALIGN", (0, 0), (-1, -1), "LEFT"),
("FONTSIZE", (0, 0), (-1, -1), 12),
("FONTNAME", (0, 0), (-1, -1), "Courier-Bold"),
("TOPPADDING", (0, 0), (-1, -1), 5),
("BOTTOMPADDING", (0, 0), (-1, -1), 7),
("LINEBELOW", (0, 0), (-1, 0), 1, colors.black),
]
)
tools_table_header_Style = TableStyle(
[
("BACKGROUND", (0, 0), (-1, 0), "lightblue"),
("TEXTCOLOR", (0, 0), (-1, -1), colors.black),
("ALIGN", (0, 0), (-1, -1), "LEFT"),
("FONTSIZE", (0, 0), (-1, -1), 11),
("FONTNAME", (0, 0), (-1, -1), "Courier-Bold"),
]
)
tools_table_header_Style1 = TableStyle(
[
("BACKGROUND", (0, 0), (-1, 0), "lightgreen"),
("TEXTCOLOR", (0, 0), (-1, -1), colors.black),
("ALIGN", (0, 0), (-1, -1), "CENTER"),
("FONTSIZE", (0, 0), (-1, -1), 11),
("FONTNAME", (0, 0), (-1, -1), "Courier-Bold"),
]
)
Style2 = TableStyle(
[
("ALIGN", (0, 0), (-1, -1), "LEFT"),
("LEFTPADDING", (0, 0), (-1, -1), 0),
("RIGHTPADDING", (0, 0), (-1, -1), 0),
("BOTTOMPADDING", (0, 0), (-1, -1), -10),
]
)
Style3 = TableStyle(
[
("VALIGN", (0, 0), (-1, -1), "TOP"),
("ALIGN", (0, 0), (-1, -1), "RIGHT"),
("LEFTPADDING", (0, 0), (-1, -1), 130),
("RIGHTPADDING", (0, 0), (-1, -1), 0),
("TOPPADDING", (0, 0), (-1, -1), 0),
]
)
Style4 = TableStyle([("VALIGN", (0, 0), (-1, -1), "TOP")])
mainHeader.setStyle(
main_table_header_Style
) # adding style to table main header
finalTable.append(mainHeader)
# Create Tools Array
tools_header = []
tools_body = []
if type(data) == dict:
all_table = []
for key, value in data.items():
temp = []
temp_table = []
temp.append(key)
tool_table_header = Table([temp], colWidths="*")
tool_table_header.setStyle(tools_table_header_Style)
temp_table.append(tool_table_header)
if key != "Builtwith":
t_h = []
t_b = []
for k, v in value.items():
t_h.append(k)
t_b.append(v)
t_body = []
for index, item in enumerate(t_h):
if item != "status":
arr1 = []
arr2 = []
if type(t_b[index]) is list:
temp_txt = ""
for txt in t_b[index]:
temp_txt += txt + ", "
arr1.append(item + ":")
text = t_b[index]
wraped_text = "\n".join(
wrap(str(temp_txt[:-3]), 60)
) # 60 is line width
arr1.append(wraped_text)
else:
# MY CODE
arr2.append(arr1)
n_table = Table(arr2, [200, 370])
n_table.setStyle(Style4)
t_body.append(n_table)
tool_header = Table([temp_table], colWidths="*")
tool_body = Table([[t_body]], [200, 370])
finalTable.append(
Table(
[[[tool_header, tool_body]]],
colWidths="*",
)
)
Use splitInRow argument in the Table class so that it will split the data on the other page, for example:
tool_body = Table([[t_body]], [200, 370], splitInRow=1)
This is an example of my question.
Click here to check out the problem in my PDF file
from reportlab.lib import colors
from reportlab.platypus import SimpleDocTemplate, Table
doc = SimpleDocTemplate("test.pdf")
element = []
data = [["Testing Table", ""], ["Short content", "This is a short content."],["Long content", "aaaaaaaaaaaaa This is a super long content which I dont know how to
automaticaly make it fit my A4 page. aaaaaaaaaaaaaaaaaaaa"]]
t = Table(data, style=[("BOX", (0, 1), (-1, -1), 2, colors.black),
("GRID", (0, 1), (-1, -1), 0.5, colors.black),
("ALIGN", (0, 0), (0, -1), "CENTER"),
("VALIGN", (0, 0), (-1, -1), "MIDDLE"),
("ALIGN", (1, 1), (1, -1), "LEFT")])
element.append(t)
doc.build(element)
I am not sure if there is an option provided in reportlab, but you can do it externally by using the textwrap module.
Input data:
data = [["Testing Table", ""],
["Short content", "This is a short content."],
["Long content", "aaaaaaaaaaaaa This is a super long content which I dont know how to automaticaly make it fit my A4 page.aaaaaaaaaaaaaaaaaaaa"]]
Processing:
data = [(header, '\n'.join(textwrap.wrap(content, width=70))) for header, content in data]
The textwrap.wrap breaks up lines that are longer than 70 characters. And the join adds them together using the linebreak character (\n).
Which results in an output format:
You could wrap your long text (or all texts) in a Paragraph object.
To save myself from repeating Pragraph("...", style), I've created a function P(txt).
from reportlab.lib import colors
from reportlab.platypus import SimpleDocTemplate, Table, Paragraph
from reportlab.lib.styles import getSampleStyleSheet
doc = SimpleDocTemplate("test.pdf")
element = []
style = getSampleStyleSheet()['Normal']
def P(txt):
return Paragraph(txt, style)
data = [[P("Testing Table"), ""], [P("Short content"), P("This is a short content.")],
[P("Long content"), P("aaaaaaaaaaaaa This is a super long content which I dont know how to automaticaly make it fit my A4 page. aaaaaaaaaaaaaaaaaaaa")]]
t = Table(data, style=[("BOX", (0, 1), (-1, -1), 2, colors.black),
("GRID", (0, 1), (-1, -1), 0.5, colors.black),
("ALIGN", (0, 0), (0, -1), "CENTER"),
("VALIGN", (0, 0), (-1, -1), "MIDDLE"),
("ALIGN", (1, 1), (1, -1), "LEFT")])
element.append(t)
doc.build(element)
Output:
How can I perform something like dtR (delete until you meet the R in the line) across all the lines in a linewise visual block, or say, for the next n lines?
The long story
Let's suppose there is the following piece of code:
L0 = Rotated_Shape((1, 0), (-1, 0), (-1, 1))
L90 = Rotated_Shape((0, -1), (0, 1), (1, 1))
L180 = Rotated_Shape((-1, 0), (1, 0), (1, -1))
L270 = Rotated_Shape((0, 1), (0, -1), (-1, -1))
O0 = Rotated_Shape((1, 0), (1, -1), (0, -1))
O90 = Rotated_Shape((0, -1), (-1, -1), (-1, 0))
O180 = Rotated_Shape((-1, 0), (-1, 1), (0, 1))
O270 = Rotated_Shape((0, 1), (1, 1), (1, 0))
S0 = Rotated_Shape((-1, 0), (0, -1), (1, -1))
S90 = Rotated_Shape((0, 1), (-1, 0), (-1, -1))
S180 = Rotated_Shape((1, 0), (0, 1), (-1, 1))
S270 = Rotated_Shape((0, -1), (1, 0), (1, 1))
T0 = Rotated_Shape((0, 1), (-1, 0), (1, 0))
T90 = Rotated_Shape((1, 0), (0, 1), (0, -1))
T180 = Rotated_Shape((0, -1), (1, 0), (-1, 0))
T270 = Rotated_Shape((-1, 0), (0, -1), (0, 1))
Z0 = Rotated_Shape((1, 0), (0, -1), (-1, -1))
Z90 = Rotated_Shape((0, -1), (-1, 0), (-1, 1))
Z180 = Rotated_Shape((-1, 0), (0, 1), (1, 1))
Z270 = Rotated_Shape((0, 1), (1, 0), (1, -1))
I am now reworking this code and I want all these lines to become what is on the right side of the equation (assignment), i. e. delete the variable names, the equal sign and keep only the Rotated_Shape((... part.
I guess the best way to do this particular case is to search and replace a regular expression, but my first approach I didn't know how to do was to use the blockwise-visual or line-visual mode for each four of them and do something like dtR (delete until you meet the R in the line).
You can highlight those lines with a visual block and then use :help 'normal'.
The end result post-select looks something like: :'<,'>normal dtR
You can also abbreviate normal to norm.