← Return to the example · Supporting files

Portfolio lifecycle statemachine-Copy1

Saved notebook · 8 cells. Code and outputs below are retained from the original; nothing was executed for this reading copy. Environment dependencies, missing data and the model limitations remain as described in the linked guide.

Cell 1 · code

import matplotlib
import matplotlib.pyplot as plt
import numpy as np
import random
import weakref

Cell 2 · code

class Projects:
    
    _instances=set()
    
    def __init__(self,number,name,state,reward):
        self.number=number
        self.name=name
        self.state=state
        self.reward=reward
        self._instances.add(weakref.ref(self))
        
    @classmethod
    def getinstances(cls):
        for i in cls._instances:
            yield i()

Cell 3 · code

p1=Projects(1,'DT','Proposal',0)
p2=Projects(2,'Covid_plan','Business_Case',0)
# https://www.codegrepper.com/code-examples/python/how+to+get+a+list+of+all+instances+of+a+class+in+python

Cell 4 · code

# W and S': Reward and State transition
def step(state,action):
    
    if action == 'promote':
        if state == 'Proposal':
            return 'Business_Case', -2
        if state == 'Business_Case':
            return 'Project_planned', -5
        if state == 'Project_planned':
            return 'Project_started', -2
        if state == 'Project_started':
            return 'Project_complete',50
        
    if state == 'Project_cancelled':
        return 'Project_cancelled',0
    
    if state == 'Project_complete':
        return 'Project_complete', 0

    if action == 'maintain':
        if state == 'Proposal':
            return "Proposal", -2
        if state == 'Business_Case':
            return 'Business_Case', -2
        if state == 'Project_planned':
            return 'Project_planned',-2
        if state == 'Project_started':
            return 'Project_started',-15
    
    if action=='cancel':
        if state == 'Proposal':
            return 'Project_cancelled', -2
        if state == 'Business_Case':
            return 'Project_cancelled',-5
        if state == 'Project_planned':
            return 'Project_cancelled', -10
        if state == 'Project_started':
            return 'Project_cancelled',-20

Cell 5 · code

# x Decision selection
Action_options=['cancel','maintain','promote']

Cell 6 · code

#Simulation of multiple trials
success=0
#for trial in range (1,2):
    
for p in Projects.getinstances():
    
    #state 0 decision
    state=p.state
    total_rewards=0
    
    for s in range(0,5):
        # state s action
        action=Action_options[random.randint(0,2)]

        # state s+1
        next_step=step(state,action)
        next_state, this_reward = next_step
        print ('project ',p.number, 'step ', s,next_step)
        
        #update project
        p.state=next_state
        p.reward+=this_reward
        
        if next_state=='Project_complete':
            success+=1
            break
Saved output
project  1 step  0 ('Business_Case', -2)
project  1 step  1 ('Business_Case', -2)
project  1 step  2 ('Project_cancelled', -2)
project  1 step  3 ('Proposal', -2)
project  1 step  4 ('Project_cancelled', -2)
project  2 step  0 ('Business_Case', -2)
project  2 step  1 ('Project_cancelled', -5)
project  2 step  2 ('Business_Case', -2)
project  2 step  3 ('Project_cancelled', -5)
project  2 step  4 ('Project_planned', -5)

Cell 7 · code

#Washup
for p in Projects.getinstances():
    print (p.name, p.state, p.reward )
Saved output
DT Project_cancelled -10
Covid_plan Project_planned -19

Cell 8 · code