0

Okey, so im learning python and im trying to create this basic pick-sell game...

import random
global gold
gold = 0

class Fruit:
    def __str__(self):
        return self.name

    def __repr__(self):
        return self.name

class Apple(Fruit):
    def __init__(self):
        self.name = "Apple"
        self.desc = "An Red Apple!"
        self.value = "2 Gold"

class Grapes(Fruit):
    def __init__(self):
        self.name = "Grapes"
        self.desc = "Big Green Grapes!"
        self.value = "4 Gold"

class Banana(Fruit):
    def __init__(self):
        self.name = "Banana"
        self.desc = "Long, Fat Yellow Bananas"
        self.value = "5 Gold"

class Orange(Fruit):
    def __init__(self):
        self.name = "Orange"
        self.desc = "Big Orange Orange"
        self.value = "7 Gold"


inventory = []

print ("Fruits!")
print ("To see your inventroy press: i")
print ("To sell fruits press: s")
print ("To pick fruits press: p")

def action():
    return input("Action: ")


def i ():
    print ("Your Inventory: ")
    print ("*" + str(inventory))

def p ():
    pick = [Apple(), Orange(), Grapes(), Banana()]
    inventory.append (random.choice(pick))

def s ():
    print ("...")

while True:
    actioninput = action()
    if actioninput in ["i", "İ"]:
        i ()
    elif actioninput in ["s", "S"]:
        s ()
    elif actioninput in ["p", "P"]:
        p ()
    else:
        print ("Invalid Action!")

So my questions is:

  1. in def p():, i would like to print the item that has been added to the list. i tryed some things but they didn't work...

  2. I have no idea how to do a "sell" function, how can i delete an item from the list and add it's value to global gold?

i edited the def s(): as like this and i get an error:

def s():
    global gold
    sell = input ("What item would you like to sell?")
    if sell == "Apple":
        inventory.remove (Apple)
        gold = gold + 2
    elif sell == "Orange":
        inventory.remove (Orange)
        gold = gold + 7
    elif sell == "Banana":
        inventory.remove (Banana)
        gold = gold + 4
    elif sell == "Grapes":
        inventory.remove (Grapes)
        gold = gold + 5

ValueError: list.remove(x): x not in list
Mizuchi
  • 53
  • 5
  • 1
    What is wrong with an intermediate value? `added_thing = random.choice(pick) ; inventory.append(added_thing) ; ` – Tadhg McDonald-Jensen May 19 '16 at 13:28
  • take a look at the [methods on `list` objects](https://docs.python.org/3.5/tutorial/datastructures.html#more-on-lists) I think you will be interested in `.pop()` for your second question. – Tadhg McDonald-Jensen May 19 '16 at 13:30
  • 1
    Also note that putting `global gold` in the global scope doesn't mean that all functions can modify the global variable, you need to put the `global` statement **in** the functions that will change it's value. – Tadhg McDonald-Jensen May 19 '16 at 13:31
  • Just a side note, if you made `self.value` an integer instead of a string it would be a lot easier to keep track of the gold you need to add, the first addition to my answer was assuming `self.value` was an integer and will raise a TypeError with your current code, and I am not a fan of my work around for the other addition to my answer. – Tadhg McDonald-Jensen May 19 '16 at 15:08

3 Answers3

2
  1. "in def p():, I would like to print the item that has been added to the list."

The easiest way is to just use an intermediate variable:

def p ():
    pick = [Apple(), Orange(), Grapes(), Banana()]
    fruit_picked = random.choice(pick)
    inventory.append (fruit_picked)
    print("you picked a", fruit_picked)

You could also get the last element of the list with the indice [-1]:

def p ():
    pick = [Apple(), Orange(), Grapes(), Banana()]
    inventory.append (random.choice(pick))
    print("you picked a", inventory[-1])
  1. "How can I delete an item from the list and add it's value to global gold?"

use list.pop to pop out an item and then do stuff with it's .value attribute:

def s():
    global gold #need this in the function that you are modifying the global value
    fruit_sold = inventory.pop() #pop the last item
    gold += fruit_sold.value
  1. "How can I select the specific element to remove from the list"

For this there are a few ways, without making modifications to your Fruit class you can just iterate over the list and check for a fruit that has the same name as what was entered:

def s():
    global gold
    fruit_to_sell = input("what kind of fruit do you want to sell? ")
    for fruit in inventory:
        if fruit.name == fruit_to_sell:
            gold+=fruit.value
            inventory.remove(fruit)
            print("ok, you just sold a(n) {0} for {0.value} gold".format(fruit))
            return #finish the function
    #if no fruit was found
    print("you don't have any of those kind of fruit \n" + 
          "(This demo doesn't check for capitalization)")

The reason you got the error you did is because you tried to remove the class from the inventory, there are only Fruit objects in the list so that didn't make a whole lot of sense:

Apple == Apple() #almost always false, unless you   specifically overloaded __eq__ to make it True.

You could make a change to your Fruit class so that as long as the fruits are the same type (subclass) they will compare equal:

class Fruit:
    def __eq__(self,other):
        return type(self) == type(other) 
    ...

then your sell could be only slightly tweaked to remove any instance:

def s():
    global gold
    sell = input ("What item would you like to sell?")
    if sell == "Apple":
        inventory.remove (Apple()) #make an instance here@
        gold = gold + 2
    elif sell == "Orange":
        inventory.remove (Orange())
        ... #you get the point

Although if you try to sell an Apple when you don't have any this will still raise an error, it could be even better to check if you have any first:

def s():
    global gold
    sell = input ("What item would you like to sell?")
    if sell == "Apple":
        selling = Apple()
    elif sell == "Orange":
        selling = Orange()
    elif sell == "Banana":
        selling = Banana()
    elif sell == "Grapes":
        selling = Grapes()
    if selling in inventory: #make sure you have some of what ever you are selling before trying to sell it!
        inventory.remove(selling)
        gold += int(selling.value.rstrip(" Gold"))
         # I didn't realize value was a str, this shoddy conversion
         #  works but is not a very good solution
    else:
        print("you don't have any of those!\n"+
              "(This demo doesn't check for capitalization)")
Community
  • 1
  • 1
Tadhg McDonald-Jensen
  • 20,699
  • 5
  • 35
  • 59
0

use isinstance() to detect which class the object belongs to.

keep global variable isn't a good approach. Maybe start building an value to pass around functions as an account.

then check your balance before buy. (off budget) etc

CodeFarmer
  • 2,644
  • 1
  • 23
  • 32
  • there is no buying, the user is picking fruit (doesn't cost any money) and how would you use `isinstance` to show the fruit that was picked? especially when the OP was overridden `__repr__` to just show the type of fruit. – Tadhg McDonald-Jensen May 19 '16 at 13:46
0

list_name[-1] is the last item in the list, and hence the one that was most recently appended.

In your case : inventory[-1]

In the sell function you may use list_name.remove('element_to_be_removed') to remove an element for the list.

In your case :

fruit_to_remove = inventory[-1]
inventory.remove(fruit_to_remove)

or use list.pop(). (as per Tadhg McDonald-Jensen's comment)

Ani Menon
  • 27,209
  • 16
  • 105
  • 126
  • however, the OP will need a reference to the original object to `remove` it, so you would have to do something like `fruit_to_remove = inventory[-1] ; inventory.remove(fruit_to_remove)` but that is what the `list.pop()` method is for! :) – Tadhg McDonald-Jensen May 19 '16 at 13:56
  • @TadhgMcDonald-Jensen yeah `.pop()` does it too :) – Ani Menon May 19 '16 at 14:09