donkirkby / live-py-plugin

Live coding in Python with PyCharm, Emacs, Sublime Text, or even a browser
https://donkirkby.github.io/live-py-plugin
MIT License
291 stars 57 forks source link

Equivalent solutions for Turtle tutorial aren't always accepted #359

Closed BTWS2 closed 2 years ago

BTWS2 commented 2 years ago

What I did

I tried as many ways as possible to draw a triangle. These solutions are ok.

def normal():  # OK
    turtle.bgcolor('ivory')
    turtle.fillcolor('yellow')
    turtle.begin_fill()
    for _ in range(3):
        turtle.forward(100)
        turtle.right(120)
    turtle.end_fill()

def normal_long():  # OK
    # with unnecessary undo
    turtle.bgcolor('ivory')
    turtle.fillcolor('yellow')
    turtle.begin_fill()
    turtle.forward(100)
    turtle.right(120)
    turtle.forward(100)
    turtle.right(120)
    turtle.undo()
    turtle.undo()
    turtle.forward(100)
    turtle.right(120)
    turtle.forward(100)
    turtle.right(120)
    turtle.end_fill()

def normal_logo():  # OK
    turtle.mode("logo")
    turtle.bgcolor('ivory')
    turtle.fillcolor('yellow')
    turtle.begin_fill()
    turtle.right(90)
    for _ in range(3):
        turtle.forward(100)
        turtle.right(120)
    turtle.end_fill()

def coordinates():  # OK
    turtle.bgcolor('ivory')
    turtle.fillcolor('yellow')
    a = math.sqrt(100 ** 2 - 50 ** 2)
    turtle.begin_fill()
    turtle.goto(100, 0)
    turtle.goto(50, -a)
    turtle.goto(0, 0)
    turtle.end_fill()

These are not.

def backward():  # todo: isn't accepted because of one pixel.
    turtle.bgcolor('ivory')
    turtle.fillcolor('yellow')
    turtle.begin_fill()
    for _ in range(3):
        turtle.right(240)
        turtle.backward(100)
    turtle.end_fill()

def coordinates_variant():  # todo: isn't accepted because of one pixel.
    turtle.bgcolor('ivory')
    turtle.fillcolor('yellow')
    a = math.sqrt(100 ** 2 - 50 ** 2)
    # Start at different corner
    turtle.penup()
    turtle.hideturtle()
    turtle.goto(100, 0)
    turtle.showturtle()
    turtle.pd()
    turtle.begin_fill()
    turtle.goto(50, -a)
    turtle.goto(0, 0)
    turtle.goto(100, 0)
    turtle.end_fill()

def coordinates_variant2():  # todo: isn't accepted because of one pixel.
    turtle.bgcolor('ivory')
    turtle.fillcolor('yellow')
    a = math.sqrt(100 ** 2 - 50 ** 2)
    turtle.home()
    turtle.begin_fill()
    turtle.goto(100, 0)
    turtle.goto(50, -a)
    turtle.goto(0, 0)
    turtle.end_fill()

def polygon_circle():  # todo: isn't accepted because of the left edge.
    a = math.sqrt(100 ** 2 - 50 ** 2)
    r = 100 / (2 * math.sin(math.pi / 3))
    turtle.goto(50, -a)
    turtle.bgcolor('ivory')
    turtle.fillcolor('yellow')
    turtle.begin_fill()
    turtle.circle(r, 360, 3)
    turtle.end_fill()

What happened

Some solutions aren't accepted.

image

What I wanted to happen

All solutions should be accepted.

My environment

Describe the versions of everything you were using:

donkirkby commented 2 years ago

I fixed most of your examples by centring lines on the pixels and allowing small changes in the colour values.

However, polygon_circle() still doesn't match. That's because you draw the left edge twice, and that matters when the line isn't along the pixel grid. The antialiasing will shade the neighbouring pixels darker when you repeatedly draw the same line. To avoid that, you have to only draw that edge once:

import math
import turtle

def polygon_circle():  # todo: isn't accepted because of the left edge.
    a = math.sqrt(100 ** 2 - 50 ** 2)
    r = 100 / (2 * math.sin(math.pi / 3))
    turtle.up()
    turtle.goto(50, -a)
    turtle.down()
    turtle.bgcolor('ivory')
    turtle.fillcolor('yellow')
    turtle.begin_fill()
    turtle.circle(r, 360, 3)
    turtle.end_fill()

polygon_circle()

If we want to avoid being so sensitive, we'd either have to figure out how to turn off antialiasing (I couldn't find an easy way), or use a more sophisticated comparison that looks at neighbouring pixels. We could experiment with that after we get the basics working, and I'll be interested to hear what students get stuck on.