Examples

These examples generate diagrams to be displayed from a Python console or Jupyter Notebook. After importing pyml, model elements can be specified as simple lists. Element relationships are designated as lists of tuple pairs. The output filenames are optional and used here to generate the included SVG images.

Use Case Model

Actors and use cases are first specified in lists. The interactions between actors and use cases are identified by their tuple pairs and drawn accordingly on the diagram.

import pyml

# system model
system_name = "Course Portal"
actors = ['Student', 'Instructor']
use_cases = ['Post Discussion', 'Take Quiz', 'Create Quiz']
interactions = [('Student', 'Post Discussion'), ('Instructor', 'Post Discussion'), ('Student', 'Take Quiz'), ('Instructor', 'Create Quiz')]
use_case_relationships = []

# create diagram
pyml.use_case_diagram(system_name, actors, use_cases, interactions, use_case_relationships, filename=system_name+'use case diagram.pdf')

Sequence Model

A sequence diagram can be constructed per the following.

# system model
system_name = "Battle Simulator"
actors = ['Battle Planner']
objects = ['main']
actions = [
('Battle Planner', 'main', 'run()'),
('main', 'Battle Planner', 'request for side 1 name'),
('Battle Planner', 'main', 'side 1 name'),
('main', 'Battle Planner', 'request for side 2 name'),
('Battle Planner', 'main', 'side 2 name'),
('main', 'Battle Planner', 'request for side 1 starting level'),
('Battle Planner', 'main', 'side 1 starting level'),
('main', 'Battle Planner', 'request for side 1 lethality coefficient'),
('Battle Planner', 'main', 'side 1 lethality coefficient'),
('main', 'Battle Planner', 'request for side 2 starting level'),
('Battle Planner', 'main', 'side 2 starting level'),
('main', 'Battle Planner', 'request for side 2 lethality coefficient'),
('Battle Planner', 'main', 'side 2 lethality coefficient'),
('main', 'Battle Planner', 'time history of troops and victor'),
]

# create diagram
pyml.sequence_diagram(system_name, actors, objects, actions, filename=system_name+"_sequence_diagram")

Context Model

# system model
system_name = "Python Interpreter with PyML"
external_actors = ["User", "OS", "Graphviz"]
# create context diagram
pyml.context_diagram(system_name, external_actors, filename="pyml_context_diagram_offline")

Work Breakdown Structure

# project work breakdown structure
wbs_decompositions = [
('Skateboard', 'Hardware'), ('Skateboard', 'Software'), ('Skateboard', 'Integration and Test'),
                ('Hardware', 'Board'), ('Hardware', 'Wheels'), ('Hardware', 'Mounting'),
                ('Software', 'OS'), ('Software', 'GPS Driver'), ('Software', 'Route Tracking'),
                ('Integration and Test', 'Fixed Platform'), ('Integration and Test', 'Street Testing')]

# create diagram
pyml.wbs_diagram(wbs_decompositions, filename="skateboard_wbs")

Critical Path Analysis

A critical path can be computed from a set of tasks with associated time durations and dependencies as below.

# tasks, durations and dependencies
tasks = [('A', {'Duration': 3}),
         ('B', {'Duration': 5}),
         ('C', {'Duration': 2}),
         ('D', {'Duration': 3}),
         ('E', {'Duration': 5})]

task_dependencies = [('A', 'C'),
                ('B', 'C'),
                ('A', 'D'),
                ('C', 'E'),
                ('D', 'E')]

# create diagram
pyml.critical_path_diagram(tasks, task_dependencies, filename="critical_path")

Design Structure Matrix

tasks = ['Make Board', 'Acquire Wheels', 'Assemble', 'Test']
task_dependencies = [('Make Board', 'Assemble'), ('Acquire Wheels', 'Assemble'), ('Assemble', 'Test'), ('Test', 'Assemble')]
pyml.design_structure_matrix(tasks, task_dependencies, filename="skateboard_task_dsm_with_feedback")
dsm dsm Make Board Acquire Wheels Assemble Test Make Board Acquire Wheels Assemble X X X Test X

Requirements Diagram

# Intelligence, Surveillance, & Reconnaissance Unmanned Underwater Vehicle (ISR UUV) un-numbered requirements
requirements = [("ISR UUV", "Performance"),
                ("Performance", 
                ("The UUV shall be capable of completing a mission of 6 hours duration.", 
                "The UUV shall be capable of a top speed of 14 knots.", 
                "The UUV shall be capable of surviving in an open ocean environment to a depth of 1500 meters.", 
                "The UUV shall avoid detection.")),
                ("ISR UUV", "Communication"),
                ("Communication", 
                ("Mission parameters shall be uploadable to the UUV",
                "The UUV shall receive remote commands",
                "The UUV shall commence its mission when commanded",
                "The UUV shall be capable of transmitting data in a host ship compatible format",
                "The UUV shall indicate that it is ready for recovery")),]

# draw requirements diagram as horizontal tree left -> right
requirements_diagram(requirements, rankdir='LR', filename="uuv_requirements_tree")

Fault Tree

lamp_circuit_fault_tree = [("Missing Indication", "and", ["Resistor Fails", "Capacitor Fails", "Both Lamps Out"]),
           ('Both Lamps Out', 'or', ['Lamp 1 Fails', 'Lamp 2 Fails', 'Lamp 3 Fails']),
           ('Resistor Fails', 'basic', []),
           ('Capacitor Fails', 'basic', []),
           ('Lamp 1 Fails', 'BASIC', []),
           ('Lamp 2 Fails', 'basic', []),
           ('Lamp 3 Fails', 'basic', []),
                          ]

pyml.fault_tree_diagram(lamp_circuit_fault_tree, filename="lamp_circuit_fault_tree")

Read Fault Tree from Excel

Portion of example Excel file aav_fault_tree.xlsx:

aav_fault_tree_excel.png

# read fault tree from Excel file into list of nodes
fault_tree_list = pyml.read_fault_tree_excel('aav_fault_tree.xlsx')

# create fault tree diagram
pyml.fault_tree_diagram(fault_tree_list)

aav_fault_tree.png

Causal Diagram

# causal relationships
relationships = [('Available personnel',"Workforce gap", "-"),
    ('Required personnel',"Workforce gap", "+"),
    ("Workforce gap", "Hiring rate", "+"),
    ("Hiring rate", "Available personnel", "+"),
                ]

# draw diagram
causal_diagram(relationships)

System Dynamics Model

# Rayleigh curve staffing model

model_init(start=0, stop=6, dt=.2)

add_stock("cumulative_effort", 0, inflows=["effort rate"])
add_flow("effort rate", "learning_function * (estimated_total_effort - cumulative_effort)")
add_auxiliary("learning_function", "manpower_buildup_parameter * time")
add_auxiliary("manpower_buildup_parameter", .5)
add_auxiliary("estimated_total_effort", 15)

model_run()
plot_output('cumulative_effort', 'effort rate', "learning_function")