Am I crazy, or is this a bug?

I have been trying to make a Processing for Python variation of the Coding Train episode on the toothpick fractal. When I run my code, I get an error on line 56, saying that my method toothpick.intersects(x, y) takes two arguments and I have given it three. But quite clearly I have given it two. Here is the code snippet in question. I have added a line comment after the line which triggered the error.

def intersects(x, y):
        """This function checks if self intersects the point (x, y)."""
        if self.ax == x and self.ay == y:
            return True
        else:
            return False
        
    def createA(self, others):
        """This function checks to see if any other toothpick has an endpoint at self.a.  If it does not, it returns True.
        If it does, it returns False."""
        x = self.ax
        y = self.ay
        available = True
        for other in others:
            different_toothpick = not (other.x != self.x and other.y != self.y)
            if different_toothpick and other.intersects(x, y):  #THIS IS THE PROBLEM PIECE OF CODE THAT TRIGGERS THE ERROR!!!!
                available = False
        if available:
            return toothpick(self.x, self.y, not dir)

In case you think this may be caused by something I did in a previous or later line, here is the full code:

#THIS IS A PYTHON PORT OF THE TOOTHPICK CREATION PROGRAM CREATED BY THE YOUTUBE CHANNEL "THE CODING TRAIN," WITH
#THE ORIGINAL FRACTAL DESIGN CREATED BY OMAR POL.
#PORT CREATED BY WILLIAM GRANNIS




pick_length = 63

picks = []


class toothpick(object):
    """This is a class for toothpicks.  Each toothpick takes in 2 pairs of x/y coordinates as the endpoints, and an
    orientation."""
    def __init__(self, x, y, dir):
        """This function initializes the toothpick.  It takes an x/y coordinate pair and a boolean, True for a 
        horizontal orientaion and False for a vertical one.
        It then assigns the toothpick endpoint locations based on the orientation, vertical or horizontal.
        """
        self.x = x
        self.y = y
        self.dir = dir
        if dir:
            self.ax = self.x - pick_length / 2
            self.ay = self.y
            self.bx = self.x + pick_length / 2
            self.by = self.y
        if not dir:
            self.ay = self.y - pick_length / 2
            self.ax = self.x
            self.by = self.y + pick_length / 2
            self.bx = self.x
            
    def show(self):
        """This function draws the toothpick on the screen, in black, with width 2 and length pick_length."""
        stroke(0)
        strokeWeight(2)
        line(self.ax, self.ay, self.bx, self.by)
        
    def intersects(x, y):
        """This function checks if self intersects the point (x, y)."""
        if self.ax == x and self.ay == y:
            return True
        else:
            return False
        
    def createA(self, others):
        """This function checks to see if any other toothpick has an endpoint at self.a.  If it does not, it returns True.
        If it does, it returns False."""
        x = self.ax
        y = self.ay
        available = True
        for other in others:
            different_toothpick = not (other.x != self.x and other.y != self.y)
            if different_toothpick and other.intersects(x, y):
                available = False
        if available:
            return toothpick(self.x, self.y, not dir)
        
        return False
    def createB(self, others):
        """This function checks to see if any other toothpick has an endpoint at self.b.  If it does not, it returns True.
        If it does, it returns False."""
        x = self.bx
        y = self.by
        available = True
        for other in others:
            different_toothpick = not (other.x != self.x and other.y != self.y)
            if different_toothpick and other.intersects(x, y):
                available = False
        if available:
            return toothpick(self.x, self.y, not dir)
        
        return False    


def setup():
    global picks
    size(600, 600)
    background(255)
    picks.append(toothpick(0, 0, 1))
    
    
    
    
def draw():
    translate(width/2, height/2)
    global picks
    next = []
    
    for pick in picks:
        pick.show()
        nextA = pick.createA(picks)
        nextB = pick.createB(picks)
        if nextA:                   #This is a tricky bit of code.  In Python, anything not explicitly False, or 0, is True, so as long as pick.createA() does not return False, this will execute, even though pick.createA() may return a toothpick.
            next.append(nextA)
        if nextB:                   #Same as above.
            next.append(nextB)
        picks = next  

I am new to programming, and therefore tend to think that anything that goes wrong is my fault. However, it does sound as if py,processing is a work in progress, and I do not think I am crazy. If this is not on me, how do I create a bug report?

Hi! I have forgotten most of Python… but could it be that the method is missing self as an argument?

2 Likes

Yes!! This solved the issue. Thank you. It was my fault (as could be expected). Weird that it didn’t throw an undeclared variable error in the method definition.

This has to do with how classes work in Python – it is core to the Python language, and not specific to Python mode in Processing.

There is an extended discussion here:

And an old thread about the error (being misleading) here:

https://mail.python.org/pipermail/python-dev/2010-May/100238.html

Re:

There is no error because it is actually legal to have a method without “self”. This can either be a staticmethod or a classmethod.

1 Like