M7) Payback period calculation for warehouse design projects

You are comparing seven warehouse projects that require an investment in Material Handling Equipment (MHE). For this exercise, the company accepts a project when its payback period is at most 3.0 years, including exactly 3.0 years.

The payback period is calculated by dividing the initial investment by the annual profit generated by the equipment:

\[ \text{Payback period} = \frac{\text{Initial investment}}{\text{Annual profit}} \]

This period represents the time it takes (in years) for the project to recover the initial investment through the annual profits generated.

The supplied Python function payback_years(investment, profit) in Listing 1 takes an initial investment and annual profit in the same currency and returns the payback period in years. Both amounts are positive. For example, payback_years(50_000, 20_000) returns 2.5.

Listing 1: Python function payback_years to compute the payback period for MHE projects based on the initial investment and annual profit.
def payback_years(investment, profit):
    return investment / profit

The supplied function is_viable_project(years, limit_years) in Listing 2 takes two numbers measured in years:

  1. years: the calculated payback period for one project.
  2. limit_years: the company’s maximum acceptable payback period.

It returns the Boolean value True when the project meets this payback criterion, and False otherwise. Both inputs are nonnegative.

Listing 2: Supplied function that checks whether a payback period meets a specified limit.
def is_viable_project(years, limit_years):
    return years <= limit_years

For example, with a limit of 4.0 years, is_viable_project(2.5, 4.0) returns True, is_viable_project(4.0, 4.0) returns True, and is_viable_project(4.5, 4.0) returns False. The function checks the supplied limit; it does not calculate the payback period.

Table 1 gives the investment and annual profit for each project.

Table 1: Initial investment and annual profit for various MHE projects.
Project name Initial investment Annual profit
Automated Guided Vehicles (AGVs) 500,000 150,000
Forklift Fleet Upgrade 300,000 100,000
Automated Storage and Retrieval System (AS/RS) 1,200,000 400,000
Conveyor System Installation 400,000 120,000
Pallet Shuttle System 700,000 200,000
Voice Picking System 150,000 50,000
Robotic Palletizers 800,000 250,000

The same input is stored as a list of dictionary records in Listing 3. Each record uses the fields name, initial_investment, and annual_profit.

Listing 3: Input records for the seven warehouse projects.
projects = [
    {
        "name": "Automated Guided Vehicles (AGVs)",
        "initial_investment": 500_000,
        "annual_profit": 150_000,
    },
    {
        "name": "Forklift Fleet Upgrade",
        "initial_investment": 300_000,
        "annual_profit": 100_000,
    },
    {
        "name": (
            "Automated Storage and Retrieval "
            "System (AS/RS)"
        ),
        "initial_investment": 1_200_000,
        "annual_profit": 400_000,
    },
    {
        "name": "Conveyor System Installation",
        "initial_investment": 400_000,
        "annual_profit": 120_000,
    },
    {
        "name": "Pallet Shuttle System",
        "initial_investment": 700_000,
        "annual_profit": 200_000,
    },
    {
        "name": "Voice Picking System",
        "initial_investment": 150_000,
        "annual_profit": 50_000,
    },
    {
        "name": "Robotic Palletizers",
        "initial_investment": 800_000,
        "annual_profit": 250_000,
    },
]

Use the fixed setting in Listing 4 for every project. Both supplied functions are available to all four implementations.

Listing 4: Maximum acceptable payback period for every project, in years.
limit_years = 3.0

Compare the four implementations in Listing 5. Each starts with an empty results list. Append one dictionary per project with these fields:

  • name: the project’s name.
  • payback_period: its calculated payback period in years.
  • viable: the Boolean result returned by is_viable_project.
Listing 5: Alternatives for calculating the payback period and viability of every project (Question 1).
(a) Implementation 1.
results = []

for project in projects:
    years = payback_years(
        project[
            "initial_investment"
        ],
        project["annual_profit"],
    )
    viable = is_viable_project(
        years,
        project["annual_profit"],
    )
    results.append({
        "name": project["name"],
        "payback_period": years,
        "viable": viable,
    })
(b) Implementation 2.
results = []

for project in projects:
    years = payback_years(
        project[
            "initial_investment"
        ]
    )
    viable = is_viable_project(
        years,
        limit_years,
    )
    results.append({
        "name": project["name"],
        "payback_period": years,
        "viable": viable,
    })
(c) Implementation 3.
results = []

for project in projects:
    years = payback_years(
        project[
            "initial_investment"
        ],
        project["annual_profit"],
    )
    viable = is_viable_project(
        years,
        limit_years,
    )
    results.append({
        "name": project["name"],
        "payback_period": years,
        "viable": viable,
    })
(d) Implementation 4.
results = []

for project in projects:
    years = payback_years(
        projects[0][
            "initial_investment"
        ],
        projects[0][
            "annual_profit"
        ],
    )
    viable = is_viable_project(
        years,
        limit_years,
    )
    results.append({
        "name": project["name"],
        "payback_period": years,
        "viable": viable,
    })

Which implementation correctly processes every project using the fixed limit_years and appends its result to results?

results.append(record) adds one complete record at the list’s end and returns None. Starting with results = [], results.append({"name": "AGVs"}) leaves results as [{"name": "AGVs"}].