【python】py课上机作业3「谢尔宾斯基三角形」「递归输出列表」

1. 绘制谢尔宾斯基三角形(正三角形)

定义:
谢尔宾斯基三角形(英语:Sierpinski triangle)是一种分形,
由波兰数学家谢尔宾斯基在1915年提出.
参考:百度百科
谢尔宾斯基三角形

参考图谢尔宾斯基三角形,分别写两py程序,实现图中两三角形的绘制
图一为:在这里插入图片描述
思路:
首先先定义好画画的方法,我们将需要画的点坐标和颜色传入draw方法中,然后记得一开始要把penup,也就是把笔提起来,要不然就会画下画笔的移动鬼姬.
再定义一个获取两坐标中间位置的坐标的方法,getMid.
我们主要是使用turtle这个库来实现了,方法为使用递归嵌套,每次使degree减一来完成递归操作.每次都把三个顶点的坐标减半.
(当然颜色你是可以根据自己的喜好来的hh)

图一三角形代码区:

import turtle


def draw(points, color):
    t.fillcolor(color)
    t.penup()  # 提起画笔,防止将画笔移动的路劲给画下来
    t.goto(points['left'])
    t.pendown()  # 开始画
    t.begin_fill()
    t.goto(points['top'])
    t.goto(points['right'])
    t.goto(points['left'])
    # 以左上右下的顺序进行画三角形。
    t.end_fill()


def getMid(p1, p2):
    return (p1[0] + p2[0]) / 2, (p1[1] + p2[1]) / 2
    # 获得两点之间的点


def sierpinski(degree, points):
    colors = ["blue", "red", "green", "white", "yellow", "pink", "orange"]
    if degree > 0:
        draw(points, colors[degree - 1])
        # 根据不同的层数来选择不同的颜色
        sierpinski(degree - 1, {
    
    'left': points['left'], 'top': getMid(points['left'], points['top']),
                                'right': getMid(points['left'], points['right'])})
        # 递归调用,实现每次都画一个边长只有原来一半的三角形
        sierpinski(degree - 1, {
    
    'left': getMid(points['left'], points['top']), 'top': points['top'],
                                'right': getMid(points['top'], points['right'])})
        sierpinski(degree - 1,
                   {
    
    'left': getMid(points['left'], points['right']), 'top': getMid(points['top'], points['right']),
                    'right': points['right']})


t = turtle.Turtle()
t.speed(30)  # 速度可以自己设置,不过小了会很慢
points = {
    
    'left': (-200, -100), 'top': (0, 200), 'right': (200, -100)}
# 起始位置,因为最中间时(0,0)。所以我们这样设置
sierpinski(7, points)  # 有7层
turtle.done()

最后我自己运行的效果:
在这里插入图片描述

2. 绘制谢尔宾斯基三角形(倾斜三角形)


图二:
图二要实现:
在这里插入图片描述
思路:
其实很简单,就是把上面实现的稍微改一下,把顶点的位置往右移动一点就不是正三角形了,然后再把配色改一下就ok了

图二三角形代码区:

import turtle


def draw(points, color):
    t.fillcolor(color)
    t.penup()
    t.goto(points['left'])
    t.pendown()
    t.begin_fill()
    t.goto(points['top'])
    t.goto(points['right'])
    t.goto(points['left'])
    t.end_fill()


def getMid(p1, p2):
    return (p1[0] + p2[0]) / 2, (p1[1] + p2[1]) / 2


def sierpinski(degree, points):
    if degree > 1:
        draw(points, "black")
        #因为我们要实现的图片是黑色底的,只有在最后一层的时候才画黄色的三角形,所以这里进行判断,然后再选择不同的颜色进行填充
        sierpinski(degree - 1, {
    
    'left': points['left'], 'top': getMid(points['left'], points['top']),'right': getMid(points['left'], points['right'])})
        sierpinski(degree - 1, {
    
    'left': getMid(points['left'], points['top']), 'top': points['top'],'right': getMid(points['top'], points['right'])})
        sierpinski(degree - 1{
    
    'left': getMid(points['left'], points['right']), 'top': getMid(points['top'], points['right']), 'right': points['right']})
    if degree == 1:
        draw(points, "yellow")
        sierpinski(degree - 1, {
    
    'left': points['left'], 'top': getMid(points['left'], points['top']), 'right': getMid(points['left'], points['right'])})
        sierpinski(degree - 1, {
    
    'left': getMid(points['left'], points['top']), 'top': points['top'], 'right': getMid(points['top'], points['right'])})
        sierpinski(degree - 1, {
    
    'left': getMid(points['left'], points['right']), 'top': getMid(points['top'], points['right']), 'right': points['right']})
t = turtle.Turtle()
t.speed(30)
#因为这次是倾斜的三角形而不是等边三角形,所以把top点稍微歪一点就可以实现
points = {
    
    'left': (-200, -100), 'top': (50, 200), 'right': (200, -100)}
sierpinski(6, points)
turtle.done()

最后我自己的实现效果图:
在这里插入图片描述


3. 递归输出列表

写一个print_list函数,实现同print函数相似的功能。
要求代码中不出现for、while。
也不能这样:
def print_list(lst):
print(lst)

(递归实现)

思路:
因为不能使用for while所以我们可以使用递归切片来进行输出每次列表的第一个元素,然后将从第二个元素开始的新列表传给本身函数进行递归,从而实现输出每一个元素
数字部分我们已经完成了,但是还有中括号部分需要完成,首先因为我们是用递归做的,所以如果直接输出中括号的话会出现很多个,那么要怎么才可以实现在递归函数中是的某些代码只运行一次呢?
我们可以使用全局变量和进行条件判断的方法.
对于前括号,我们使用全局变量来进行控制,一旦发现是第一次运行,就加上一个[,要不然都不加[直接输出首元素.
后括号我们使用条件来进行控制,当长度为1的时候就输出元素和]结尾.
当然因为列表还有很多特殊情况都是需要考虑的,比如列表为空,那么我们就当长度为0时输出[]就可以了.

代码区:

f = 1#全局变量f,f=1代表是第一次运行print_list方法


def print_list(lst):
    global f
    if len(lst) == 0:
        print([])
    elif len(lst) == 1:
        if f == 1:
            print(f"[{
      
      lst[0]}]")
        else:
            f = 1
            print(f"{
      
      lst[0]}]")
    else:
        if f == 1:
            print(f"[{
      
      lst[0]}", end=', ')
            f += 1
            print_list(lst[1:])
        else:
            print(lst[0], end=', ')
            print_list(lst[1:])


def main():
    print([1, 22, 555])
    print_list([1, 22, 555])

    print([])
    print_list([])

    print([521])
    print_list([521])


main()

新手上路,有错请指正;

猜你喜欢

转载自blog.csdn.net/qq_33884853/article/details/124715026