![]() |
another positional argument error (...and executing objects stored in a list) - Printable Version +- Python Forum (https://python-forum.io) +-- Forum: Python Coding (https://python-forum.io/forum-7.html) +--- Forum: Homework (https://python-forum.io/forum-9.html) +--- Thread: another positional argument error (...and executing objects stored in a list) (/thread-14137.html) |
another positional argument error (...and executing objects stored in a list) - itmustbebunnies - Nov-16-2018 Okay, Python gurus - your help solving this issue, please? I am writing a program that asks a user to make a selection to enter information that is used to create an instance of a class that is then stored in a list to be called upon for drawing (using turtle). I have two different classes: Circle and Rectangle. Here is my main code: from circle import Circle from rectangle import Rectangle def main(): playAgain = True list = [] while playAgain: print("1) Enter Circle") print("2) Enter Rectangle") print("3) Remove Shape") print("4) Draw Shapes") print("5) Exit") menu = int(input("What would you like to do? ")) color_list = ["red", "yellow", "blue", "green"] # Enter Circle if menu == 1: centerX, centerY = eval(input("Enter the center position (x,y): ")) radius = eval(input("Enter radius: ")) correct = False while not correct: print("0) Red") print("1) Yellow") print("2) Blue") print("3) Green") color = eval(input("Choose a color: ")) if color == 0 or color == 1 or color == 2 or color == 3: color = color_list[color] correct = True else: print("You have made an invalid selection. Please try again.") correct = False circle = Circle(centerX, centerY, radius, color) list.append(circle) # Enter Rectangle if menu == 2: startX, startY = eval(input("Enter the starting position (x,y): ")) height = eval(input("Enter height: ")) width = eval(input("Enter width: ")) correct = False while not correct: print("0) Red") print("1) Yellow") print("2) Blue") print("3) Green") color = eval(input("Choose a color: ")) if color == 0 or color == 1 or color == 2 or color == 3: color = color_list[color] correct = True else: print("You have made an invalid selection. Please try again.") correct = False rectangle = Rectangle(startX, startY, height, width, color) list.append(rectangle) # Remove Shape if menu == 3: if len(list) > 0: print("The list contains", len(list), "objects.") remove = int(input("Please select an item from 1 to " + str(len(list)) + " to remove that object:")) del list[remove - 1] else: print("The list contains no objects.") # Draw Shapes if menu == 4: for circle in list: circle.draw(centerX, centerY, radius, color) for rectangle in list: rectangle.draw(startX, startY, height, width, color) # Exit if menu == 5: playAgain = False print() print("Thank you for playing.") main()Here is my circle code: import turtle class Circle: def __init__(self, centerX, centerY, radius, color): self.centerX = centerX self.centerY = centerY self.radius = radius self.color = color def draw(self, centerX, centerY, radius, color): turtle.hideturtle() turtle.penup() turtle.setheading(0) turtle.pencolor(color) turtle.goto(centerX, centerY - radius) turtle.pendown() turtle.fillcolor(color) turtle.begin_fill() turtle.circle(radius) turtle.penup() turtle.end_fill()Here is my rectangle code: class Rectangle: def __init__(self, startX, startY, height, width, color): self.startX = startX self.startY = startY self.height = height self.width = width self.color = color def draw(self, startX, startY, width, height, color): turtle.hideturtle() turtle.setheading(0) turtle.penup() turtle.goto(startX, startY) turtle.pencolor(color) turtle.fillcolor(color) turtle.pendown() turtle.begin_fill() turtle.forward(width) turtle.right(90) turtle.forward(height) turtle.right(90) turtle.forward(width) turtle.right(90) turtle.forward(height) turtle.end_fill() turtle.penup()When I select to enter a circle, I am able to input all of the info and it appears to store it as an object in the list (when I use print(list)to verify). The same is true of adding a Rectangle object to the list. The issue I am encountering is when I go to draw the objects. The turtle window will open and the first object will draw, but then I am getting the following error: The turtle will draw the first shape and fill it in with the color selected for the last object, but then it immediately gives me this error. (Also, I know eval is not best practice - but it is how we have been told to do assignments in this class.) Thank you for your time and effort. RE: another positional argument error (...and executing objects stored in a list) - buran - Nov-16-2018 when you iterate over element in the list like this for circle in list:it doesn't matter you say circle, it iterates over all elements in the list - both instances of class Circle and instances of class Rectangle, i.e. it does not filter just circles. So I guess you have both circles and rectangles in the list and when there is error your 'circle' is actually instance of class Rectangle and expect 5 arguments, not 4 Not related to your problem, but as an advise - don't use list as variable name, it's built-in function and it will not be available to you. RE: another positional argument error (...and executing objects stored in a list) - itmustbebunnies - Nov-16-2018 Thanks for your help. I've changed the name of my list to shape_list and used if/elif statements to check the type of object in the list before executing draw() from class Circle or class Rectangle: main code: from circle import Circle from rectangle import Rectangle import turtle def main(): playAgain = True shape_list = [] while playAgain: print("1) Enter Circle") print("2) Enter Rectangle") print("3) Remove Shape") print("4) Draw Shapes") print("5) Exit") menu = int(input("What would you like to do? ")) color_list = ["red", "yellow", "blue", "green"] # Enter Circle if menu == 1: centerX, centerY = eval(input("Enter the center position (x,y): ")) radius = eval(input("Enter radius: ")) correct = False while not correct: print("0) Red") print("1) Yellow") print("2) Blue") print("3) Green") color = eval(input("Choose a color: ")) if color == 0 or color == 1 or color == 2 or color == 3: color = color_list[color] correct = True else: print("You have made an invalid selection. Please try again.") correct = False circle = Circle(centerX, centerY, radius, color, "circle") shape_list.append(circle) # Enter Rectangle if menu == 2: startX, startY = eval(input("Enter the starting position (x,y): ")) height = eval(input("Enter height: ")) width = eval(input("Enter width: ")) correct = False while not correct: print("0) Red") print("1) Yellow") print("2) Blue") print("3) Green") color = eval(input("Choose a color: ")) if color == 0 or color == 1 or color == 2 or color == 3: color = color_list[color] correct = True else: print("You have made an invalid selection. Please try again.") correct = False rectangle = Rectangle(startX, startY, height, width, color, "rectangle") shape_list.append(rectangle) # Remove Shape if menu == 3: if len(shape_list) > 0: print("The list contains", len(shape_list), "objects.") remove = int(input("Please select an item from 1 to " + str(len(shape_list)) + " to remove that object:")) del shape_list[remove - 1] else: print("The list contains no objects.") # Draw Shapes if menu == 4: turtle.hideturtle() turtle.setheading(0) for i in shape_list: if i.isCircle(): circle.draw(centerX, centerY, radius, color) elif i.isRectangle(): rectangle.draw(startX, startY, height, width, color) turtle.exitonclick() # Exit if menu == 5: playAgain = False print() print("Thank you for playing.") main()class Circle: import turtle class Circle: def __init__(self, centerX, centerY, radius, color, kind = "circle"): self.__centerX = centerX self.__centerY = centerY self.__radius = radius self.__color = color self.kind = "circle" def isCircle(self): if self.kind == "circle": return True def isRectangle(self): if self.kind == "circle": return False def draw(self, __centerX, __centerY, __radius, __color): turtle.penup() turtle.pencolor(__color) turtle.goto(__centerX, __centerY - __radius) turtle.pendown() turtle.fillcolor(__color) turtle.begin_fill() turtle.circle(__radius) turtle.penup() turtle.end_fill()class Rectangle: import turtle class Rectangle: def __init__(self, startX, startY, height, width, color, kind): self.__startX = startX self.__startY = startY self.__height = height self.__width = width self.__color = color self.kind = "rectangle" def isRectangle(self): if self.kind == "rectangle": return True def isCircle(self): if self.kind == "rectangle": return False def draw(self, __startX, __startY, __height, __width, __color): turtle.penup() turtle.goto(__startX, __startY) turtle.pencolor(__color) turtle.fillcolor(__color) turtle.pendown() turtle.begin_fill() turtle.forward(__width) turtle.right(90) turtle.forward(__height) turtle.right(90) turtle.forward(__width) turtle.right(90) turtle.forward(__height) turtle.end_fill() turtle.penup()The program appears to work. Turtle will draw the circular and rectangular shapes in their given location, but ALL of the shapes are drawn in the color of the shape that was last added to the list. Any ideas where I'm going wrong on color assignment? RE: another positional argument error (...and executing objects stored in a list) - ichabod801 - Nov-16-2018 I'm not sure if this is the issue, but when you create the Circle or Rectangle classes, you store the details of the shape in various values: self.__startX, self.startY, and so on. But then when you draw them, you require the values to be passed to the draw method as parameters. I would just use the values you already stored. So line 22 of the rectangle class is turtle.goto(__startX, __startY) . I would remove __startX and __startY from the parameter list of draw, and instead use turtle.goto(self.__startX, self.__startY) . Then do the same for all of the other variables used in the draw method.
RE: another positional argument error (...and executing objects stored in a list) - itmustbebunnies - Nov-16-2018 Oooh! I was hopeful that would solve the problem (it made sense that it might...). I made the change: class Circle: import turtle class Circle: def __init__(self, centerX, centerY, radius, color, kind = "circle"): self.__centerX = centerX self.__centerY = centerY self.__radius = radius self.__color = color self.kind = "circle" def isCircle(self): if self.kind == "circle": return True def isRectangle(self): if self.kind == "circle": return False def draw(self): turtle.penup() turtle.pencolor(self.__color) turtle.goto(self.__centerX, self.__centerY - self.__radius) turtle.pendown() turtle.fillcolor(self.__color) turtle.begin_fill() turtle.circle(self.__radius) turtle.penup() turtle.end_fill()class Rectangle: import turtle class Rectangle: def __init__(self, startX, startY, height, width, color, kind): self.__startX = startX self.__startY = startY self.__height = height self.__width = width self.__color = color self.kind = "rectangle" def isRectangle(self): if self.kind == "rectangle": return True def isCircle(self): if self.kind == "rectangle": return False def draw(self): turtle.penup() turtle.goto(self.__startX, self.__startY) turtle.pencolor(self.__color) turtle.fillcolor(self.__color) turtle.pendown() turtle.begin_fill() turtle.forward(self.__width) turtle.right(90) turtle.forward(self.__height) turtle.right(90) turtle.forward(self.__width) turtle.right(90) turtle.forward(self.__height) turtle.end_fill() turtle.penup()and changed the applicable section of my main code: from circle import Circle from rectangle import Rectangle import turtle def main(): playAgain = True shape_list = [] while playAgain: print("1) Enter Circle") print("2) Enter Rectangle") print("3) Remove Shape") print("4) Draw Shapes") print("5) Exit") menu = int(input("What would you like to do? ")) color_list = ["red", "yellow", "blue", "green"] print(shape_list) # Enter Circle if menu == 1: centerX, centerY = eval(input("Enter the center position (x,y): ")) radius = eval(input("Enter radius: ")) correct = False while not correct: print("0) Red") print("1) Yellow") print("2) Blue") print("3) Green") color = eval(input("Choose a color: ")) if color == 0 or color == 1 or color == 2 or color == 3: color = color_list[color] correct = True circle = Circle(centerX, centerY, radius, color, "circle") shape_list.append(circle) else: print("You have made an invalid selection. Please try again.") correct = False # Enter Rectangle if menu == 2: startX, startY = eval(input("Enter the starting position (x,y): ")) height = eval(input("Enter height: ")) width = eval(input("Enter width: ")) correct = False while not correct: print("0) Red") print("1) Yellow") print("2) Blue") print("3) Green") color = eval(input("Choose a color: ")) if color == 0 or color == 1 or color == 2 or color == 3: color = color_list[color] correct = True rectangle = Rectangle(startX, startY, height, width, color, "rectangle") shape_list.append(rectangle) else: print("You have made an invalid selection. Please try again.") correct = False # Remove Shape if menu == 3: if len(shape_list) > 0: print(shape_list) print("The list contains", len(shape_list), "objects.") remove = int(input("Please select an item from 1 to " + str(len(shape_list)) + " to remove that object:")) del shape_list[remove - 1] print(shape_list) else: print("The list contains no objects.") # Draw Shapes if menu == 4: turtle.hideturtle() turtle.setheading(0) for i in shape_list: if i.isCircle(): circle.draw() elif i.isRectangle(): rectangle.draw() turtle.exitonclick() # Exit if menu == 5: playAgain = False print() print("Thank you for playing.") main()I am still running into the same issue where the color of the shape last added to the list is being used for every object. I also have just realized, as well, that the object is drawn in the position of the last object of that type's given position. Any other ideas? RE: another positional argument error (...and executing objects stored in a list) - ichabod801 - Nov-16-2018 This bit of code is your problem: for i in shape_list: if i.isCircle(): circle.draw() elif i.isRectangle(): rectangle.draw()You want to draw i, but you are drawing circle. The circle variable is rewritten every time you enter a new circle, and then appended to shape_list. Also note that both Circle and Rectangle objects have a draw method, so you don't need to figure out what type of shape it is to draw it. Try this instead: for shape in shape_list: shape.draw() RE: another positional argument error (...and executing objects stored in a list) - buran - Nov-16-2018 you also don't need def isCircle(self): if self.kind == "circle": return True def isRectangle(self): if self.kind == "circle": return Falseand also def isRectangle(self): if self.kind == "rectangle": return True def isCircle(self): if self.kind == "rectangle": return Falsenor .kind property
RE: another positional argument error (...and executing objects stored in a list) - itmustbebunnies - Nov-16-2018 I must've misunderstood what you were telling me before, buran. I thought that testing the object type, somehow, using isCircle/isRectangle would solve my issue? I have removed it from both classes and removed the kind property, as well. Also, I've changed for i in shape_list: if i.isCircle(): circle.draw() elif i.isRectangle(): rectangle.draw()to for shape in shape_list: shape.draw()as ichabod801 pointed out. I also made a few minor tweaks (e.g. resetting the turtle screen each time user selects draw) and the code is now working as intended! ![]() |