Let’s say that I want to initiate a game. Python will ask with inputs the name of the players. Maybe it’s 2 players, maybe 230, it’s open.
Let’s say I want to give all players some simple start scores (Force, Gold and Weapon for examples).
I know there are several methods to do that. It could be Classes (I’m not very good with classes…), with lists of dict or so…
But my problem is that, as the players are created dynamically, I don’t know how to tell Python to create, say, Peter as an instance of Players to get some Players.name, Players.force, etc.
The only way I could think of is to create a external file (a pickle file, for example) that I can ask Python to name Peter.pk and to stock it to be re-read later. But I’m sure I’m wrong here, as classes are supposed to be just for that.
I think I miss a general concept here. What do you think ?
Another option would be to implement a Database, such as SQLite3
To use SQLite3 with Python3.x, there is no installation required; simply import the module.
Although there are many similarities between SQLite and other SQL databases, there are also some major differences (see: Quirks, Caveats, and Gotchas In SQLite). To make the transition between development (which is the best use case for SQLite) and production less complicated, it would be prudent to follow the rules imposed by the a fully featured SQL backend, rather than rely on any “fudging” that can be done with SQLite.
I already used sqlite with python and I didn’t think about that for stocking datas.
Your solution seems to work perfectly. Did you ever thought about a class with every player beeing instance of the class and characteristics beeing datas of that instances ? Do you think it could be relevant with dynamic player entries and unknown number of players ?
Yes, that thought had occurred to me, but as I’ve not got a working example, because I’ve not used any class instance in my code so far, I didn’t suggest it, but a class looks likely to be a good use case for this kind of application.
To move this forward, I would code up a working model for each method and assess how easy each one is to implement, scale and maintain.
I’m sure that OPs here have already done the groundwork and can say which would be the best option; we’ll see.
I would definitely recommend you to go on with a dict of dicts if you don’t want to use classes. Dicts are able to store data as key-value pairs and that will help you a lot since you are working with string player names. Here, I have written down some sample code:
players = {}
name_input = "Just a dummy value."
while name_input != "" :
name_input = input("Enter a name:")
if name_input not in players.keys():
players[name_input] = {} #setting a new key for the new name. It also holds
# a dict value because we will want to get its
# properties like `players["peter"]["weapon"]`
#SET UP THE DEFAULT PROPERTIES:
players[name_input]["weapon"] = "fork"
players[name_input]["health"] = 122
# ETC.
else:
print("Name already exists.")
#Then, when you want to access/edit those properties:
players["peter"]["weapon"] = "golden sword"
Class-ic implementation:
class Player:
def __init__(self, name, weapon, health): # you can add much more args
self.name = name
self.weapon = weapon
self.health = health
players = {}
name_input = "Just a dummy value."
while name_input != "" :
[...]
players[name_input] = Player(name_input, "fork", 122)
[...]
# while updating/accessing to properties:
players["peter"].health = 2000
(In your case, a class is not really required because it plays the role of a dict.-but better to use-)
If you try to work with variable names instead of dict keys holding values about players, you will probably get stuck. Because it is nearly impossible to implement it. Main problem is that you can not convert a string to a variable name. (Actually, there is a “hack” -but not recommended in this case- which is about globals()).
I hope I have well understood your question and this will help you about it.
My major problem here is that my limited knowledge of classes makes me think that they are some dicts… So, yes, class calls are just a bit more elegant but I’m more confortable with dicts. Also, I like Rob’s method with the indices (putting indexes of datas in variables with understandable names).
I supposed that if you wanted to save those entered datas, you will serialize that dict with pickle or json ?
For example, this code could be a Dungeon Master’s helper for a classic table RPG. So the first pass with the python app could be entering every info for players. Then there is the game session. And then, if the game is stopped, I would want to save all datas to recover them laters for the following of that game session…
And if the RPG environnement is a kitchen, your fork is definitely part of the available arsenal.
Hmm, I see the point now. Then, you can go on with @rob42’s recommendation about sqlite.
Just a little point: it is generally a more preferred and simple way to use jsons. (Simpler syntax and usage/transformation). Choose the one fits your taste.
Json sample:
import json
player_data = json.dumps(players) # will give the json string
with open("player_data.json", "w") as file:
file.write(player_data)
Just wanted you to know: when I started to write my first post in this topic, there was just one reply and I just wanted to contribute a bit more. Hope no one took it wrong.(I seem to have intervened a little)
I could of course use sqlite. I just feel like the syntax in python (entire sqlite code + python precode) is a bit heavy.
What do you think about pickle ? As I don’t plan to share my code or to make it cross platform, I thought it was faster and “pythonesque”…
I don’t think there is something to take wrong, here. It’s an open discussion about coding with dynamically entered datas. Every contribution is appreciated.
Just a thought (and this may be way too/overly complicated), but it would be possible to write all the game data that’s been created in dicts or whatever, to a database, then rebuild said data when play resumes. I’ve not thought this through, so it could very well be a throwaway.
I don’t think that would be necessary. If sqlite is chosen, then those datas don’t have to be “rebuild” or “reimported” into the code as the DB file is at local level and python can dialog with it back and forth…
But I can be wrong, here.
In the case of external saving with pickle or json, yes, dicts are to be reimported.
There is also a way to save datas with cvs or even simple text file. xml could be nice, too.
Yep. That’s the reason I like pickle. You can pickle any Python’s object and get it back. The only con is that you can’t understand it if you read it… it’s bytes.
A good logic lies behind the idea. But, to my personal sight, using a bunch of different variables (instead of only one dict etc.) makes things harder to maintain. Since there is not a big deal about it, you may use it.(actually, there may be; see the ‘btw’ part please) That will just need a bit more effort.
That was just a dummy example. Even I didn’t think such deeply .
I think, that was fork, “the-knife-and-fork-thing”.
Btw, since you haven’t got a definite number of players, you will probably need a dict which will store all the indexes.(with player names as keys, of course). What if you don’t use a dict at least for that?
It will probably be required to fill globals() with lots of unnecessary stuff.(lots of vars!)
It is generally “hard”(it requires the usage of undirect ways) and unrecommended to create custom-named variables. To do that, you should do something like globals()[var_name] = value or exec(f"{var_name} = {value}")
So, use a dict for storing those indexes please; if you choose the way you have mentioned(which I don’t recommend much - find it better to use A dict to store all the data) in your last post.
According to that idea’s implementation, to access properties, you should do something like:
gold[ indexes["Peter"] ]
xp_level[ indexes["Peter"] ]
# three diff. vars. total
#Logic:
# find the variable related to your job
# get the index of player name
# get the property using the index
instead of
players["Peter"]["gold"]
players["Peter"]["xp_level"]
# just one var.
#Logic:
# find the key related to your job
# Direct-access to the player property using the key.
# no need to find a "magic index".