250425 -- tangram项目总结

担心

虽然做完了,但是还是隐约有点担心客户成绩不好,过不了测试

我其实经常性的担心,即使做完了,也有新的任务要做。其实这样的担心并不合理,我已经尽力替客户做事情了,后面就靠天收了。

其实完成项目带来的快乐是短暂的,做项目的过程,不断客服困难前进的过程,才是快乐的来源。

总结

这个项目我觉得最出彩的部分,就是我定义了 Piece 父类
又定义了 LargeTri SmallTri MedTri Square Para 这几个具体的子类

通过定义一个 Piece 父类和多个具体的子类(如 LargeTri、SmallTri、MedTri、Square、Para),
利用了继承和多态的特性。这种设计模式使得代码更加清晰和易于管理。

父类提供了公共的接口
--------- 旋转、翻转、字符串打印、__lt__ 等

子类提供了不同图形的不同顶点数据


class Piece:
    def __init__(self, anchor):
        self.anchor = anchor
        self.name = 'piece'
        # 默认顶点关系
        self.vertices = []
        # 更新顶点列表
        self.update_vertices()
        self.xfliped=False
        for v in self.vertices:
            print(v)

    def update_vertices(self):
        # 计算并更新顶点列表
        for vertex in self.vertices:
            # 假设 Vertex 类有一个方法 add,用于将两个顶点相加
            vertex.x = self.anchor.x + vertex.x
            vertex.y = self.anchor.y + vertex.y

    def xflip(self):
        #关于锚点,左右翻转
        for i in range(len(self.vertices)):
            self.vertices[i].x = self.anchor.x + self.anchor.x - self.vertices[i].x
        self.xfliped=True

    def rotate_around_anchor(self, angle):
        # 将顶点平移到原点
        for i in range(len(self.vertices)):
            self.vertices[i].x -= self.anchor.x
            self.vertices[i].y -= self.anchor.y

       
        for vertex in self.vertices:
            # 旋转每个顶点
            for _ in range(angle // 45):
                vertex.rotate_45()

        # 将顶点平移回原位置
        for i in range(len(self.vertices)):
            self.vertices[i].x += self.anchor.x
            self.vertices[i].y += self.anchor.y

    def get_min(self):
        # 找到最小的顶点
        min_vertex = min(self.vertices)
        return min_vertex
    
    def get_second_min(self):
        # 找到第二个最小的顶点
        sorted_vertices = sorted(self.vertices)
        return sorted_vertices[1] if len(sorted_vertices) > 1 else None
    
    def __lt__(self,other):
        min1 = self.get_min()
        min2 = other.get_min()
        #需要考虑min顶点重合的情况,这时候要比较第二min的顶点
        if min1 == min2:
            min1 = self.get_second_min()
            min2 = other.get_second_min()

        # 注意这里是 topmost 规则, y轴方向向上
        if min1.y > min2.y:
            return True
        elif min1.y == min2.y and min1.x < min2.x:
            return True
        else:
            return False
        

    def __str__(self):

        if self.xfliped:
            # 翻转后,确保顶点按顺时针顺序排列
            self.vertices.reverse()

        # 找到最小的顶点
        min_vertex = min(self.vertices)
        min_index = self.vertices.index(min_vertex)
        # 从最小的顶点开始重新排列顶点列表
        sorted_vertices = self.vertices[min_index:] + self.vertices[:min_index]
    
        # 返回字符串表示,不包含单引号
        return f"{self.name:15}: [{', '.join(str(v) for v in sorted_vertices)}]"

class LargeTri(Piece):
    def __init__(self, anchor):
        super().__init__(anchor)
        self.name = 'Large triangle'
        self.vertices = [
            Vertex("0},{0"),
            Vertex("2},{2"),
            Vertex("2},{0")
        ]
        self.update_vertices()

class SmallTri(Piece):
    def __init__(self, anchor):
        super().__init__(anchor)
        self.name = 'Small triangle'
        self.vertices = [
            Vertex("0},{0"),
            Vertex("1},{1"),
            Vertex("1},{0")
        ]
        self.update_vertices()

class MedTri(Piece):
    def __init__(self, anchor):
        super().__init__(anchor)
        self.name = 'Medium triangle'
        self.vertices = [
            Vertex("0},{0"),
            Vertex("1},{1"),
            Vertex("2},{0")
        ]
        self.update_vertices()

class Square(Piece):
    def __init__(self, anchor):
        super().__init__(anchor)
        self.name = 'Square'
        self.vertices = [
            Vertex("0},{0"),
            Vertex("0},{1"),
            Vertex("1},{1"),
            Vertex("1},{0")
        ]
        self.update_vertices()

class Para(Piece):
    def __init__(self, anchor):
        super().__init__(anchor)
        self.name = 'Parallelogram'
        self.vertices = [
            Vertex("0},{0"),
            Vertex("1},{1"),
            Vertex("2},{1"),
            Vertex("1},{0")
        ]
        self.update_vertices()


正则表达式

通过这个项目,我还熟悉了正则表达式的用法

正则表达式是一种用来匹配字符串的强有力的武器。它的设计思想是用一种描述性的语言来给字符串定义一个规则,凡是符合规则的字符串,我们就认为它“匹配”了,否则,该字符串就是不合法的。

https://www.runoob.com/python/python-reg-expressions.html

我这次用了一些基础的用法

# Extract PieceName
                    piece_match = re.search(r'{Tang\w+}', line)
# Extract rotate
                            rotate_match = re.search(r'rotate\s*=\s*([-\d]+)', line)
# Extract xscale
                            xflip_match = re.search(r'xscale\s*=\s*([-\d]+)', line)
                            yflip_match = re.search(r'yscale\s*=\s*([-\d]+)', line)
# 分割整数部分和 sqrt(2) 部分
        a_part_match =  re.search(r'[\+|-]?[0-9]*\.?[0-9]*[\+|-]', coord_str)
anchor_match = re.search(r'\(.*\)', line)

解析

模式 含义
\w 单词
\s 空格
[|] 不同模式的组合
? 0或1次
* 0次或多次
+ 一次或多次

re.search方法

re.search 扫描整个字符串并返回第一个成功的匹配。

函数语法:

re.search(pattern, string, flags=0)

甚至了解到了正则表达式来自于神经科学家,这个也太有意思了吧。

我自己写了一个正则表达式

在这个网站(https://jex.im/regulex/#!flags=&re=^(a|b)*%3F%24)做了可视化:

flex词法分析器里的正则表达式

之前做的项目:https://gitee.com/wangqiyuejava63/sysy-compiler
里面的词法分析器也用到了正则表达式

INTCON     [0-9]+ //整型常量
IDENFR     [a-zA-Z_][a-zA-Z0-9_]* //标识符
STRCON     \"([^\"\\]|\\.)*\"  //字符串常量
[ \t\r\n]+          ;   // 忽略空白符
.                   { PRINT("TOKEN: UNKNOWN (%s)\n", yytext); }
"//"[^"\n"]*       ;   // 跳过单行注释

第一天工作记录

第二天工作记录

Fraction类

StdFraction 是 Python 的 fractions.Fraction 类的别名。

fractions.Fraction 是 Python 标准库中的一个类,用于表示有理数(分数)。

它提供了多种方法来处理分数,包括加法、减法、乘法、除法等,并且可以自动简化分数。

1. Fraction 类

功能:表示分数,支持加法、减法、除法等基本运算。
方法:
init:初始化分数,支持从字符串或两个整数创建分数。
addsubtruediv:实现分数的加法、减法和除法。
eq:比较两个分数是否相等。
str:返回分数的字符串表示。
to_float:将分数转换为浮点数。
minus:判断分数是否为负。

2. Complex 类

功能:表示复数形式的坐标,包含实部和虚部。
方法:
init:初始化复数,支持实部和虚部的设置。
addsub:实现复数的加法和减法。
eqltgt:比较两个复数。
str:返回复数的字符串表示。

3. Vertex 类

功能:表示一个顶点,支持坐标变换和旋转。
方法:
init:从字符串初始化顶点坐标。
transform:将字符串形式的坐标转换为 Complex 类型。
addsub:实现顶点的加法和减法。
eqlt:比较两个顶点。
rotate_45:将顶点绕原点旋转45度。
str:返回顶点的字符串表示。

4. Piece 类

功能:表示一个拼图块,包含锚点和顶点列表。
方法:
init:初始化拼图块,设置锚点和顶点列表。
update_vertices:更新顶点列表,将顶点平移到锚点。
xflip:关于锚点进行左右翻转。
rotate_around_anchor:绕锚点旋转拼图块。
get_min、get_second_min:获取最小顶点和第二个最小顶点。
lt:比较两个拼图块。
str:返回拼图块的字符串表示。

5. 具体拼图块类

LargeTri、SmallTri、MedTri、Square、Para:
功能:继承自 Piece 类,表示不同类型的拼图块。
方法:在构造函数中设置默认顶点。

6. TangramPuzzle 类

功能:解析 .tex 文件,提取拼图块的变换信息和顶点信息。
方法:
init:初始化 TangramPuzzle 对象,解析文件。
parse_transformations:解析文件中的变换信息。
parse_vertices:解析文件中的顶点信息。
str:返回拼图块的字符串表示,按特定顺序排列。

posted @ 2025-04-25 18:42  lucky_doog  阅读(13)  评论(0)    收藏  举报