【python】Fraction类详解及生成分数四则运算“试卷”

2024-07-30 12:28:06 浏览数 (2)

一、前言

实验所需的库

代码语言:javascript复制
from fractions import Fraction
import random
from PIL import Image, ImageDraw, ImageFont
  • 标准库中的 random 模块包含用于生成随机数的函数
  • fractions 模块包含用于处理分数的 Fraction

终端指令

代码语言:javascript复制
conda create -n DL python==3.11
代码语言:javascript复制
conda activate DL
代码语言:javascript复制
conda install numpy pillow

代码语言:javascript复制
pip install numpy pillow

Fraction类

  当调用Fraction函数时,有几种可能的参数类型:

1. Fraction(numerator, denominator):

  使用整数作为分子和分母创建一个分数。在这里,Fraction(16, -10)创建了一个分数,分子为16,分母为-10。由于分母为负数,Fraction对象会自动将其转换为正数,结果为Fraction(-8, 5)。

代码语言:javascript复制
Fraction(16, -10)

输出: Fraction(-8, 5)

2. Fraction(numerator)

  如果只提供一个参数,Fraction对象会将其作为分子,分母默认为1。

代码语言:javascript复制
Fraction(123)

输出: Fraction(123, 1)

3. Fraction()

  如果没有提供参数,则使用默认值0/1。

代码语言:javascript复制
Fraction()

输出: Fraction(0, 1)

4. 分数作参数

  传入字符串作为参数,Fraction会尝试解析该字符串来创建分数。

代码语言:javascript复制
Fraction('3/7')

输出: Fraction(3, 7)

5. 负分数作参数

  与前一个例子类似,Fraction会去除字符串中的空格并解析分数。

代码语言:javascript复制
Fraction(' -3/7 ')

输出: Fraction(-3, 7)

6. 字符串作参数

  同样,Fraction会尝试解析字符串中的数字来创建分数,忽略其他字符。

代码语言:javascript复制
Fraction('1.414213 tn')

输出: Fraction(1414213, 1000000)

7. 小数作参数

  与前面的例子类似,Fraction会解析负小数来创建分数。

代码语言:javascript复制
Fraction('-.125')

输出: Fraction(-1, 8)

8. 科学计数法

  Fraction也支持科学计数法表示的小数。

代码语言:javascript复制
Fraction('7e-6')

输出: Fraction(7, 1000000)

9. 浮点数作参数

  如果参数是浮点数,Fraction对象会将其转换为最接近的分数。

代码语言:javascript复制
Fraction(2.25)

输出: Fraction(9, 4)

10. 浮点数精度问题

  浮点数1.1在计算机中以二进制形式表示时会产生精度损失

代码语言:javascript复制
Fraction(1.1)

输出: Fraction(2476979795053773, 2251799813685248)

11. Decimal对象作参数

  同样,使用Decimal对象作为参数可以避免浮点数精度问题:

代码语言:javascript复制
from decimal import Decimal
Fraction(Decimal('1.1'))

输出: Fraction(11, 10)

二、实现过程

Version 1 四则运算

代码语言:javascript复制
import random
from fractions import Fraction

num1 = random.randint(1, 10)
num2 = random.randint(1, 10)
num3 = random.randint(1, 10)
num4 = random.randint(1, 10)

operator = random.choice([' ', '-', '*', '/'])

if operator == ' ':
    result = Fraction(num1, num2)   Fraction(num3, num4)
elif operator == '-':
    result = Fraction(num1, num2) - Fraction(num3, num4)
elif operator == '*':
    result = Fraction(num1, num2) * Fraction(num3, num4)
elif operator == '/':
    result = Fraction(num1, num2) / Fraction(num3, num4)

print(f"{num1}/{num2} {operator} {num3}/{num4}  = {result}")

  首先通过生成四个 1~10 之间的随机整数,然后再随机选择运算符,最后用 Fraction 表达式进行四则运算并输出结果。

  • num1 = random.randint(1, 10): 通过 random.randint 函数生成一个 1~10 之间的随机整数赋值给 num1num2num3num4的表示方式类似。
  • operator = random.choice([' ', '-', '*', '/']): 通过 random.choice 选择 ' ''-''*''/'中的一个赋值给 operator
  • Fraction(num1, num2)Fraction类构造函数生成一个分数对象,分子为num1,分母为num2
  • 根据 operator 的值,使用 Fraction 类的四则运算符进行相应的计算,结果赋值给 result
  • 使用 f-string 格式化输出,打印出分数表达式及其计算结果。

例如:

Version 2 试题list

代码语言:javascript复制
from fractions import Fraction
import random
from PIL import Image, ImageDraw, ImageFont

num = 0

problems = []
answers = []
max_range = 100
for i in range(100):
    num1 = random.randint(1, max_range)
    num2 = random.randint(1, max_range)
    num3 = random.randint(1, max_range)
    num4 = random.randint(1, max_range)
    operator = random.choice([' ', '-', '*', '/'])

    if operator == ' ':
        result = Fraction(num1, num2)   Fraction(num3, num4)
    elif operator == '-':
        result = Fraction(num1, num2) - Fraction(num3, num4)
    elif operator == '*':
        result = Fraction(num1, num2) * Fraction(num3, num4)
    else:  # Division
        result = Fraction(num1, num2) / Fraction(num3, num4)
    problem = f"{num1}/{num2} {operator} {num3}/{num4} = "
    # print(f"{num1}/{num2} {operator} {num2}/{num1} = ")
    problems.append(problem)
    answers.append(str(result))

    print(problem)

改进版

  • 增加了一个循环,用于生成 100 个不同的问题。
  • 将问题和答案都添加到了两个不同的列表中。

Version 3 可视化

代码语言:javascript复制
from fractions import Fraction
import random
from PIL import Image, ImageDraw, ImageFont

problems = []
answers = []
max_range = 10
for i in range(100):
    num1 = random.randint(1, max_range)
    num2 = random.randint(1, max_range)
    num3 = random.randint(1, max_range)
    num4 = random.randint(1, max_range)
    operator = random.choice([' ', '-', '*', '/'])

    if operator == ' ':
        result = Fraction(num1, num2)   Fraction(num3, num4)
    elif operator == '-':
        result = Fraction(num1, num2) - Fraction(num3, num4)
    elif operator == '*':
        result = Fraction(num1, num2) * Fraction(num3, num4)
    else:  # Division
        result = Fraction(num1, num2) / Fraction(num3, num4)
    problem = f"{num1}/{num2} {operator} {num3}/{num4} = "
    # print(f"{num1}/{num2} {operator} {num2}/{num1} = ")
    problems.append(problem)
    answers.append(str(result))

    print(problem)

num = 20
text_y = 50
font = ImageFont.truetype("arial.ttf", 25)


problem_image = Image.new('RGB', (800, 1200), color='white')
draw = ImageDraw.Draw(problem_image)
draw.text((300, 20), 'Math Problems', fill='blue', font=font)
for i in range(num):
    draw.text((50, text_y), problems[i], fill='black', font=font)
    text_y  = 50

problem_image.save('math_problems_7.png')

text_y = 50
answer_image = Image.new('RGB', (800, 1200), color='white')
draw = ImageDraw.Draw(answer_image)
draw.text((300, 20), 'Math Answers', fill='blue', font=font)
for i in range(num):
    draw.text((50, text_y), f"{problems[i]} = {answers[i]}", fill='black', font=font)
    text_y  = 50

answer_image.save('math_answers_7.png')

  使用Image模块创建白底图片,并设置了真实字体以及颜色。然后将生成的问题和答案添加到了图片中,并保存为png文件。

Problems
Answers

Version 4 排除负数

代码语言:javascript复制
from fractions import Fraction
import random
from PIL import Image, ImageDraw, ImageFont

problems = []
answers = []
max_range = 10
for i in range(100):
    num1 = random.randint(1, max_range)
    num2 = random.randint(1, max_range)
    num3 = random.randint(1, max_range)
    num4 = random.randint(1, max_range)
    operator = random.choice([' ', '-', '*', '/'])

    if operator == ' ':
        result = Fraction(num1, num2)   Fraction(num3, num4)
    elif operator == '-':
        if Fraction(num1, num2) < Fraction(num3, num4):
            num1, num3 = num3, num1
            num2, num4 = num4, num2
        # print(num1, num2, num3, num4)
        result = Fraction(num1, num2) - Fraction(num3, num4)
    elif operator == '*':
        result = Fraction(num1, num2) * Fraction(num3, num4)
    else:  # Division
        result = Fraction(num1, num2) / Fraction(num3, num4)
    problem = f"{num1}/{num2} {operator} {num3}/{num4} = "
    # print(f"{num1}/{num2} {operator} {num2}/{num1} = ")
    problems.append(problem)
    answers.append(str(result))

    print(problem)

num = 20
text_y = 50
font = ImageFont.truetype("arial.ttf", 25)


problem_image = Image.new('RGB', (800, 1200), color='white')
draw = ImageDraw.Draw(problem_image)
draw.text((300, 20), 'Math Problems', fill='blue', font=font)
for i in range(num):
    draw.text((50, text_y), problems[i], fill='black', font=font)
    text_y  = 50

problem_image.save('math_problems_7.png')

text_y = 50
answer_image = Image.new('RGB', (800, 1200), color='white')
draw = ImageDraw.Draw(answer_image)
draw.text((300, 20), 'Math Answers', fill='blue', font=font)
for i in range(num):
    draw.text((50, text_y), f"{problems[i]} {answers[i]}", fill='black', font=font)
    text_y  = 50

answer_image.save('math_answers_7.png')

0 人点赞