Louis S.
Louis S.

Reputation: 35

How to solve Index out of range for complex code

I have a code that asks the user if they want the program to draw rectangular patterns (if they enter the number 1) or circular patterns (if they enter number 2).

It works fine, but if the user enters the number 3 then the program randomly has to choose to draw either circular or rectangular patterns in a random place on the screen.

The only input the user has to enter after choosing (3) is how many random patterns should be drawn on the screen.

The problem is that I am getting an error

"line 91, in drawSuperPattern rand_shape = shape_functs[randint(0,1)] IndexError: list index out of range".

I know that it tries to access element 0, rand_shape will set to "drawRectanglePattern" but there is no object at element 1.

How can I solve this? I have tried fixing it but I can't seem to solve it.

if I change it to: shape_functs = [drawRectanglePattern, drawCirclePattern] the code won't work because they take a different number of arguments.

main module:

import pattern

def main():

    while True:
        print("Choose a mode")
        print("1) Rectangle Pattern")
        print("2) Circle Pattern")
        print("3) Super Pattern")

        mode = int(input("Which mode do you want to play? 1, 2 or 3: "))

        pattern.setup()

        if mode == 1:
            width = int(input("Enter width for the rectangles: "))
            height = int(input("Enter height for the rectangles: "))
            offset = int(input("Enter the offset for the rectangle: "))
            count = int(input("Enter how many rectangles you'd like in the pattern: "))
            centerX, centerY = eval(input("Enter center position (x, y): "))

            pattern.drawRectanglePattern(int(centerX), int(centerY), width, height, count, offset)
        elif mode == 2:
            radius = int(input("Enter the radius for the circles: "))
            offset2 = int(input("Enter the offset for the circle: "))
            count = int(input("Enter how many circles you'd like in the pattern: "))
            centerX, centerY = eval(input("Enter center position (x, y): "))

            pattern.drawCirclePattern(int(centerX), int(centerY), radius, count, offset2)
        elif mode == 3:
            super = int(input("Enter how many super patterns you'd like: "))


            pattern.drawSuperPattern(super)

        print("Do you want to play again?")
        print("1) Yes, and keep drawings")
        print("2) Yes, and clear drawings")
        print("3) No, I am all done")

        response = int(input("Choose 1, 2, or 3: "))

        if response == 1:
            pass
        elif response == 2:
            pattern.reset()
        else:
            print("Thanks for playing!")
            break

main()

pattern.py code:

import turtle
from random import choice, randint

turtle.speed('fastest')

SCREEN_WIDTH = 1000
SCREEN_HEIGHT = 800

COLORS = ["pink", "red", "purple", "black", "dark cyan", "lavender", "blue", "yellow", "dark green", "orange", "gold", "brown", "tan"]


def setup():
    turtle.screensize(SCREEN_WIDTH, SCREEN_HEIGHT)
    turtle.speed('fastest')

def reset():
    turtle.clearscreen()

def getRandomColor():
    return choice(COLORS)

def drawRectangle(centerX, centerY, width, height):
    #turtle.goto(centerX - width/2, centerY - height/2)
    turtle.pd()
    turtle.color(getRandomColor())

    for _ in range(2):
        turtle.forward(width)
        turtle.left(90)
        turtle.forward(height)
        turtle.left(90)


def drawRectanglePattern(centerX, centerY, width, height, count, offset):
    rotation = 360 / count
    turtle.pu()
    turtle.goto(centerX, centerY)

    for _ in range(count):

        turtle.pu()

        turtle.forward(offset)
        turtle.right(90+rotation/2)

        drawRectangle(centerX, centerY, width, height)

        turtle.pu()

        turtle.left(90+rotation/2)
        turtle.backward(offset)


        turtle.right(rotation)

def drawCircle(centerX, centerY, radius):

    turtle.pd()
    turtle.color(getRandomColor())
    turtle.circle(radius)


def drawCirclePattern(centerX, centerY, radius, count, offset2):
    rotation = 360 / count
    turtle.pu()
    turtle.goto(centerX, centerY)

    for _ in range(count):

        turtle.pu()

        turtle.forward(offset2)
        turtle.right(90+rotation/2)

        drawCircle(centerX, centerY, radius)


        turtle.pu()

        turtle.left(90+rotation/2)
        turtle.backward(offset2)


        turtle.right(rotation)

def drawSuperPattern(super):

    for i in range(super):
        shape_functs = [drawRectanglePattern]

        rand_shape = shape_functs[randint(0, 1)]

        width = randint(0, 100)
        height = randint(0, 100)
        offset = randint(0, 100)
        count = randint(0, 100)
        centerX = randint(0, 100)
        centerY = randint(0, 100)

        rand_shape(int(centerX), int(centerY), width, height, count, offset)

        shape_funcs = [drawCirclePattern]
        rand_shape2 = shape_funcs[randint(0, 1)]

        offset2 = randint(0, 100)
        count = randint(0, 100)
        radius = randint(0, 100)
        centerX = randint(0, 200)
        centerY = randint(0, 200)

        rand_shape2(centerX, centerY, count, offset2, radius)

Upvotes: 0

Views: 55

Answers (1)

radoh
radoh

Reputation: 4825

You might want to extract the code that draw random rectangle/circle into separate functions without any argument. Then you can call them randomly as you planned originally

def drawRandomRectanglePattern():
    drawRectanglePattern(randint(0, 100), ..., randint(0, 100))

def drawRandomCirclePattern():
    drawCirclePattern(randint(0, 100), ..., randint(0, 100))

and then use them

def drawSuperPattern(super):
    shape_functs = [drawRandomRectanglePattern, drawRandomCirclePattern]
    for i in range(super):
        rand_shape = shape_functs[randint(0, len(shape_functs) - 1)]
        rand_shape()

Upvotes: 2

Related Questions