-10
\$\begingroup\$

Write code to generate a PDF file containing 6 bingo cards. Winner is the one that uses the shortest code and needs no actions except for installing a library and running the code. (No Save As PDF). Rules are as follows.

  • The generated PDF file should display accurately in Adobe's PDF reader, Google Chrome and Moxilla Firefox.
  • Page size should be either Letter or A4.
  • Cards should be arranged in 3 rows and 2 columns.
  • Each card should be 3 inches in width and height.
  • Each card should contain numbers 1 to 25 in random order, arranged in 5x5 squares. The numbers in all 6 cards should be generated independently.
  • Text size should be 20 points.
  • Text font should be Helvetica, Arial, Calibri or Open Sans. Text should be centered in each cell.
  • The bingo cards should have borders with lines having thickness either 0.5 or 1 points.
  • You can use a pre-existing, publicly available library or package to create a PDF file but the code to generate and arrange bingo cards should be your own.
  • These is a margin of 20% allowed in each dimension, but all cards should be strictly equal in size.

Reference Answer

Install reportlab using pip install reportlab

from reportlab.pdfgen import canvas
from reportlab.lib.pagesizes import letter
from random import shuffle
my_canvas = canvas.Canvas("Bingo Cards.pdf", pagesize=letter)
my_canvas.setLineWidth(1)
my_canvas.setFont('Helvetica', 20)
a = [i for i in range(1, 26)]
for row in range(0, 3):
    for col in range (0, 2):
        shuffle(a)
        rowplace = 252*row
        colplace = 276*col
        my_canvas.line(60+colplace, 36+rowplace, 276+colplace, 36+rowplace)
        my_canvas.line(276+colplace, 36+rowplace, 276+colplace, 246+rowplace)
        my_canvas.line(60+colplace, 36+rowplace, 60+colplace, 246+rowplace)
        my_canvas.line(60+colplace, 246+rowplace, 276+colplace, 246+rowplace)
        for grid in range(0, 5):
            gridplace = grid*43.2
            my_canvas.line(60+colplace, 36+rowplace+gridplace, 276+colplace, 36+rowplace+gridplace)
            my_canvas.line(60+colplace+gridplace, 36+rowplace, 60+colplace+gridplace, 246+rowplace)
            for i in range(0, 5):
                my_canvas.drawCentredString(81.6+colplace+gridplace, 47.6+rowplace+i*43.2, str(a[i+5*grid]))
my_canvas.save()

The result is shown in the following image.

Sample bingo cards PDF

\$\endgroup\$
2
  • 3
    \$\begingroup\$ Is this a code-golf challenge? As the post is currently phrased, it lacks objective winning criteria. \$\endgroup\$ Commented Nov 18, 2023 at 17:47
  • \$\begingroup\$ Thanks for the reminder @noodleman. I added the winning criteria. \$\endgroup\$
    – paki eng
    Commented Nov 18, 2023 at 20:19

1 Answer 1

2
\$\begingroup\$

Python 3.8 (pre-release), 380 bytes

Requires reportlab. Install reportlab using pip install reportlab.

Default A4 pagesize, the margin on the dimensions allows for the rounding on the cards' positions.

Save the pdf file as "b".

from reportlab.pdfgen import canvas
import random
b=canvas.Canvas('b')
b.setLineWidth(1)
b.setFont('Helvetica',20)
n=list(range(25))
w=216
d=43
for y in(48,313,577):
 for x in(54,325):
  random.shuffle(n);b.lines([(x,y,x+w,y),(x,y,x,y+w)])
  for i in range(25):f,g=x+d*(i%5),y+d*(i//5);b.lines([(x,g+d,x+w,g+d),(f+d,y,f+d,y+w)]);b.drawCentredString(f+22,g+12,str(n[i]+1))
b.save()

Python 3.8 (pre-release), fully parametrized, 551 bytes

Default A4 pagesize. All the dimensions are parametrized:

  • font size
  • numbers in each card
  • number of cards in the page, arranged in rows and columns
  • size of card

Save the pdf file as "b".

from reportlab.pdfgen import canvas
from reportlab.lib.units import inch
import random
b=canvas.Canvas('b')
b.setLineWidth(1)
t=20
b.setFont('Helvetica',t)
k=25
q=int(k**.5)
n=list(range(k))
r=3
c=2
w=3*inch
h=3*inch
d=w/q
e=h/q
o=(b._pagesize[0]-w*c)/(c+1)
v=(b._pagesize[1]-h*r)/(r+1)
for y in range(r):
 y=y*(v+h)+v
 for x in range(c):
  x=x*(o+w)+o;random.shuffle(n);b.lines([(x,y,x+w,y),(x,y,x,y+h)])
  for i in range(k):f,g=x+d*(i%q),y+e*(i//q);b.lines([(x,g+e,x+w,g+e),(f+d,y,f+d,y+h)]);b.drawCentredString(f+d/2,g+(e-t)/2,str(n[i]+1))
b.save()

Code with comments

from reportlab.pdfgen import canvas
from reportlab.lib.units import inch
import random

# pdf canvas, default A4
b=canvas.Canvas('b')
b.setLineWidth(1)

t=20
b.setFont('Helvetica',t)

# numbers in each card
k=25
# numbers in cards are arranged in perfect squares
q=int(k**.5)
n=list(range(k))

# cards in page, arranged in rows and columns
r=3
c=2

# width and height of cards
w=3*inch
h=3*inch

# size of cells
d=w/q
e=h/q

# spacing between cards
o=(b._pagesize[0]-w*c)/(c+1)
v=(b._pagesize[1]-h*r)/(r+1)

# loop on rows in page
for y in range(r):

    # bottom position of card
    y=y*(v+h)+v

    # loop on columns in page
    for x in range(c):

        # left position of card
        x=x*(o+w)+o

        # randomize numbers
        random.shuffle(n)

        # draw the bottom and left line of card
        b.lines([(x,y,x+w,y),(x,y,x,y+h)])

        # loop on numbers
        for i in range(k):

            # orizontal and vertical position of the lines
            # as offset from the initial position of the card
            f,g=x+d*(i%q),y+e*(i//q)

            # draw lines
            b.lines([(x,g+e,x+w,g+e),(f+d,y,f+d,y+h)])

            # draw number as text, centered in the cell
            b.drawCentredString(f+d/2,g+(e-t)/2,str(n[i]+1))

# save pdf canvas as file
b.save()
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.