Skip to content

Commit

Permalink
statistics visualize : --task_completion_cireteria引数でタスクの完了条件を指定で…
Browse files Browse the repository at this point in the history
…きるようにしました (#1296)

* 最初に受入フェーズに到達した日時を記載する

* update

* 教師付開始日の基準を完了日にする

* 完了条件を記載

* merge

* fix\

* update doc

* document 修正

* task_compeltion_criteria を追加

* グラフを生成

* modify test data

* テストデータの修正
  • Loading branch information
yuji38kwmt authored Nov 11, 2024
1 parent aa545e0 commit 0cfce5d
Show file tree
Hide file tree
Showing 28 changed files with 375 additions and 135 deletions.
15 changes: 14 additions & 1 deletion annofabcli/stat_visualization/mask_visualization_dir.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
from annofabcli.statistics.visualization.dataframe.task_worktime_by_phase_user import TaskWorktimeByPhaseUser
from annofabcli.statistics.visualization.dataframe.user_performance import UserPerformance
from annofabcli.statistics.visualization.dataframe.worktime_per_date import WorktimePerDate
from annofabcli.statistics.visualization.model import ProductionVolumeColumn
from annofabcli.statistics.visualization.model import ProductionVolumeColumn, TaskCompletionCriteria
from annofabcli.statistics.visualization.project_dir import ProjectDir

logger = logging.getLogger(__name__)
Expand Down Expand Up @@ -223,12 +223,15 @@ def main(args: argparse.Namespace) -> None:
create_custom_production_volume_list(args.custom_production_volume) if args.custom_production_volume is not None else None
)

task_completion_criteria = TaskCompletionCriteria(args.task_completion_criteria)
input_project_dir = ProjectDir(
args.dir,
task_completion_criteria,
custom_production_volume_list=custom_production_volume_list,
)
output_project_dir = ProjectDir(
args.output_dir,
task_completion_criteria,
metadata=input_project_dir.read_metadata(),
)
mask_visualization_dir(
Expand Down Expand Up @@ -271,6 +274,16 @@ def parse_args(parser: argparse.ArgumentParser) -> None:
"column_list": [{"value": "video_duration_minute", "name": "動画長さ"}],
}

parser.add_argument(
"--task_completion_criteria",
type=str,
choices=[e.value for e in TaskCompletionCriteria],
default=TaskCompletionCriteria.ACCEPTANCE_COMPLETED.value,
help="タスクの完了条件を指定します。\n"
"* ``acceptance_completed``: タスクが受入フェーズの完了状態であれば「タスクの完了」とみなす\n"
"* ``acceptance_reached``: タスクが受入フェーズに到達したら「タスクの完了」とみなす\n",
)

parser.add_argument(
"--custom_production_volume",
type=str,
Expand Down
38 changes: 28 additions & 10 deletions annofabcli/stat_visualization/merge_visualization_dir.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
WholeProductivityPerFirstAnnotationStartedDate,
)
from annofabcli.statistics.visualization.dataframe.worktime_per_date import WorktimePerDate
from annofabcli.statistics.visualization.model import ProductionVolumeColumn
from annofabcli.statistics.visualization.model import ProductionVolumeColumn, TaskCompletionCriteria
from annofabcli.statistics.visualization.project_dir import MergingInfo, ProjectDir

logger = logging.getLogger(__name__)
Expand All @@ -45,11 +45,13 @@ class WritingVisualizationFile:
def __init__(
self,
output_project_dir: ProjectDir,
task_completion_criteria: TaskCompletionCriteria,
*,
user_id_list: Optional[List[str]] = None,
minimal_output: bool = False,
) -> None:
self.output_project_dir = output_project_dir
self.task_completion_criteria = task_completion_criteria
self.user_id_list = user_id_list
self.minimal_output = minimal_output

Expand Down Expand Up @@ -126,13 +128,13 @@ def write_task_worktime_by_phase_user(self, task_worktime_by_phase_user: TaskWor

@_catch_exception
def write_performance_per_first_annotation_started_date(self, task: Task) -> None:
obj = WholeProductivityPerFirstAnnotationStartedDate.from_task(task)
obj = WholeProductivityPerFirstAnnotationStartedDate.from_task(task, self.task_completion_criteria)
self.output_project_dir.write_whole_productivity_per_first_annotation_started_date(obj)
self.output_project_dir.write_whole_productivity_line_graph_per_annotation_started_date(obj)

@_catch_exception
def write_merge_performance_per_date(self, task: Task, worktime_per_date: WorktimePerDate) -> None:
obj = WholeProductivityPerCompletedDate.from_df_wrapper(task, worktime_per_date)
obj = WholeProductivityPerCompletedDate.from_df_wrapper(task, worktime_per_date, task_completion_criteria=self.task_completion_criteria)
self.output_project_dir.write_whole_productivity_per_date(obj)
self.output_project_dir.write_whole_productivity_line_graph_per_date(obj)

Expand Down Expand Up @@ -176,7 +178,7 @@ def merge_task_worktime_by_phase_user(self) -> TaskWorktimeByPhaseUser:
merged_obj = TaskWorktimeByPhaseUser.merge(*tmp_list, custom_production_volume_list=self.custom_production_volume_list)
return merged_obj

def create_merging_info(self) -> MergingInfo:
def create_merging_info(self, task_completion_criteria: TaskCompletionCriteria) -> MergingInfo:
"""
`project_info.json`の内容から、どのようにマージしたかを示す情報を作成する。
"""
Expand All @@ -186,12 +188,15 @@ def create_merging_info(self) -> MergingInfo:
project_info = project_dir.read_project_info()
project_info_list.append(project_info)

merge_info = MergingInfo(target_dir_list=target_dir_list, project_info_list=project_info_list)
merge_info = MergingInfo(
target_dir_list=target_dir_list, project_info_list=project_info_list, task_completion_criteria=task_completion_criteria
)
return merge_info


def merge_visualization_dir( # pylint: disable=too-many-statements
project_dir_list: List[ProjectDir],
task_completion_criteria: TaskCompletionCriteria,
output_project_dir: ProjectDir,
*,
custom_production_volume_list: Optional[list[ProductionVolumeColumn]] = None,
Expand All @@ -200,7 +205,7 @@ def merge_visualization_dir( # pylint: disable=too-many-statements
) -> None:
merging_obj = MergingVisualizationFile(project_dir_list, custom_production_volume_list=custom_production_volume_list)

merging_info = merging_obj.create_merging_info()
merging_info = merging_obj.create_merging_info(task_completion_criteria)
output_project_dir.metadata = merging_info.to_dict(encode_json=True)

# 基本となるCSVファイルを読み込みマージする
Expand All @@ -210,7 +215,9 @@ def merge_visualization_dir( # pylint: disable=too-many-statements

user_performance = UserPerformance.from_df_wrapper(task_worktime_by_phase_user=task_worktime_by_phase_user, worktime_per_date=worktime_per_date)
whole_performance = WholePerformance.from_df_wrapper(task_worktime_by_phase_user=task_worktime_by_phase_user, worktime_per_date=worktime_per_date)
writing_obj = WritingVisualizationFile(output_project_dir, user_id_list=user_id_list, minimal_output=minimal_output)
writing_obj = WritingVisualizationFile(
output_project_dir, user_id_list=user_id_list, minimal_output=minimal_output, task_completion_criteria=task_completion_criteria
)

writing_obj.write_task_list_and_histogram(task)
writing_obj.write_worktime_per_date(worktime_per_date)
Expand Down Expand Up @@ -258,20 +265,31 @@ def main(args: argparse.Namespace) -> None:
custom_production_volume_list = (
create_custom_production_volume_list(args.custom_production_volume) if args.custom_production_volume is not None else None
)

task_completion_criteria = TaskCompletionCriteria(args.task_completion_criteria)
merge_visualization_dir(
project_dir_list=[ProjectDir(e) for e in args.dir],
project_dir_list=[ProjectDir(e, task_completion_criteria) for e in args.dir],
task_completion_criteria=task_completion_criteria,
user_id_list=user_id_list,
custom_production_volume_list=custom_production_volume_list,
minimal_output=args.minimal,
output_project_dir=ProjectDir(args.output_dir),
output_project_dir=ProjectDir(args.output_dir, task_completion_criteria),
)


def parse_args(parser: argparse.ArgumentParser) -> None:
parser.add_argument("--dir", type=Path, nargs="+", required=True, help="マージ対象ディレクトリ。2つ以上指定してください。")
parser.add_argument("-o", "--output_dir", type=Path, required=True, help="出力先ディレクトリ。配下にプロジェクト名のディレクトリが出力される。")

parser.add_argument(
"--task_completion_criteria",
type=str,
choices=[e.value for e in TaskCompletionCriteria],
default=TaskCompletionCriteria.ACCEPTANCE_COMPLETED.value,
help="タスクの完了条件を指定します。\n"
"* ``acceptance_completed``: タスクが受入フェーズの完了状態であれば「タスクの完了」とみなす\n"
"* ``acceptance_reached``: タスクが受入フェーズに到達したら「タスクの完了」とみなす\n",
)

parser.add_argument(
"-u",
"--user_id",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
get_json_from_args,
)
from annofabcli.statistics.visualization.dataframe.project_performance import ProjectPerformance
from annofabcli.statistics.visualization.model import ProductionVolumeColumn
from annofabcli.statistics.visualization.model import ProductionVolumeColumn, TaskCompletionCriteria
from annofabcli.statistics.visualization.project_dir import ProjectDir

logger = logging.getLogger(__name__)
Expand All @@ -31,7 +31,10 @@ def create_custom_production_volume_list(cli_value: str) -> list[ProductionVolum

def main(args: argparse.Namespace) -> None:
root_dir: Path = args.dir
project_dir_list = [ProjectDir(elm) for elm in root_dir.iterdir() if elm.is_dir()]
# task_completion_criteriaは何でもよいので、とりあえずACCEPTANCE_COMPLETEDを指定
project_dir_list = [
ProjectDir(elm, task_completion_criteria=TaskCompletionCriteria.ACCEPTANCE_COMPLETED) for elm in root_dir.iterdir() if elm.is_dir()
]

custom_production_volume_list = (
create_custom_production_volume_list(args.custom_production_volume) if args.custom_production_volume is not None else None
Expand Down
17 changes: 14 additions & 3 deletions annofabcli/stat_visualization/write_graph.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
InspectorProductivityPerDate,
)
from annofabcli.statistics.visualization.dataframe.task import Task
from annofabcli.statistics.visualization.model import ProductionVolumeColumn
from annofabcli.statistics.visualization.model import ProductionVolumeColumn, TaskCompletionCriteria
from annofabcli.statistics.visualization.project_dir import ProjectDir

logger = logging.getLogger(__name__)
Expand Down Expand Up @@ -129,8 +129,9 @@ def main(args: argparse.Namespace) -> None:
create_custom_production_volume_list(args.custom_production_volume) if args.custom_production_volume is not None else None
)

input_project_dir = ProjectDir(args.dir, custom_production_volume_list=custom_production_volume_list)
output_project_dir = ProjectDir(args.output_dir, metadata=input_project_dir.read_metadata())
task_completion_criteria = TaskCompletionCriteria(args.task_completion_criteria)
input_project_dir = ProjectDir(args.dir, task_completion_criteria, custom_production_volume_list=custom_production_volume_list)
output_project_dir = ProjectDir(args.output_dir, task_completion_criteria, metadata=input_project_dir.read_metadata())
main_obj = WritingGraph(
project_dir=input_project_dir,
output_project_dir=output_project_dir,
Expand Down Expand Up @@ -164,6 +165,16 @@ def parse_args(parser: argparse.ArgumentParser) -> None:
help="必要最小限のファイルを出力します。",
)

parser.add_argument(
"--task_completion_criteria",
type=str,
choices=[e.value for e in TaskCompletionCriteria],
default=TaskCompletionCriteria.ACCEPTANCE_COMPLETED.value,
help="タスクの完了条件を指定します。\n"
"* ``acceptance_completed``: タスクが受入フェーズの完了状態であれば「タスクの完了」とみなす\n"
"* ``acceptance_reached``: タスクが受入フェーズに到達したら「タスクの完了」とみなす\n",
)

custom_production_volume_sample = {
"column_list": [{"value": "video_duration_minute", "name": "動画長さ"}],
}
Expand Down
11 changes: 8 additions & 3 deletions annofabcli/stat_visualization/write_performance_rating_csv.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
ProjectPerformance,
ProjectWorktimePerMonth,
)
from annofabcli.statistics.visualization.model import ProductionVolumeColumn, WorktimeColumn
from annofabcli.statistics.visualization.model import ProductionVolumeColumn, TaskCompletionCriteria, WorktimeColumn
from annofabcli.statistics.visualization.project_dir import ProjectDir

logger = logging.getLogger(__name__)
Expand Down Expand Up @@ -326,7 +326,11 @@ def create_rating_df(
custom_production_volume_list_by_directory.get(p_project_dir.name) if custom_production_volume_list_by_directory is not None else None
)
project_title = p_project_dir.name
project_dir = ProjectDir(p_project_dir, custom_production_volume_list=custom_production_volume_list)
project_dir = ProjectDir(
p_project_dir,
task_completion_criteria=TaskCompletionCriteria.ACCEPTANCE_COMPLETED,
custom_production_volume_list=custom_production_volume_list,
)
project_dir_list.append(project_dir)

try:
Expand Down Expand Up @@ -471,7 +475,8 @@ def create_user_df(target_dir: Path) -> pandas.DataFrame:
if not p_project_dir.is_dir():
continue

project_dir = ProjectDir(p_project_dir)
# task_completion_criteriaは何でもよいので、とりあえずACCEPTANCE_COMPLETEDを指定
project_dir = ProjectDir(p_project_dir, task_completion_criteria=TaskCompletionCriteria.ACCEPTANCE_COMPLETED)

try:
user_performance = project_dir.read_user_performance()
Expand Down
4 changes: 3 additions & 1 deletion annofabcli/statistics/visualization/dataframe/task.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,8 @@ def columns(self) -> list[str]:
"first_acceptance_username",
"first_acceptance_worktime_hour",
"first_acceptance_started_datetime",
# 最後の受入
# 受入フェーズの日時
"first_acceptance_reached_datetime",
"first_acceptance_completed_datetime",
# 作業時間に関する内容
"worktime_hour",
Expand Down Expand Up @@ -229,6 +230,7 @@ def empty(cls, *, custom_production_volume_list: Optional[list[ProductionVolumeC
"first_acceptance_user_id",
"first_acceptance_username",
"first_acceptance_started_datetime",
"first_acceptance_reached_datetime",
"first_acceptance_completed_datetime",
]

Expand Down
Loading

0 comments on commit 0cfce5d

Please sign in to comment.