python模块学习记录3---替换规则与连接元素

以turtle函数的应用:L系统为例。(turtle函数是画图的库)

论文:《Graphical modeling using L-systems》

L系统的解释有点偏生物细胞方向,详细介绍移步百度百科。本质上就是一个重写系统。

b站up主指路:正月点灯笼

我这里只是学习了根据需求如何编写程序,程序的逻辑该是怎样的。

主要学到了替换规则和连接元素的编程思路。

‘F’:前进                                      ‘-’:左转                             ‘+’:右转

前进长度:length(L)                  转弯角度:angle(A)

原始路径:"F-F-F-F"(含义:前进L,左转A,前进L,左转A,前进L,左转A,前进L)

规则:F  --> F-F+F+FF-F-F+F (含义,将所有的前进F替换成"F-F+F+FF-F-F+F")

比如:迭代一次后路径变成"F-F+F+FF-F-F+F-F-F+F+FF-F-F+F-F-F+F+FF-F-F+F-F-F+F+FF-F-F+F"

画图:(angle = 90。length根据图形复杂度定义大小,复杂图形想看到全貌length就定义小一点)

原始路径的图形"F-F-F-F":

规则使用一次(迭代一次)之后的图形:

规则使用两次(迭代两次)之后的图形:

代码:(论文图1.6的复现)

无规则时的代码:

from turtle import *

length = 10   # 定义前进长度
angle = 90    # 定义转弯角度

def draw_path(path):    # 画图的方法,输入变量为原始路径
    for symbol in path:         # 遍历原始路径
        if symbol == 'F':       # 如果是F,那么前进length;如果是-,那么左转angle度;如果是+,那么右转angle度
            forward(length)
        elif symbol == '-':
            left(angle)
        elif symbol == '+':
            right(angle)

path = "F-F-F-F"        # 原始路径
speed(0)
draw_path(path)   # 调用画图的方法
exitonclick()

有规则时的代码:

from turtle import *

length = 10   # 定义前进长度
angle = 90    # 定义转弯角度

def draw_path(path):    # 画图的方法,输入变量为原始路径
    for symbol in path:         # 遍历原始路径
        if symbol == 'F':       # 如果是F,那么前进length;如果是-,那么左转angle度;如果是+,那么右转angle度
            forward(length)
        elif symbol == '-':
            left(angle)
        elif symbol == '+':
            right(angle)

def apply_rule(path):        # 使用规则的代码,输入参数为路径
    rule = "F-F+F+FF-F-F+F"      # 规则
    path = path.replace("F", rule)      # 将所有的F替换成规则
    return path              # 返回替换之后的路径

path = "F-F-F-F"        # 原始路径

speed(0)
path = apply_rule(path)      # 调用规则的方法
#path = apply_rule(path)      # 使用几次(迭代几次)就调用几次
draw_path(path)
exitonclick()

复杂一点的该怎么处理?比如图1.10

可以看到,原始路径是Fl,但有两条规则。如果根据上面的replace函数编写代码(如下图)

 那么,会出状况:

原始路径:Fl

程序第一步运行:查找原始路径中的Fl,将其替换成"Fl+Fr+",路径成为了Fl+Fr+

程序第二步运行:运行第一条规则,查找原始路径中的Fl并替换,路径成为Fl+Fr++Fr+;

                            

注意:这里出现了两个Fr,第一个是已经运用了第一条规则的Fr,第二个是上一步路径里的Fr。理想的,在使用第二条规则时,应该是第一个Fr不变,而改变第二个Fr。但如果还是使用replace函数,则不会按照理想步骤进行下去。

 

因此,需要另外一种替换规则的方式:

将Fl+Fr+变成数组的形式:['Fl','Fr','+']。在数组里面遍历每个元素,如果有Fl,那就第一条规则将对应元素替换;如果有Fr,那就第二条规则将对应元素替换。同时进行。

于是:

1、拆分路径:

def split_path(path):      # 拆分路径成为数组的形式
    i = 0
    lst = []
    while i < len(path):
        # 如果第i个元素是F的话,那么将当前元素和后一个元素进行组合。这一步是得到Fl或者Fr。
        # 如果不这么切片的话,path[i]是“F”和“l”,或者是“F”和“r”
        if path[i] == 'F':
            lst.append(path[i:i+2])
            i += 2
        else:          # 否则,就直接放入创建的数组里。这一步是得到“+”或者“-”
            lst.append(path[i])
            i += 1
    return lst

 2、使用规则,然后合成一个完整的路径:

def apply_rule(path, rules):        # 将数组使用规则,然后合成一个完整的路径
    lst = split_path(path)          # 得到切开的数组
    for symbol in lst:              # 遍历数组元素
        if symbol in rules:         # 如果数组中有元素是字典rules里的,那么就使用规则进行替换
            # lst.index(symbol)是想找到元素symbol在lst数组里所在的索引位置
            # 比如数组['Fl','+','Fr','+']。Fl的索引为0,那么lst.index(symbol)的值为0。lst[0]就是指代数组lst的第一个元素变成rules[symbol]
            # 而rules是一个字典,symbol是Fl,那么rules[symbol]就是冒号后面的值"Fl+Fr+"
            lst[lst.index(symbol)] = rules[symbol]
    # 这组合的方式精髓了(该学习的)
    # 用join函数进行连接。最前面的""的含义是用什么方式进行连接,双引号之间什么都没有就不用任何字符,如果双引号之间有空格等字符,就是用空格等字符去连接。
    # join后面是遍历lst里面的每个元素,取名为symbol,然后将symbol连起来得到path。path的值就是“Fl+Fr+++-Fl-Fr+”
    path = "".join(symbol for symbol in lst)
    return path

 规则的编写:

rules = {
    "Fl": "Fl+Fr+",
    "Fr": "-Fl-Fr"
}

3、画图(和之前差不多):

def draw_path(path):    # 画图的方法,输入变量为原始路径
    lst = split_path(path)
    for symbol in lst:
        if symbol == 'Fl' or symbol == 'Fr':
            forward(length)
        elif symbol == '-':
            left(angle)
        elif symbol == '+':
            right(angle)

完整代码:

from turtle import *

length = 5   # 定义前进长度
angle = 90    # 定义转弯角度

def split_path(path):      # 拆分路径成为数组的形式
    i = 0
    lst = []
    while i < len(path):
        # 如果第i个元素是F的话,那么将当前元素和后一个元素进行组合。这一步是得到Fl或者Fr。
        # 如果不这么切片的话,path[i]是“F”和“l”,或者是“F”和“r”
        if path[i] == 'F':
            lst.append(path[i:i+2])
            i += 2
        else:          # 否则,就直接放入创建的数组里。这一步是得到“+”或者“-”
            lst.append(path[i])
            i += 1
    return lst

def apply_rule(path, rules):        # 将数组使用规则,然后合成一个完整的路径
    lst = split_path(path)          # 得到切开的数组
    for symbol in lst:              # 遍历数组元素
        if symbol in rules:         # 如果数组中有元素是字典rules里的,那么就使用规则进行替换
            # lst.index(symbol)是想找到元素symbol在lst数组里所在的索引位置
            # 比如数组['Fl','+','Fr','+']。Fl的索引为0,那么lst.index(symbol)的值为0。lst[0]就是指代数组lst的第一个元素变成rules[symbol]
            # 而rules是一个字典,symbol是Fl,那么rules[symbol]就是冒号后面的值"Fl+Fr+"
            lst[lst.index(symbol)] = rules[symbol]
    # 这组合的方式精髓了(该学习的)
    # 用join函数进行连接。最前面的""的含义是用什么方式进行连接,双引号之间什么都没有就不用任何字符,如果双引号之间有空格等字符,就是用空格等字符去连接。
    # join后面是遍历lst里面的每个元素,取名为symbol,然后将symbol连起来得到path。path的值就是“Fl+Fr+++-Fl-Fr+”
    path = "".join(symbol for symbol in lst)
    return path

def draw_path(path):    # 画图的方法,输入变量为原始路径
    lst = split_path(path)
    for symbol in lst:
        if symbol == 'Fl' or symbol == 'Fr':
            forward(length)
        elif symbol == '-':
            left(angle)
        elif symbol == '+':
            right(angle)

rules = {
    "Fl": "Fl+Fr+",
    "Fr": "-Fl-Fr"
}


path = "Fl+Fr+"        # 原始路径
speed(0)

path = apply_rule(path,rules)      # 调用规则的方法
draw_path(path)
exitonclick()

论文后面还有一堆高大上画树的方式,但我不是生物领域的。目前就学到此。

综上:

1、学到了规则替换的方式:

  • 简单的替换可以使用replace函数。
  • 复杂的替换可以使用字典的方式进行书写规则,然后拆分成元素,将每个元素进行查找和替换。

2、连接元素的方式:join函数

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值