じろきちノート
ホームプロフィールお問い合わせ
全体の進捗率を計算する
プログラミング
全体の進捗率を計算する
oiekjr
oiekjr
2024年08月16日

やりたいこと

あるアプリケーションの実装中に、全体の進捗率を ”いい感じに” 計算したいと思いました。
以下に紹介する関数では、ステータスごとに重み付けすることで進捗率の計算を実現しています。

# Python 3.9 ~

import logging

logger = logging.getLogger(__name__)


def calculate_weighted_progress(status_counts: list[int], decimal_places: int = 2) -> float:
    """
    ステータスごとのカウントに基づいて重み付き進捗率を計算する
    :param status_counts: ステータスごとのカウントのリスト
    :param decimal_places: 進捗率の小数点以下の桁数
    :return: 重み付き進捗率(パーセンテージ)
    :raises ValueError: status_countsの要素数が1個以下の場合
    """
    if len(status_counts) <= 1:
        raise ValueError("status_countsには2つ以上の要素が必要です。")

    # ステータスに応じて重みを動的に設定
    status_count = len(status_counts)
    status_weights = [i / (status_count - 1) for i in range(status_count)]
    logger.debug(f"Status weights: {status_weights}")

    # 重み付き進捗度を計算
    weighted_progress = sum(count * weight for count, weight in zip(status_counts, status_weights))
    logger.debug(f"Weighted progress: {weighted_progress}")

    # status_countsの総数を使用して全体の進捗率を計算
    total_items = sum(status_counts)
    logger.debug(f"Total items: {total_items}")

    progress_percentage = (weighted_progress / total_items) * 100
    logger.debug(f"Progress percentage (before rounding): {progress_percentage}%")

    # 指定された小数点以下の桁数に丸める
    progress_percentage = round(progress_percentage, decimal_places)
    logger.debug(f"Progress percentage (after rounding): {progress_percentage}%")

    if progress_percentage.is_integer():
        return int(progress_percentage)

    return progress_percentage

例として、タスク総数が30件で、未完了が5件、作業中が10件、完了が15件である場合・・・

calculate_weighted_progress([5, 10, 15])

全体の進捗率は 66.67% となります。

もちろん全てのタスクが完了している場合の進捗率は 100% になります。

calculate_weighted_progress([0, 0, 30])

この関数を使う場合の注意点として、最後の要素は「完了」を表すステータスである 必要があります。


© 2022 oiekjr

(o゚ω゚o)

クイックリンク

プライバシーポリシープロフィールお問い合わせ

ソーシャルメディア