Skip to content

Commit

Permalink
Add to_dict() and from_dict() to SupplyChainNetwork (part of #14)
Browse files Browse the repository at this point in the history
  • Loading branch information
LarrySnyder committed Jun 29, 2022
1 parent 391d05c commit edc0e8e
Show file tree
Hide file tree
Showing 2 changed files with 142 additions and 2 deletions.
46 changes: 44 additions & 2 deletions src/stockpyl/supply_chain_network.py
Original file line number Diff line number Diff line change
Expand Up @@ -266,9 +266,51 @@ def to_dict(self):
for n in self.nodes:
network_dict['nodes'].append(n.to_dict())

# TODO: need to replicate network structure

return network_dict

@classmethod
def from_dict(cls, the_dict):
"""Return a new |class_network| object with attributes copied from the
values in ``the_dict``.
Parameters
----------
the_dict : dict
Dict representation of a |class_network|, typically created using ``to_dict()``.
Returns
-------
SupplyChainNetwork
The object converted from the dict.
"""
if the_dict is None:
network = None
else:
# Initialize node object.
network = SupplyChainNetwork()

# Non-object attributes.
network.period = the_dict['period']
network.max_max_replenishment_time = the_dict['max_max_replenishment_time']

# Nodes.
for n_dict in the_dict['nodes']:
network.nodes.append(SupplyChainNode.from_dict(n_dict))

# Convert nodes' successors and predecessors back to node objects. (SupplyChainNode.to_dict()
# replaces them with indices.)
for n in network.nodes:
preds = []
succs = []
for m in network.nodes:
if m.index in n.predecessors():
preds.append(m)
if m.index in n.successors():
succs.append(m)
n._predecessors = preds
n._successors = succs

return network

# Methods for node handling.

Expand Down
98 changes: 98 additions & 0 deletions tests/test_supply_chain_network.py
Original file line number Diff line number Diff line change
Expand Up @@ -1707,3 +1707,101 @@ def test_example_6_1_renumbered(self):
S_echelon = {3: 10, 2: 15, 1: 5}
S_local = echelon_to_local_base_stock_levels(instance, S_echelon)
self.assertDictEqual(S_local, {3: 5, 2: 0, 1: 0})


class TestToFromDict(unittest.TestCase):
@classmethod
def set_up_class(cls):
"""Called once, before any tests."""
print_status('TestToFromDict', 'set_up_class()')

@classmethod
def tear_down_class(cls):
"""Called once, after all tests, if set_up_class successful."""
print_status('TestToFromDict', 'tear_down_class()')

def test_example_6_1(self):
"""Test that to_dict() and from_dict() correctly convert SupplyChainNetwork object to and from dict
in Example 6.1.
"""
print_status('TestToFromDict', 'test_example_6_1()')

network = load_instance("example_6_1")

# Convert network to dict.
network_dict = network.to_dict()

# Convert dict back to network.
dict_network = SupplyChainNetwork.from_dict(network_dict)

# Compare.
self.assertTrue(network.deep_equal_to(dict_network))

def test_assembly_3_stage(self):
"""Test that to_dict() and from_dict() correctly convert SupplyChainNetwork object to and from dict
in 3-stage assembly system.
"""
print_status('TestToFromDict', 'test_assembly_3_stage()')

network = load_instance("assembly_3_stage")

# Convert network to dict.
network_dict = network.to_dict()

# Convert dict back to network.
dict_network = SupplyChainNetwork.from_dict(network_dict)

# Compare.
self.assertTrue(network.deep_equal_to(dict_network))

def test_example_6_1_per_22(self):
"""Test that to_dict() and from_dict() correctly convert SupplyChainNetwork object to and from dict
in Example 6.1 per 22.
"""
print_status('TestToFromDict', 'test_example_6_1_per_22()')

network = load_instance("example_6_1")

# Set initial inventory levels to local BS levels.
for n in network.nodes:
n.initial_inventory_level = n.inventory_policy.base_stock_level

# Strategy for these tests: run sim for a few periods, convert nodes
# to dict and back, compare to original.
simulation(network, 23, rand_seed=17, progress_bar=False)

# Convert network to dict.
network_dict = network.to_dict()

# Convert dict back to network.
dict_network = SupplyChainNetwork.from_dict(network_dict)

# Compare.
self.assertTrue(network.deep_equal_to(dict_network))

def test_assembly_3_stage_per_22(self):
"""Test that to_dict() and from_dict() correctly convert SupplyChainNetwork object to and from dict
in 3-stage assembly system.
"""
print_status('TestToFromDict', 'test_assembly_3_stage_per_22()')

network = load_instance("assembly_3_stage")

# Set initial inventory levels to local BS levels.
for n in network.nodes:
n.initial_inventory_level = n.inventory_policy.base_stock_level

# Strategy for these tests: run sim for a few periods, convert nodes
# to dict and back, compare to original.
simulation(network, 23, rand_seed=17, progress_bar=False)

# Convert network to dict.
network_dict = network.to_dict()

# Convert dict back to network.
dict_network = SupplyChainNetwork.from_dict(network_dict)

# Compare.
self.assertTrue(network.deep_equal_to(dict_network))


0 comments on commit edc0e8e

Please sign in to comment.