Python is my first language, and I am very new to it, so the answer may be very clear, but after many hours looking and experimenting, I am not sure what is causing the problem.
An overview of the module:
The DicePool module is meant to manage collections of “dice”, stored as dictionary items. Each dictionary key (herein poolKey) has a list containing information about one “type” of dice, most importantly, a tuple describing its faces and an integer representing the quantity of “dice” type ‘x’ in the “pool.”
My specific question regards the Transfer method, which used to be two methods (send and receive, basically), but which I thought I could combine into one method. When the test code at the bottom runs, I’d like it to leave dp.dictPool[poolKey][1] == 0 and dp2.dictPool[poolKey][1] == 2. But in every attempt I’ve made, the values come out the same. Sorry I can’t categorize this question better . . . I don’t really know what the problem is.
Anyway, one half of the Transfer method is supposed to run for the “sender” instance, and one half is supposed to run for the “receiver” instance.
import random
class DicePool(object):
def __init__(self):
self.dictPool = {}
def AddDice(self, poolKey, faces = 6, quant = 1, color = "white"):
'''faces must be int or items 'a,b,c'; count must be int or def to 1'''
try: #if count is not an integer, it defaults to 1
quant = int(quant)
except:
print("Quant is not an integer, defaulting to 1")
quant = 1
try: #if faces is can be int, a list is built of numbers 1 to faces
faces = int(faces)
if faces < 2: #a 1 or 0-sided die breaks the program
faces = 2
tempList = []
for i in range(1, faces+1):
tempList.append(i)
faces = tempList
except: #if faces is not an integer, it is split into list items by ","
faces = faces.split(",")
if poolKey in self.dictPool.keys(): #if the key already exists in pool
self.dictPool[poolKey][1] += quant #add to the quantity,
else: #if the key does not already exist, set all attributes
self.dictPool[poolKey] = [faces, quant, color]
def Transfer(self, poolKey, targetPool, sendQuant, senderPool = None):
'''targetPool must be DicePool instance'''
if targetPool:
self.dictPool[poolKey][1] -= sendQuant
targetPool.Transfer(poolKey, None, sendQuant, self)
else:
try:
self.dictPool[poolKey][1] -= sendQuant
except:
self.dictPool[poolKey] = senderPool.dictPool[poolKey]
self.dictPool[poolKey][1] = sendQuant
dp = DicePool()
dp2 = DicePool()
dp.AddDice("d6")
dp.AddDice("d6")
dp.Transfer("d6",dp2,2)
print(dp.dictPool,dp2.dictPool)
The problem is in this line:
The values in your dictPools are lists. Here, you set one object’s dictPool value to the same list as in the other one. Not a copy of the list, but the same list. So later if you add or subtract from that list, it will affect the other as well, because they are sharing one list object.
Try doing
self.dictPool[poolKey] = senderPool.dictPool[poolKey][:]. The[:]grabs the contents of the list rather than the list object iself.