im fairly new to python and im doing a RPG to practice what i'm learning. I have a dictionary of items and i want to get the name of one of them, but when i call it i get a message :
You don't have any<classes.inventory.Item object at 0x7f52e39bce48>left!
My dictionary is this one:
player_items = [{"item":potion, "quantity": 15},
{"item":hipotion, "quantity": 10},
{"item":superpotion, "quantity": 8},
{"item":elixir, "quantity": 3},
{"item":hielixir, "quantity":1},
{"item":grenade, "quantity": 12}]
item = player.items[item_choice]["item"]
player.items[item_choice]["quantity"] -= 1
if player.items[item_choice]["quantity"] == 0:
print(bcolors.FAIL+"\n"+"You don't have any"+str(item)+"left!"+bcolors.ENDC)
class Item:
def __init__(self, name, type, description, prop):
self.name = name
self.type = type
self.description = description
self.prop = prop
class Person:
def __init__(self, hp, mp, atk, df, magic, items):
self.maxhp = hp
self.hp = hp
self.maxmp = mp
self.mp = mp
self.atkhigh = atk+10
self.atklow = atk-10
self.df = df
self.items = items
self.magic = magic
self.actions = ["Attack", "Magic", "Items"]
Anyone know what im doing wrong? Thanks in advance for your time.
EDIT : Found the error. I need to learn more. I just needed to add the name property when i called the item :
print(bcolors.FAIL+"\n"+"You don't have any"+str(item.name)+"left!"+bcolors.ENDC)
Sorry i wasted your time guys.
item isn't the string "potion", for instance; it's a reference to an instance of Item that represents a potion. You need to provide an appropriate __str__ method for your Item class.
#Ifsalazar2010 welcome to python. here are a few things I see you may be doing wrong.
First, your dict values need to be string, otherwise python will try to look for those as object. So write "potion" instead of potion
player_items = [{"item":"potion", "quantity": 15},
{"item":"hipotion", "quantity": 10},
{"item":"superpotion", "quantity": 8},
{"item":"elixir", "quantity": 3},
{"item":"hielixir", "quantity":1},
{"item":"grenade", "quantity": 12}]
Next, you need to use the proper object player_items and not player.items. Your object is a list of dictionaries, which you can call by index and you haven't defined item_choice. I am using the index 1 as example.
item = player_items[1]["item"]
print(item)
player_items[1]["quantity"] -= 1
print(player_items)
In short, seems like you didn't provide detail in your example to replicate your errors. for example what is bcolors.FAIL
Related
I'm new in Python and I'm trying to print a dictionary that I made:
print({
"Mamifero":"Gato",
"Reptil":"Lagartija",
"Mamifero":"Perro",
"Reptil":"Tortuga",
"Reptil":"Serpiente",
"Mamifero":"Koala"
})
But the Windows console only gave me this:
{'Mamifero': 'Koala', 'Reptil': 'Serpiente'}
How do I do to see all the elements using print()?
Your problem actually bypassing the need for unique keys in the dictionary.
As discussed in the thread Make a dictionary with duplicate keys in Python,
the most convenient solution might be in creating custom class as following:
class p(object):
def __init__(self, name):
self.name = name
def __repr__(self):
return self.name
def __str__(self):
return self.name
d = {p('Mamifero'): 'Gato', p('Reptil'): 'Lagartija', p('Mamifero'): 'Perro', p('Reptil'): 'Tortuga', p('Reptil'): 'Serpiente', p('Mamifero'): 'Koala'}
print(d)
Otherwise, the thread provides many similar solutions. This might be the easiest to reproduce, though.
You can use the function .items(), this returns the key and value in a list of tuples. But first define your dictionary.
Example:
dic = {'a' : 1, 'b' : 2, 'c' : 3 , 'd' : 4}
print(dic.items())
First, a dictionary should have distinct keys. After you fix that, I suggest you check out dictionaries' functionalities below:
Input:
# First_Name: [age, job, eyes]
peoples_details = {
"Tom":[25, "Lawyer", "Brown"],
"Adam":[28, "Python Specialist", "Blue"],
"John":[45, "Unemployed", "Green"]
}
for value in peoples_details.values():
print(value)
for you_can_name_this_var_anything_actually in peoples_details.keys():
print(you_can_name_this_var_anything_actually)
for key, value in peoples_details.items():
print(key, value)
Output:
====================== RESTART: C:/Users/tom/Desktop/py.py =====================
[25, 'Lawyer', 'Brown']
[28, 'Python Specialist', 'Blue']
[45, 'Unemployed', 'Green']
Tom
Adam
John
Tom [25, 'Lawyer', 'Brown']
Adam [28, 'Python Specialist', 'Blue']
John [45, 'Unemployed', 'Green']
Thanks everyone, I'm learn something today and I create this as an example of a Dictionary:
dictionary_1 = {"animal":"gato", "numero_patas":4, "cola":True, "edad":3.6, "nombre":None}
print(dictionary_1)
for key, value in dictionary_1.items():
print(key, "=", value)
And the Windows Console gave me this:
{'animal': 'gato', 'numero_patas': 4, 'cola': True, 'edad': 3.6, 'nombre': None}
animal = gato
numero_patas = 4
cola = True
edad = 3.6
nombre = None
Thank you very much.
I am creating a monopoly like game and in this, I have a list which is for the players in this I have a dictionary for each player it is set up like this:
players.append[
{
"playerName": John,
"money": 1500,
"properties": ["Mediterranean Ave"],
"railroads": ["Reading Railroad"],
"inJail": False
}
{
"playerName": Smith,
"money": 1500,
"properties": ["Baltic Ave"],
"railroads": ["B. & O. Railroad"],
"inJail": False
}
]
so whenever a player lands on a property I want to check if anyone owns it and if anyone owns it who does, I tried using the count function but that did not work I also tried using the get function for dictionaries but that also failed what ways may I search for it.
You can try this
def is_property_owned(property_name):
for p in players:
if property_name in p['properties']:
return p['playerName'] #Returns the owner of property
return None # Returns None, if no one is owning it
If this operation is going to be frequently executed, you may want to have another dictionary, say props, that describes who owns which property:
props = {}
for p in players:
props.update({x: p['playerName'] for x in p['properties']})
Then finding the owner of a property is a matter of looking up in the dictionary:
owner = props.get("Baltic Ave", None)
The dictionary must be updated every time the property changes the owner, e.g.:
props["Baltic Ave"] = "Smith"
Or:
del(props["Mediterranean Ave"])
You can use a list comprehension to retrieve a list of people owning a given property:
def property_owner(prop):
return [dic['playerName'] for dic in players if prop in dic['properties']]
property_owner('Mediterranean Ave') # ['John']
property_owner('Whitehouse') # []
I have a list of objects with ids (object.id) and a list of ids. What is the most efficient way to use the list of ids to order the object list? I have the following solution... just wondering whether there is a faster one?
Input:
result = list of user objects with user ids (user.id)
list_of_ids = list of user ids e.g. [3, 2, 5, 8, 9]
Output:
list of user objects ordered according to list_of_ids
Code:
ordered_result = []
for user_id in list_of_ids:
for user in result:
if user_id == user.id:
ordered_result.append(user)
break
You could first put the users in a dict:
usrdict = {}
for user in result:
usrdict[user.id] = user
And then you'd have a few options, based on looking up the users by their id, for example:
ordered_result = [usrdict[x] for x in list_of_ids]
Edit: I'd probably, unless you have a very large list or have perform the operation many times, not worry about efficiency that much, but rather focus on having it clear and readable.
You can use sorted function with custom sorting function. In this case returning index in the ids list.
def order_by(objects, ids):
def fn(obj):
return ids.index(obj["id"])
return sorted(objects, key=fn)
print(order_by(objects_list, id_list))
Example:
objects_list = [
{ "id": 3, "name": "penny"},
{ "id": 5, "name": "adam"},
{ "id": 9, "name": "meh"},
{ "id": 1, "name": "john"},
{ "id": 3, "name": "archibald"},
]
id_list = [9,1,3,5,6,4]
print(order_by(objects_list, id_list))
Results in:
[{'id': 9, 'name': 'meh'}, {'id': 1, 'name': 'john'}, {'id': 3, 'name': 'penny'}, {'id': 3, 'name': 'archibald'}, {'id': 5, 'name': 'adam'}]
Here is an O(n log(n)) solution. It requires the ids in both lists to be exactly the same. It sorts the object list by id and does an indirect sort of the id list yielding an index list containing the positions of ids in order. This is then used to move the sorted objects to the right positions.
import operator
class know_who_you_are:
def __init__(self, id_):
self.id = id_
def argsort(L):
"returns sorted, order"
return zip(*sorted(zip(L, range(len(L)))))
ids = [3, 2, 4, 5, 1]
objs = [know_who_you_are(id_) for id_ in [1, 5, 3, 2, 4]]
sid, oid = argsort(ids)
sobj = sorted(objs, key=operator.attrgetter('id'))
result = len(objs) * [None]
for dest, src in zip(oid, sobj):
result[dest] = src
# check
print(all(id_==obj.id for id_, obj in zip(ids, result)))
Prints:
True
Here's a variation of the scheme using the built-in sorted() function with a custom comparison function. (It may seem like a lot of code, but a significant portion of it is only there for setting up a somewhat realistic test case.)
from functools import cmp_to_key
import random
random.seed(13) # Gets consistent "random" ordering during testing.
class User:
def __init__(self, name, id):
self.name = name
self.id = id
def __repr__(self):
return '{}({!r}, id={!r})'.format(self.__class__.__name__, self.name, self.id)
#cmp_to_key # Converts cmp function to a key function.
def cmp(x, y):
""" Return -1 if the position of User x in list_of_ids < index of User y
otherwise return 1.
"""
p1, p2 = -1, -1
try:
p1 = list_of_ids.index(x.id)
p2 = list_of_ids.index(y.id)
except ValueError:
pass
return -1 if p1 < p2 else 1
list_of_ids = [3, 2, 5, 8, 9]
# Create a random list of users with these ids.
shuffled_ids = random.sample(list_of_ids, k=len(list_of_ids))
users = [User(name, id) for name, id in zip(['Andy', 'Simon', 'Nick', 'John',
'Roger'], shuffled_ids)]
print('Desired id order:', list_of_ids)
print()
print(' Before:', users)
ordered_result = sorted(users, key=cmp)
print('Ordered:', ordered_result)
Output:
Desired id order: [3, 2, 5, 8, 9]
Before: [User('Andy', id=5), User('Simon', id=9), User('Nick', id=8), User('John', id=3), User('Roger', id=2)]
Ordered: [User('John', id=3), User('Roger', id=2), User('Andy', id=5), User('Nick', id=8), User('Simon', id=9)]
I use Falcon framework and neomodel in order to communicate with neo4j database.
I have some nodes in DB and I try to return information about them via API (get methon) as a JSON object.
In order to retrive information I use the code people = Person.nodes
I iterate throu people:
for p in people:
print(p)
and I get:
{'name': 'John', 'id': 0, 'uid': '584d9b0517584b8194f222052bf177ff'}
{'name': 'Paul', 'id': 1, 'uid': 'f5763c01704e449885f846e87e1fcb6d'}
When I do json.dumps() on single entity I get an error:
TypeError: <Person: {'name': 'John', 'id': 0, 'uid': '584d9b0517584b8194f222052bf177ff'}> is not JSON serializable
How can I convert neomodel object into json object?
Using json.dumps(p.__properties__) does the trick. Using p.__dict__ tries to encode the neomodel property classes, which will throw an error.
It seems like every p in your people is an object.
Try something like json.dumps(p.__dict__). If it's a common neomodel node object then this should work.
A bit of an old question but this is how I work with this..
Creating a function on the class so I can control what data to return. With __properies__ instead of the .to_json funtion you will get all properties.
class Player(StructuredNode):
mid = IntegerProperty(unique_index=True)
f_name = StringProperty()
l_name = StringProperty()
email = StringProperty()
team = RelationshipFrom('Team', 'PLAYER', model=PlayerRel)
def to_json(self):
return {
"id": self.mid,
"firstName": self.f_name,
"lastName": self.l_name,
"email": self.email,
"fullName": self.f_name + ' ' + self.l_name
}
Then I have a node with has several Players connected and I just do this to return an array of players that can be serialized:
...
team = Team.nodes.get(team_id=id)
return ([player.to_json() for player in team.players])
I'm trying to separate various functions in my program to keep things neat. And I'm getting stuck trying to use variables created in one module in another module. I tried using global list_of_names but it wasn't working, and I've read that it's recommended not to do so anyway.
Below is a sample of my code. In my opinion, it doesn't make sense to pass list_of_names as a function argument because there are multiple other variables that I need to do this with, aside from the actual arguments that do get passed.
Unfortunately, even if I were to move read_json into engine.py, I'd still have the same problem in main.py as I need to reference list_of_names there as well.
# main.py:
import json
from engine import create_person
def read_json():
with open('names.json', 'r') as file
data = json.load(file)
return data
list_of_names = read_json()
person1 = create_person()
# engine.py:
from random import choice
def create_person():
name = choice(list_of_names)
new_person = {
'name': name,
# other keys/values created in similar fashion
}
return new_person
EDIT1:
Here's my new code. To me, this doesn't seem efficient to have to build the parameter list and then deconstruct it inside the function. (I know I'm reusing variable names for this example) Then I have to pass some of those parameters to other functions.
# main.py:
import json
from engine import create_person
def read_json():
with open('names.json', 'r') as file
data = json.load(file)
return data
player_id_index = 0
list_of_names = read_json()
person_parameters = [
list_of_names,
dict_of_locations,
player_id_index,
dict_of_occupations,
.
.
.
]
person1, player_id_index = create_person()
# engine.py:
from random import choice
def create_person(person_params):
list_of_names = person_params[0]
dict_of_locations = person_params[1]
player_id_index = person_params[2]
dict_of_occupations = person_params[3]
.
.
.
attr = person_params[n]
name = choice(list_of_names)
location = get_location(dict_of_locations) # a function elsewhere in engine.py
p_id = player_id_index
occupation = get_occupation(dict_of_occupations) # a function elsewhere in engine.py
new_person = {
'name': name,
'hometown': location,
'player id': p_id,
'occupation': occupation,
.
.
.
}
player_id_index += 1
return new_person, player_id_index
In general you should not be relying on shared global state. If you need to share state encapsulate the state in objects or pass as function arguments.
Regarding your specific problem it looks like you want to assemble random dictionaries from a set of options. It could be coded like this:
from random import choice
person_options = {
'name': ['fred', 'mary', 'john', 'sarah', 'abigail', 'steve'],
'health': [6, 8, 12, 15],
'weapon': ['sword', 'bow'],
'armor': ['naked', 'leather', 'iron']
}
def create_person(person_options):
return {k:choice(opts) for k, opts in person_options.items()}
for _ in range(4):
print create_person(person_options)
In action:
>>> for _ in range(4):
... print(create_person(person_options))
...
{'armor': 'naked', 'weapon': 'bow', 'health': 15, 'name': 'steve'}
{'armor': 'iron', 'weapon': 'sword', 'health': 8, 'name': 'fred'}
{'armor': 'iron', 'weapon': 'sword', 'health': 6, 'name': 'john'}
{'armor': 'iron', 'weapon': 'sword', 'health': 12, 'name': 'john'}
Note that a dictionary like {'armor': 'naked', 'weapon': 'bow', 'health': 15, 'name': 'steve'} looks like it might want to be an object. A dictionary is a glob of state without any defined behavior. If you make a class to house this state the class can grow methods that act on that state. Of course, explaining all this could make this answer really really long. For now, just realize that you should move away from having shared state that any old bit of code can mess with. A little bit of discipline on this will make your code much easier to refactor later on.
This addresses your edited question:
from random import choice
from itertools import count
from functools import partial
person_options = {
'name': partial(
choice, ['fred', 'mary', 'john', 'sarah', 'abigail', 'steve']),
'location': partial(
get_location, {'heaven':1, 'hell':2, 'earth':3}),
'player id': count(1).next
}
def create_person(person_options):
return {k:func() for k, func in person_options.items()}
However, we are now way beyond the scope of your original question and getting into specifics that won't be helpful to anyone other than you. Such questions are better asked on Code Review Stack Exchange