maximew
maximew

Reputation: 1

Can user "input" an object's attribute, so it uses it to call a method of this specific object?

Here's a working code I wrote:

#!/usr/bin/env python3

class c: 
    def __init__(self, name, colour):
        self.name = name 
        self.colour = colour
     
    def speak(self):
        print ("You're a " + self.name)
                 
obj1 = c('table', 'red')
obj2 = c('chair', 'blue')


ask = input("Enter a colour and I'll tell you which object you are > ")

if ask == obj1.colour:
    obj1.speak()
elif ask == obj2.colour:
    obj2.speak()

If I want to make this same "game stuff" with lots of objects, guess I have to add some "if statement" for each new object, like this:

elif ask == obj3.colour:
    obj3.speak()
elif ask == obj4.colour:
    obj4.speak()
elif ask == obj5.colour:
    obj5.speak()

but instead of having this uncool long "if list", is there any kind of short line code/function that would act like:

ask.speak()

In other words: Let the user "input" an object's attribute, so Python recognizes the object to which it belongs, and then Python calls a specific method for this object.

Upvotes: 0

Views: 480

Answers (3)

chepner
chepner

Reputation: 531490

You want a build a map of colors to objects with that color:

obj1 = c('table', 'red')
obj2 = c('chair', 'blue')
colour2object = {
  'red': obj1,
  'blue': obj2
}


ask = input("Enter a colour and I'll tell you wich object you are > ")

if ask in color2object:
    color2object[ask].speak()
else:
    print(f"No object with color {ask}")

Such a map can be populated as each instance is created.

class c:
    colour2object = {}

    def __init__(self, name, colour):
        self.name = name 
        self.colour = colour
        self.color2object[colour] = self 

    def speak(self):
        print ("You're a " + self.name)

obj1 = c('table', 'red')
obj2 = c('chair', 'blue')

ask = input(...)
if ask in c.color2object:
    c.color2object[ask].speak()
else:
    ...

Upvotes: 1

Macattack
Macattack

Reputation: 1990

The simplest modification to your current solution would be to use a list and a for loop:

objlist = []
obj1 = c('table', 'red')
objlist.append(obj1)
obj2 = c('chair', 'blue')
objlist.append(obj2)
# or
objlist = [
    c('table', 'red'),
    c('chair', 'blue'),
]


ask = input("Enter a colour and I'll tell you wich object you are > ")

for obj in objlist:
    if ask == obj.colour:
        obj.speak()
        break

Another approach you could take is to use a dictionary

objlist = [
    c('table', 'red'),
    c('chair', 'blue'),
]
objmap = {v.colour: v for v in objlist}

ask = input("Enter a colour and I'll tell you wich object you are > ")

obj = objmap[ask]
obj.speak()

Upvotes: 0

Dhruv Pillai
Dhruv Pillai

Reputation: 112

Your basic limitation here is that there is no defined container or structure that groups all of your objects together.

You could accomplish this pretty easily by storing all of your objects in a list and iterating through the list to find the matching color, like so:

objects = [
    c('table', 'red')
    c('chair', 'blue')
    ...
]

ask = input("Enter a colour and I'll tell you wich object you are > ")

for object in objects:
    if object.colour == ask:
        object.speak()

There are some notes for how the above implementation will function--namely, the loop will iterate through every object in the list and allow all objects that match the input color to call the speak method. If you'd prefer to stop looping through as soon as you've found the first object that matches the input color, you can add a break instruction immediately following the speak invocation.

Upvotes: 0

Related Questions