Python Forum
Calling an class attribute via a separate attribute in input
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Calling an class attribute via a separate attribute in input
#1
Hi, am trying to call a class attribute but am unable to get it to work. When the user inputs the Item.code into a float input, I want to display

"You have selected (Item.name) which is (Item.price). Currently (Item.amount) in stock."

I have read through the basics of Classes on the website, and Inheritance and Overloading. But I can't work out how to refer to the other Item attributes. I can always revert back to just lists, but I know that isn't good code.

Any help would be appreciated.

Code below

class Item:
    def __init__(self, code, name, price, amount):
        self.code = code
        self.name = name
        self.price = price
        self.amount = amount


class VendingMachine:

    def __init__(self):

        self.items = [
            Item(1, "Tea", 0.50, 10),
            Item(2, "Coffee", 1.00, 10),
            Item(3, "Coke", 1.50, 6),
            Item(4, "Orange Juice", 1.00, 5)
        ]
Reply
#2
I don't understand the problem. To access an attribute, you just use a dot on your instance, e.g.

>>> class Item:
...     def __init__(self, code, name, price, amount):
...         self.code = code
...         self.name = name
...         self.price = price
...         self.amount = amount
...  
... 
>>> my_item = Item(1, "Tea", 0.50, 10)
>>> my_item.price
0.5
Reply
#3
I would advise that you use dict, instead of list, e.g.

class Item:
    def __init__(self, code, name, price, amount):
        self.code = code
        self.name = name
        self.price = price
        self.amount = amount

class VendingMachine:
  
    def __init__(self):
  
        self.items = {'1':Item(1, "Tea", 0.50, 10),
                      '2':Item(2, "Coffee", 1.00, 10),
                      '3':Item(3, "Coke", 1.50, 6),
                      '4':Item(4, "Orange Juice", 1.00, 5)}

vending = VendingMachine()
user_choice = input('Item code (1-4):')
item = vending.items[user_choice]
print(f"You have selected {item.name} which is {item.price}. Currently {item.amount} in stock.")
Output:
Item code (1-4):3 You have selected Coke which is 1.5. Currently 6 in stock.
If you can't explain it to a six year old, you don't understand it yourself, Albert Einstein
How to Ask Questions The Smart Way: link and another link
Create MCV example
Debug small programs

Reply
#4
In the example you provide there is no relationship between the key and value other than order. Why do you think a dictionary better than a list in this case? Since the item code will be an integer, or at least easily converted to an integer, vending_items[choice] == vending_items[choice]. Are you suggesting the dictionary to remove converting user input from a string to an int or is there something more subtle?
Reply
#5
(Apr-04-2020, 10:42 AM)deanhystad Wrote: In the example you provide there is no relationship between the key and value other than order.

That's not true, the key is the code of the item (but str, not int). As per OP explanation, user will be required to provide item code. I.e. if the code was something different - e.g. alphanumeric code, it will be used as key. Nothing t do with order.

(Apr-04-2020, 10:42 AM)deanhystad Wrote: Why do you think a dictionary better than a list in this case?

Because that is the easiest way to access specific item from collection. if you use list instead you will need to iterate over list of items in order to find the item with code provided by user. There are different collections and you should choose the best for the task at hand.

(Apr-04-2020, 10:42 AM)deanhystad Wrote: Are you suggesting the dictionary to remove converting user input from a string to an int or is there something more subtle?

You are close... As I said keys are str, not int like the item code so that we don't convert user input to int.

Note that this is just an example. You can make it more dynamic, validate user input and so on...
If you can't explain it to a six year old, you don't understand it yourself, Albert Einstein
How to Ask Questions The Smart Way: link and another link
Create MCV example
Debug small programs

Reply
#6
Hi - thanks guys. Unfortunately if change the list to a dict as Buran suggests, that it impacts me down the line when I try to use enumerate on the items to outline the list - see below

class Item:
    def __init__(self, code, name, price, amount):
        self.code = code
        self.name = name
        self.price = price
        self.amount = amount


class VendingMachine:

    def __init__(self):

        self.items = [
            Item(1, "Tea", 0.50, 10),
            Item(2, "Coffee", 1.00, 10),
            Item(3, "Coke", 1.50, 6),
            Item(4, "Orange Juice", 1.00, 5)
        ]
    def display_items(self):
        for code, item in enumerate(self.items, start=1):
            print(f"[{code}] - {item.name} - (${item.price:.2f})")
Any chance I could the key that has been outlined above in the method display_items? Or is that something different?

Wiggles
Reply
#7
I have a vending machine at work with number and letter keys. Number keys are for columns and letters for rows. I punch a number and a letter and it gives a position in a grid. For example, pressing M5 selects a Coke and pressing C6 a strawberry flavored water. Using a list it would take a little more work to convert button presses into a selection because I would have to search through al the possible selections and compare the selection to a selection ID for the item. Using a dictionary as buran suggests it is simple because the button combination is a key in the dictionary.

For your example where you have items 1, 2, 3... you can use a list or a dictionary. The number would be the position of the item in a list or the key for a dictionary. Essentially a list is a restricted dictionary where a numerical index is the key used to access the value. The nice thing about the dictionary is the key no longer has to be numeric and you can make a vending machine program that works like my soda vending machine.
Reply
#8
Thanks guys. I have solved it using the dict method.

Appreciate the time you guys took to look over it for me
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  AttributeError: 'str' object has no attribute 'size' russoj5 4 7,433 Nov-15-2020, 11:43 PM
Last Post: deanhystad
  Object has no attribute 'replaceall' ? peterp 2 7,172 Nov-10-2020, 09:23 PM
Last Post: buran
  AttributeError: 'list' object has no attribute 'g_s' NitinL 6 3,379 Mar-31-2020, 10:24 AM
Last Post: pyzyx3qwerty
  How can you add an attribute to a function within a class? sjaakthomassen 2 1,901 Mar-18-2020, 12:27 AM
Last Post: scidam
  Attribute error in code 3DEN 1 2,394 Dec-09-2019, 10:43 AM
Last Post: buran
  ERROR NoneType object has no attribute content denizkb 1 2,613 Nov-21-2019, 01:18 PM
Last Post: denizkb
  Attribute Error DiceMann 1 1,907 Nov-01-2019, 06:54 AM
Last Post: buran
  AttributeError: 'tuple' object has no attribute 'move' senfik99 2 4,028 Feb-26-2019, 12:42 PM
Last Post: stullis
  Class and calling a method Zatoichi 3 3,091 Mar-13-2018, 08:44 PM
Last Post: Zatoichi
  text = str(text.encode('utf-8')) AttributeError: 'float' object has no attribute 'enc ulrich48155 2 8,721 Jul-31-2017, 05:21 PM
Last Post: ulrich48155

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020