-1
class Option:
    def __init__(self, activeScore, scope, influence, text):
        self.activeScore = activeScore  # activation score
        self.scope = scope
        self.influence = influence
        self.text = text

    def Active(self, score):
        if self.activeScore <= score <= self.activeScore + self.scope:
            return 1
        return 0

class Stage:
    def __init__(self, stageNo, optionList = [], stageName='stage'):
        self.stageNo = stageNo
        self.optionList = optionList  # list of objects of class Option
        self.stageName = stageName

    def AddStageOption(self, option: Option):
        self.optionList.append(option)

    def ActiveOptions(self, score):
        for option in self.optionList:
            if option.Active(score):
                yield option

class Story:
    def __init__(self, storyName):
        self.storyName = storyName
        self.stageDict = {}
        self.score = 10

# *******************I think the problem is here ************************

    def AddOption(self, text, activeScore, scope, influence, stageNo):
        if stageNo not in self.stageDict:
            self.stageDict[stageNo] = Stage(stageNo)
            print(f'\nCreated Stage : {stageNo}, Current Stages : {[self.stageDict[stage].stageNo for stage in self.stageDict]}\nStage: {stageNo} Options:'
              f' {[option.text for option in self.stageDict[stageNo].optionList]}\n')
        self.stageDict[stageNo].AddStageOption(Option(activeScore, scope, influence, text))
        print(f'Added Option: {text} to Stage: {stageNo}')

# ***********************************************************************

    def StartStory(self):
        stageList = []
        for stageNo in self.stageDict:
            stageList.append(stageNo)
        stageList.sort()
        for stageNo in stageList:
            activeOptions = list(self.stageDict[stageNo].ActiveOptions(self.score))
            print([option.text for option in self.stageDict[2].optionList], end='\n')
            print([option.text for option in activeOptions])
            choice = int(input(f'\nEnter your choice(1-{len(activeOptions)}) : '))
            self.score += activeOptions[choice - 1].influence
            break

abc = Story('ABC')
abc.AddOption('A', 10, 10, 5, 1)
abc.AddOption('B', 30, 10, 5, 1)
abc.AddOption('C', 50, 10, 5, 1)
abc.AddOption('D', 70, 10, 5, 1)
abc.AddOption('E', 10, 10, 5, 2)
abc.AddOption('F', 30, 10, 5, 2)
abc.AddOption('G', 50, 10, 5, 2)
abc.AddOption('H', 70, 10, 5, 2)
abc.AddOption('I', 10, 10, 5, 3)
abc.AddOption('J', 30, 10, 5, 3)
abc.AddOption('K', 50, 10, 5, 3)
abc.AddOption('L', 70, 10, 5, 3)
abc.AddOption('M', 10, 10, 5, 4)
abc.AddOption('N', 30, 10, 5, 4)
abc.AddOption('O', 50, 10, 5, 4)
abc.AddOption('P', 70, 10, 5, 4)
abc.AddOption('Q', 10, 10, 5, 5)
abc.AddOption('R', 30, 10, 5, 5)
abc.AddOption('S', 50, 10, 5, 5)
abc.AddOption('T', 70, 10, 5, 5)
abc.AddOption('U', 10, 10, 5, 6)
abc.AddOption('V', 30, 10, 5, 6)
abc.AddOption('W', 50, 10, 5, 6)
abc.AddOption('X', 70, 10, 5, 6)

abc.StartStory()

'''

Output:

Created Stage : 1, Current Stages : [1]
Stage: 1 Options: []

Added Option: A to Stage: 1
Added Option: B to Stage: 1
Added Option: C to Stage: 1
Added Option: D to Stage: 1

Created Stage : 2, Current Stages : [1, 2]
Stage: 2 Options: ['A', 'B', 'C', 'D']

Added Option: E to Stage: 2
Added Option: F to Stage: 2
Added Option: G to Stage: 2
Added Option: H to Stage: 2

Created Stage : 3, Current Stages : [1, 2, 3]
Stage: 3 Options: ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H']

Added Option: I to Stage: 3
Added Option: J to Stage: 3
Added Option: K to Stage: 3
Added Option: L to Stage: 3

Created Stage : 4, Current Stages : [1, 2, 3, 4]
Stage: 4 Options: ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L']

Added Option: M to Stage: 4
Added Option: N to Stage: 4
Added Option: O to Stage: 4
Added Option: P to Stage: 4

Created Stage : 5, Current Stages : [1, 2, 3, 4, 5]
Stage: 5 Options: ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P']

Added Option: Q to Stage: 5
Added Option: R to Stage: 5
Added Option: S to Stage: 5
Added Option: T to Stage: 5

Created Stage : 6, Current Stages : [1, 2, 3, 4, 5, 6]
Stage: 6 Options: ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T']

Added Option: U to Stage: 6
Added Option: V to Stage: 6
Added Option: W to Stage: 6
Added Option: X to Stage: 6
['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X']
['A', 'E', 'I', 'M', 'Q', 'U']

Enter your choice(1-6) :

'''

Description:

Instead of adding options to a particular stage why is that option being added to all the stages in the dictionary?

''' ''' I'm encountering an issue with the 'AddOption()' function within the 'Story' class that I've been trying to resolve. It seems that, rather than adding options to a specific stage, the options are being added to all stages in the dictionary. I've marked the relevant section in the code for reference.

To address this, I attempted to enhance the 'Option' class by introducing a 'stageNo' attribute. As the 'Stage' class already possesses a 'stageNo' attribute, I aimed to validate whether the options are correctly added to the corresponding stages by utilizing an if statement within the 'AddStageOption()' function within the 'Stage' class. Unfortunately, this approach did not yield the desired outcome.

What's puzzling me is why the options are being added not only to all the existing 'Stage' objects within the 'stageDict' dictionary but also to 'Stage' objects created subsequently. I suspect there might be a minor oversight on my part that's causing this behavior. I would greatly appreciate your assistance in resolving this issue. Please feel free to ask me any questions, as I am available online.

Additionally, I opted to utilize a dictionary instead of a list to store stages, as this allows me to introduce options to stages in a random sequence. For instance, if I need to create stage 8 before stage 7, I can easily achieve that using this approach.

I have included comments within the script to provide context on the issue and its output. Your insights and guidance wou your text ld be invaluable in resolving this problem. Thank you. '''

Leo
  • 3
  • 3

1 Answers1

0

The default value for parameter optionList in the init function of Stage seems to be always used. Instead of using empty list [] as a default parameter, consider using None, i.e.:

class Stage:
    def __init__(self, stageNo, optionList=None, stageName='stage'):
        self.stageNo = stageNo
        self.optionList = optionList if optionList is not None else []
        self.stageName = stageName

Python creates default parameters at parse/compile time, so if one of your default parameters is a mutable object (list, set, dict etc.), it could be edited from different places, consider this function:

def add_and_print_size(x, arr=[]):
   arr.append(x)
   print(len(arr))

add_and_print_size(True)  # prints 1
add_and_print_size(True)  # prints 2
add_and_print_size(True)  # prints 3
balgot
  • 31
  • 3