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:初始化分数,支持从字符串或两个整数创建分数。
add、sub、truediv:实现分数的加法、减法和除法。
eq:比较两个分数是否相等。
str:返回分数的字符串表示。
to_float:将分数转换为浮点数。
minus:判断分数是否为负。
2. Complex 类
功能:表示复数形式的坐标,包含实部和虚部。
方法:
init:初始化复数,支持实部和虚部的设置。
add、sub:实现复数的加法和减法。
eq、lt、gt:比较两个复数。
str:返回复数的字符串表示。
3. Vertex 类
功能:表示一个顶点,支持坐标变换和旋转。
方法:
init:从字符串初始化顶点坐标。
transform:将字符串形式的坐标转换为 Complex 类型。
add、sub:实现顶点的加法和减法。
eq、lt:比较两个顶点。
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:返回拼图块的字符串表示,按特定顺序排列。

浙公网安备 33010602011771号