143 lines
5.3 KiB
Python
143 lines
5.3 KiB
Python
import random
|
|
from reportlab.lib.pagesizes import A4
|
|
from reportlab.lib import colors
|
|
from reportlab.platypus import SimpleDocTemplate, Table, TableStyle, Paragraph, Spacer, PageBreak
|
|
from reportlab.lib.styles import getSampleStyleSheet
|
|
from reportlab.pdfbase import pdfmetrics
|
|
from reportlab.pdfbase.ttfonts import TTFont
|
|
import argparse
|
|
|
|
def format_and_return(a, b, operation, result):
|
|
"""
|
|
Formats and returns a math problem string along with its result.
|
|
|
|
Args:
|
|
a (int): The first operand in the math problem.
|
|
b (int): The second operand in the math problem.
|
|
operation (str): The mathematical operation ('+', '-', '*', '/') to be performed.
|
|
result (int): The result of the math problem.
|
|
|
|
Returns:
|
|
tuple: A tuple containing the formatted math problem string and its result.
|
|
"""
|
|
a_str, b_str = str(a).rjust(2, ' '), str(b).rjust(2, ' ')
|
|
return f"{a_str} {operation} {b_str} =", result
|
|
|
|
def generate_math_problem():
|
|
"""
|
|
Generates a random math problem with an operation chosen from addition, subtraction, multiplication, or division.
|
|
|
|
The operands are randomly generated integers, with the following constraints:
|
|
- Both operands are within the range [0, 20] for addition and subtraction.
|
|
- Both operands are within the range [0, 20] for multiplication.
|
|
- For division, the divisor is within the range [1, 5] and the dividend is a multiple of the divisor, within the range [1, 40].
|
|
|
|
Returns:
|
|
tuple: A tuple containing the formatted math problem string and the correct result (integer).
|
|
"""
|
|
operation = random.choice(['+', '-', '*', '/'])
|
|
a, b = random.randint(0, 20), random.randint(0, 20)
|
|
|
|
if operation == '+':
|
|
return format_and_return(a, b, operation, a + b)
|
|
elif operation == '-':
|
|
a, b = max(a, b), min(a, b)
|
|
return format_and_return(a, b, operation, a - b)
|
|
elif operation == '*':
|
|
return format_and_return(a, b, operation, a * b)
|
|
elif operation == '/':
|
|
b = random.randint(1, 5)
|
|
a = b * random.randint(1, 40 // b)
|
|
return format_and_return(a, b, operation, a // b)
|
|
|
|
def create_brain_jogging_pdf(filename):
|
|
"""
|
|
Creates a brain jogging PDF with math problems and saves it to the specified filename.
|
|
|
|
The PDF contains 20 rows with 4 math problems per row, chosen randomly from addition, subtraction, multiplication, and division.
|
|
The PDF has two pages: the first page contains only the math problems, and the second page includes the problems along with their results.
|
|
|
|
Args:
|
|
filename (str): The output PDF filename.
|
|
|
|
Dependencies:
|
|
- reportlab.lib.pagesizes.A4
|
|
- reportlab.platypus.SimpleDocTemplate
|
|
- reportlab.platypus.Paragraph
|
|
- reportlab.platypus.Spacer
|
|
- reportlab.platypus.Table
|
|
- reportlab.platypus.PageBreak
|
|
- reportlab.lib.colors
|
|
- reportlab.platypus.TableStyle
|
|
- reportlab.lib.styles.getSampleStyleSheet
|
|
- reportlab.pdfbase.pdfmetrics
|
|
- reportlab.pdfbase.ttfonts.TTFont
|
|
"""
|
|
problems = [[generate_math_problem() for _ in range(4)] for _ in range(20)]
|
|
data = [[problem[0] for problem in row] for row in problems]
|
|
data_with_results = [[f"{problem[0]} {problem[1]}" for problem in row] for row in problems]
|
|
|
|
doc = SimpleDocTemplate(filename, pagesize=A4)
|
|
styles = getSampleStyleSheet()
|
|
|
|
# Add title and time line
|
|
title = Paragraph("Brain Jogging Exercises", styles['Heading1'])
|
|
time_line = Paragraph("Time: _______________", styles['BodyText'])
|
|
|
|
# Create a table for the title and time line
|
|
title_table = Table([[title, time_line]], colWidths=(A4[0] / 2) * 0.75)
|
|
|
|
title_table_style = TableStyle([
|
|
('GRID', (0, 0), (-1, -1), 1, colors.white),
|
|
('ALIGN', (0, 0), (-1, -1), 'LEFT'),
|
|
('FONTNAME', (0, 0), (-1, -1), 'Helvetica'),
|
|
('FONTSIZE', (0, 0), (-1, -1), 12),
|
|
('BOTTOMPADDING', (0, 0), (-1, -1), 12),
|
|
])
|
|
|
|
title_table.setStyle(title_table_style)
|
|
|
|
table = Table(data, colWidths=(A4[0] / 4) * 0.75)
|
|
table_with_results = Table(data_with_results, colWidths=(A4[0] / 4) * 0.75)
|
|
|
|
font_name = 'Consolas' # Change this to the desired name for your font
|
|
font_path = './Consolas.ttf' # Change this to the path of the font file
|
|
|
|
custom_font = TTFont(font_name, font_path)
|
|
pdfmetrics.registerFont(custom_font)
|
|
|
|
# Define table style
|
|
table_style = TableStyle([
|
|
('GRID', (0, 0), (-1, -1), 1, colors.white),
|
|
('ALIGN', (0, 0), (-1, -1), 'LEFT'),
|
|
('FONTNAME', (0, 0), (-1, -1), 'Consolas'),
|
|
('FONTSIZE', (0, 0), (-1, -1), 12),
|
|
('BOTTOMPADDING', (0, 0), (-1, -1), 16),
|
|
])
|
|
table.setStyle(table_style)
|
|
table_with_results.setStyle(table_style)
|
|
|
|
# Add tables to the PDF
|
|
doc.build([
|
|
title_table,
|
|
Spacer(1, 12),
|
|
table,
|
|
PageBreak(),
|
|
# title,
|
|
# time_line,
|
|
title_table,
|
|
Spacer(1, 12),
|
|
table_with_results
|
|
])
|
|
|
|
def main():
|
|
parser = argparse.ArgumentParser(description="Create a brain jogging PDF.")
|
|
parser.add_argument("filename", nargs="?", default="brain-jogging.pdf",
|
|
help="The output PDF filename. (default: %(default)s)")
|
|
|
|
args = parser.parse_args()
|
|
create_brain_jogging_pdf(args.filename)
|
|
|
|
if __name__ == "__main__":
|
|
main()
|