简体   繁体   English

龟图形动画(架子)

[英]Turtle graphics animation (shelf)

I want to define a function insert_animate(blockposition, shelf, high) such that it removes the block at blockposition from shelf and insert this block into a high position at high , where high is an integer. 我想定义一个函数insert_animate(blockposition, shelf, high) ,使得其在去除块blockpositionshelf和插入在该块到一个较高的位置high ,在high是一个整数。 The function should find this position between zero and the high position, non-inclusive of high. 该函数应该在零和高位之间找到这个位置,不包括高位。 If no such position is found, the block is inserted at the high position. 如果没有找到这样的位置,则将块插入高位置。

I've managed to come up with this function: 我设法提出了这个功能:

def insert_animate(blockposition, shelf, high):
    if blockposition==0:
        return shelf
    else:
        a=s.pop(blockposition)
        for i in range(high):
            if a.size<=s[i].size:
                s.insert(i,a)
                break
            else:
                s.insert(high,a)
        return shelf

However, this only works on some cases, not all. 但是,这仅适用于某些情况,而不是全部。 I am not sure where I went wrong. 我不知道我哪里出错了。

s = shelf.init_shelf((2, 6, 1, 4, 8, 3, 9))
print(insert_animate(0, s, 0)) # returns [Block size: 2, Block size: 6, Block size: 1, Block size: 4, Block size: 8, Block size: 3, Block size: 9]
print(insert_animate(3, s, 3)) 
# returns [Block size: 1, Block size: 2, Block size: 4, Block size: 6, Block size: 4, Block size: 4, Block size: 8, Block size: 3, Block size: 9]

But it should be (for second print): 但它应该是(第二次印刷):

[Block size: 1, Block size: 2, Block size: 4, Block size: 6, Block size: 4, Block size: 4, Block size: 8, Block size: 3, Block size: 9]

print(insert_animate(6, s, 6))
# returns [Block size: 1, Block size: 2, Block size: 4, Block size: 6, Block size: 4, Block size: 4, Block size: 8, Block size: 8, Block size: 8, Block size: 8, Block size: 8, Block size: 8, Block size: 3, Block size: 9]

But it should be: 但它应该是:

[Block size: 1, Block size: 2, Block size: 4, Block size: 6, Block size: 8, Block size: 3, Block size: 9]

Why does my code work for some cases but not for others? 为什么我的代码适用于某些情况但不适用于其他情况? Does the issue lie on my for-loop? 问题出在我的for循环中吗? If anyone could help I would really appreciate it! 如果有人可以提供帮助,我会非常感激! Thank you! 谢谢!

This is the file that I'm working on: 这是我正在处理的文件:

from turtle import *

class Block(Turtle):
    def __init__(self, size):
        self.size = size
        Turtle.__init__(self, shape="square", visible=False)
        self.pu()
        self.shapesize(size * 1.5, 1.5, 2) # square-->rectangle
        self.fillcolor("black")
        self.st()
    def glow(self):
        self.fillcolor("red")
    def unglow(self):
        self.fillcolor("black")
    def __repr__(self):
        return "Block size: {0}".format(self.size)

class Shelf(list):
    def __init__(self, y):
        "create an shelf. y is y-position of first block"
        self.y = y
        self.x = -150
    def push(self, d):
        width, _, _ = d.shapesize()
        yoffset = width/2 * 20 # to align the blocks by it's bottom edge
        d.sety(self.y + yoffset)
        d.setx(self.x+34*len(self))
        self.append(d)
    def _close_gap_from_i(self, i):
        for b in self[i:]:
            xpos, _ = b.pos()
            b.setx(xpos - 34)
    def _open_gap_from_i(self, i):
        for b in self[i:]:
            xpos, _ = b.pos()
            b.setx(xpos + 34)
    def pop(self, key):
        b = list.pop(self, key)
        b.glow()
        b.sety(200)
        self._close_gap_from_i(key)
        return b
    def insert(self, key, b):
        self._open_gap_from_i(key)
        list.insert(self, key, b)
        b.setx(self.x+34*key)
        width, _, _ = b.shapesize()
        yoffset = width/2 * 20 # to align the blocks by it's bottom edge
        b.sety(self.y + yoffset)
        b.unglow()

def show_text(text):
    goto(0,-250)
    write(text, align="center", font=("Courier", 16, "bold"))

def start_sort():
    onkey(None,"space")
    clear()
    show_text("sort_me")
    sort_func(s)

def init_shelf(vals=(4, 8, 2, 9, 3, 1, 10, 7, 5, 6)):
    s = Shelf(-200)
    for i in vals:
        s.push(Block(i))
    return s

def clear_window():
    getscreen().clearscreen()

def main(func):
    global sort_func
    sort_func = func
    getscreen().clearscreen()
    ht(); penup()
    init_shelf()
    show_text("press spacebar to start sorting")
    onkey(start_sort, "space")
    onkey(bye, "Escape")
    listen()
    mainloop()

It's hard to follow your examples of starting order and final order after calling insert_animate() but here's my guess at what's going wrong: 在调用insert_animate()之后很难按照你的启动顺序和最终订单的例子,但这里是我猜错了:

I believe you've got your else clause indented incorrectly (too deep) such that it has become part of the if statement when it really should be part of the for statement: 我相信你的else子句缩进不正确(太深),以至于当它真的应该成为for语句的一部分时它已经成为if语句的一部分:

def insert_animate(blockposition, shelf, high):

    if blockposition == 0:
        return shelf

    a = s.pop(blockposition)

    for i in range(high):
        if a.size <= s[i].size:
            s.insert(i, a)
            break
    else:  # no break
        s.insert(high, a)

    return shelf

As originally written, the else clause could be executed multiple times but you only want it executed once, when the for loop exits via a means other than break . 正如最初编写的那样, else子句可以执行多次,但是当for循环通过除break之外的方式退出时,你只需要执行一次。 An else clause tied to a loop in this manner can be thought of as meaning "no break", ie execute this code if the loop has a break statement but it wasn't taken. 以这种方式绑定到循环的else子句可以被认为是“不中断”,即如果循环具有break语句但是没有被执行则执行此代码。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM