Getting AttributeError: 'Picture' object has no attribute 'getFrameColour' while trying to access the array file

Question:

The program stores pictures as objects. It stores the dimension, frame colour, and description of the picture. The program needs to input its requirements for a picture. The user will enter colour, width, and height. Then the program will search the array and output the picture description if any picture meets the requirements.

class Picture:

    def __init__(self, DescriptionP, WidthP, HeightP, FrameColourP):
        self.__Description = DescriptionP  # string
        self.__Width = WidthP  # integer
        self.__Height = HeightP  # integer
        self.__FrameColour = FrameColourP  # string


def getDescription(self):
    return self.__Description  # Fixed method to return the associated attribute to the user


def getWidth(self):
    return self.__Width


# Key rule: Only use parameters if they are passed, otherwise only use self and attributes.
def getHeight(self):
    return self.__Height


def getFrameColour(self):
    return self.__FrameColour


# In such questions, do not think much just solve normally. Use the parameters(mentionned...
def SetDescription(self, DescriptionP):
    # ...during class definition) and imagine that they have already been given a value by the user.
    self.__Description = DescriptionP


# Do this to show blank array instead of doing the method where you write 'None' multiple times.
PictureArray = []
# This is class with parameters so can happen directly but can't be blank. In case of...
for i in range(100):
    # ...object with parameters, it has to be defined first(tho can be blank there at least).
    PictureArray.append(Picture("", 0, 0, ""))


def ReadData(PictureArray):  # In object case array is not needed as parameter.
    filename = "C:\Users\ayush\Downloads\Pictures.txt"
    NumberPicturesInArray = 0
    try:
        file = open(filename, "r")
        # For internal work so .lower() used in string case, or bcoz extra variable avoided.
        Description = (file.readline()).strip().lower()
        while (Description != ""):
            # Just prefer mentionning data type for int(and .lower() here for string).
            Width = int((file.readline()).strip())
            Height = int((file.readline()).strip())
            Frame = ((file.readline()).strip()).lower()
            # Extra step to do when without 'object'...
            PictureArray[NumberPicturesInArray] = Picture(
                Description, Width, Height, Frame)
            # ...where '.append' can be thought to be replaced with '[Counter]='.
            Description = ((file.readline()).strip()).lower()
            NumberPicturesInArray = NumberPicturesInArray+1
        PictureArray.append(Picture(DescriptionP=Description,
                            WidthP=Width, HeightP=Height, FrameColourP=Frame))
        file.close()
    except IOError:
        print("Could not find file!")
    return NumberPicturesInArray, PictureArray


    # In the without 'object' case, when a return value is...
# ...there in function then use it to call the function.
NumberPicturesInArray, PictureArray = ReadData(PictureArray)


# .lower allows any case alphabets to be input but be processesed as lower only!
FrameColour = input("Input the Frame colour ").lower()
MaxWidth = int(input("Input the Maximum Width "))
MaxHeight = int(input("Input the Maximum Height "))
print("Matches Frames shown")
for Z in range(0, NumberPicturesInArray):  # This range is crucial.
    if (PictureArray[Z].getFrameColour() == FrameColour):
        if (PictureArray[Z].getWidth() <= MaxWidth):
            if (PictureArray[Z].getHeight() <= MaxHeight):
                print(PictureArray[Z].getDescription(), " ", str(PictureArray[Z].getWidth()), " ", str(
                    PictureArray[Z].getHeight()), " ", PictureArray[Z].getFrameColour())

I’m getting the error-

 if (PictureArray[Z].getFrameColour() == FrameColour):
AttributeError: 'Picture' object has no attribute 'getFrameColour'

I’m trying to call the method to read the array data.

Expected output- Description of the picture

Asked By: Ayush Rai

||

Answers:

Your __init__ method is correctly indented inside the Picture class. However, the other "methods" are not indented at all, so they’re not actually part of the class; they’re simply top-level functions. So when you create an instance of Picture, it does not have a getFrameColour method.

You want something more like this:

class Picture:
    def __init__(self, DescriptionP, WidthP, HeightP, FrameColourP):
        self.__Description = DescriptionP  #string
        self.__Width = WidthP  #integer
        self.__Height = HeightP  #integer
        self.__FrameColour = FrameColourP  #string

    def getDescription(self):
        return self.__Description

    def getWidth(self):
        return self.__Width

    def getHeight(self):
        return self.__Height

    def getFrameColour(self):
        return self.__FrameColour

This does still have some issues. Standard practice in Python is to use "snake_case", for instance using get_frame_colour instead of getFrameColour; more importantly, you don’t really need getter methods at all. It would be much cleaner to use the attributes directly. You might also want to try dataclasses to streamline things.

Answered By: CrazyChucky
Categories: questions Tags:
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.