Python module learning record 3---replacement rules and connection elements

Take the application of turtle function: L system as an example. (The turtle function is a library for drawing pictures)

论文:《Graphical modeling using L-systems》

The explanation of the L system is a bit biased towards the direction of biological cells. For a detailed introduction, move to Baidu Encyclopedia . Essentially a rewriting system.

B station up main guide: Lantern lighting on the first month

I just learned how to write programs according to requirements, and what the logic of the program should be.

I mainly learned the programming ideas of replacing rules and connecting elements.

'F': Forward '-': Left turn '+': Right turn

Forward length: length (L) Turning angle: angle (A)

Original path: "FFFF" (meaning: forward L, left A, forward L, left A, forward L, left A, forward L)

Rule: F --> F-F+F+FF-F-F+F (meaning, replace all forward Fs with "F-F+F+FF-F-F+F")

For example: after one iteration, the path becomes "F-F+F+FF-F-F+FF-F+F+FF-F-F+FF-F+F+FF-F-F+FF-F+F +FF-F-F+F"

Drawing: (angle = 90. Length defines the size according to the complexity of the graphics. For complex graphics, if you want to see the whole picture, define a smaller length)

Graph "FFFF" of the original path:

The graph after the rule is used once (iterated once):

The graph after using the rule twice (iterating twice):

Code: (Reproduction of Figure 1.6 in the paper)

Code without rules:

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()

Code when there are rules:

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()

How to deal with more complicated ones? For example, Figure 1.10

As you can see, the original path is Fl, but there are two rules. If you write the code according to the replace function above (as shown below)

 Then, there will be a situation:

Original path: Fl

The first step of the program is to run: find the Fl in the original path, replace it with "Fl+Fr+", and the path becomes Fl+Fr+

The second step of the program is to run: run the first rule, find and replace Fl in the original path, and the path becomes Fl+Fr++Fr+;

                            

Note: There are two Fr here, the first is the Fr that has already applied the first rule, and the second is the Fr in the previous path. Ideally, when using the second rule, the first Fr should be unchanged and the second Fr should be changed. But if you still use the replace function, it will not proceed according to the ideal steps.

 

Therefore, another way of replacing rules is needed:

Turn Fl+Fr+ into an array: ['Fl','Fr','+']. Traverse each element in the array, if there is Fl, then the first rule will replace the corresponding element; if there is Fr, then the second rule will replace the corresponding element. simultaneously.

then:

1. Split path:

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. Use the rules, and then synthesize a complete path:

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

 Writing of the rules:

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

3. Drawing (similar to before):

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)

Full code:

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()

There are still a bunch of tall ways to draw trees at the back of the paper, but I am not in the field of biology. That's all for now.

In summary:

1. Learned the way of rule replacement:

  • Simple replacements can use the replace function.
  • Complicated replacements can be written in the form of a dictionary, and then split into elements, and each element is searched and replaced.

2. The way to connect elements: join function

Guess you like

Origin blog.csdn.net/m0_57224196/article/details/130054184
Recommended