Search code examples
pythontkinterturtle-graphicsl-systems

Why is this L-System only drawing a straight line?


I'm trying to write a program that generates strings, and then draws certain lines based on what character in the string is next. I believe it is generating the strings correctly as I've checked a few iterations by hand, but the turtle I'm using doesn't seem to be working correctly.

For example, the code below should generate the Sierpinski triangle, but only draws a straight line.

I've checked with other L-Systems (such as the dragon curve) and whilst it doesn't produce a horizontal line the results are still incorrect. The strings appear to be correct so I think the problem is with how the turtle module is interpreting my instructions. It's my first time using the module so I wouldn't be surprised if I'd gotten something very basic wrong.

from tkinter import *
import turtle 

Width=500
Height=500

def process_string(string):
    return string.translate(str.maketrans({'A':'B-A-B','B':'A+B+A'}))


def createSystem(seed,depth):
    string=seed
    for i in range(depth):  
        string=process_string(string)
        print(string)
    return(string)


def draw(string):

    t = turtle.RawTurtle(canvas) 
    t.penup()
    t.goto(-0.4*Width,0.4*Height) #this translation fits more of the curve 
                                   on the screen
    t.pendown()
    t.shape("circle")
    t.speed("fastest")


    for char in string:

        if char=="A" or char=="B":
            t.forward(10)
        elif char=="+":
            t.right(60)
        elif char=="-":
            t.left(60)



root=Tk()
canvas=Canvas(width=Width, height=Height)
canvas.pack()    
draw(createSystem("A",3))
print("COMPLETE")
root.mainloop() }

As before, this example should produce the Sierpinski triangle, but just produces a horizontal line.

As a final quick question that I don't think merits its own post, the turtle documentation says that speed("fastest") should remove all animation, however this isn't the case, any ideas? Thanks for your time all!

EDIT: I've updated the code with user suggestions and whilst this provides the correct result for the triangle it still gives an incorrect image for the dragon curve. The information for the dragon curve is

"variables : X Y constants : F + − start : FX rules : (X → X+YF+), (Y → −FX−Y) angle : 90° Here, F means "draw forward", − means "turn left 90°", and + means "turn right 90°". X and Y do not correspond to any drawing action and are only used to control the evolution of the curve."


Solution

  • Problem is

    if char=="A" or "B":
    

    which means

    if (char == "A") or "B":
    

    so it compares char only with "A" and it gives

    if True or "B": 
    

    or

    if False or "B": 
    

    First gives

    if True:
    

    second gives

    if "B": 
    

    but this works like

    if bool("B"): 
    

    which gives

    if True: 
    

    So finnally if char=="A" or "B": works like if True: so this part of code is always executed.


    It has to be

    if char == "A" or char == "B": 
    

    or

    if char in ("A", "B"): 
    

    or

    if char in "AB":   
    

    As @cdlane mention in comment you can also use set()

    if char in {"A", "B"}: 
    

    which need constant time to check char in any size set. But for small set you will no see difference in time.