From 1d76529c51675b2069e1092371140136b2db040e Mon Sep 17 00:00:00 2001 From: RomanKurlygin Date: Thu, 28 May 2026 11:25:03 +0300 Subject: [PATCH] fix: add runnable project files for ai-fluency task Add a minimal Python CLI implementation with source code and dependency configuration so the repository can be validated by autograder requirements. Co-authored-by: Cursor --- README.md | 22 ++++++++ main.py | 7 +++ pyproject.toml | 14 +++++ requirements.txt | 2 + src/fluency_tracker/__init__.py | 2 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 232 bytes .../__pycache__/cli.cpython-310.pyc | Bin 0 -> 1144 bytes .../__pycache__/tracker.cpython-310.pyc | Bin 0 -> 2004 bytes src/fluency_tracker/cli.py | 31 +++++++++++ src/fluency_tracker/tracker.py | 49 ++++++++++++++++++ 10 files changed, 127 insertions(+) create mode 100644 main.py create mode 100644 pyproject.toml create mode 100644 requirements.txt create mode 100644 src/fluency_tracker/__init__.py create mode 100644 src/fluency_tracker/__pycache__/__init__.cpython-310.pyc create mode 100644 src/fluency_tracker/__pycache__/cli.cpython-310.pyc create mode 100644 src/fluency_tracker/__pycache__/tracker.cpython-310.pyc create mode 100644 src/fluency_tracker/cli.py create mode 100644 src/fluency_tracker/tracker.py diff --git a/README.md b/README.md index 1f36e7b..72f5d66 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,28 @@ --- +## Project implementation + +This repository contains not only the plan text, but also a small Python project that implements a basic progress tracker for this plan. + +### Source files + +- `main.py` — CLI entrypoint. +- `src/fluency_tracker/tracker.py` — parser of markdown checklist and report builder. +- `src/fluency_tracker/cli.py` — command-line interface. +- `requirements.txt` / `pyproject.toml` — dependency and project configuration files. + +### Run locally + +```bash +python -m pip install -r requirements.txt +python main.py --plan-file README.md +``` + +The command prints current progress and pending items from checklist tasks (`- [ ]` / `- [x]`). + +--- + ## 1. Цель и контекст ### Зачем мне AI fluency diff --git a/main.py b/main.py new file mode 100644 index 0000000..8f363c8 --- /dev/null +++ b/main.py @@ -0,0 +1,7 @@ +"""CLI entrypoint for AI fluency plan tracker.""" + +from src.fluency_tracker.cli import main + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..4ea38f2 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,14 @@ +[build-system] +requires = ["setuptools>=68", "wheel"] +build-backend = "setuptools.build_meta" + +[project] +name = "ai-fluency-plan-tracker" +version = "0.1.0" +description = "Small CLI utility to track progress of AI Fluency plan." +readme = "README.md" +requires-python = ">=3.10" +dependencies = [] + +[tool.setuptools.packages.find] +where = ["src"] diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..a249f4a --- /dev/null +++ b/requirements.txt @@ -0,0 +1,2 @@ +# Runtime dependencies +# Kept intentionally minimal for the assignment project. diff --git a/src/fluency_tracker/__init__.py b/src/fluency_tracker/__init__.py new file mode 100644 index 0000000..b182dd4 --- /dev/null +++ b/src/fluency_tracker/__init__.py @@ -0,0 +1,2 @@ +"""AI Fluency tracker package.""" + diff --git a/src/fluency_tracker/__pycache__/__init__.cpython-310.pyc b/src/fluency_tracker/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3c76453bdcc5d936c30e13cc96dbc5b20bd9c9d7 GIT binary patch literal 232 zcmd1j<>g`kf(^gLvy_4KV-N=!FakLaKwQiLBvKfn7*ZI688n%yq#ZpK+;U1&^O7qS zN{SMbvr~%{3V>8%da9nECgUyk`1q9kLG)iEeIUW?oE5VsW;vnWd$#Bc25j{yCR4|a6lXFgz?|k36)zVUj;Q0P)bu#b>`C&IV2l~hhLa5$B zLz0+CDp^ho7BgyXFZW^(S3mcQAP&$M$S@C!D2|F&+`|2`Y|G9kKW@ugvL~0&>PYV$ z>95TB*3N4_u7GdilFw9`e&ls7N^U@;Qw76wi=uKv`UQ7Q{9B1%nZt(s{#(3f4B(;vqF_-&t^et@4p)Mx&Y^vt(K!< z$b{NzKhtBfAQL7%>D%f)dldIrL9{!6_U^Dc;x$wUptR-}ApToZAz&)2qmrkGDxKz; zHp4!RyHe>Cvf7q5?+ymG{J}WO)x7<7d-LU+?O`G3FKoHoRQ&o5o57DV^j_b_UCI1` zRAVvA%?7_d-yb4N(WSrf4^>|Gy{2`=Nxb|oDREConPAirg=~k8I`~Fl30e7>Y;BC* zBYAohi+MGAsr1xT^=Kcei5`dpBzI7VtQ=W9gY~CRpFA9o*X6o=B-Yj*KNgP=$P+Qr zkd7`jPcG#irFk~2KVAuX@oE>J)OYaXQ%1u-zQ=Gy>$e}kEp#_tR+@iw^ldUur{gO$ z3^^fI!Bcuhj;Ub_I`K~EFV2iKeipJxZ}`U7BzSlX4@*8*n>^z4(KLO02M%J!$A#L z2iX4W`_Qv4-yObse9B XS+1U2QnYpXq{mvUM^{+KTkib@%&sZ^ literal 0 HcmV?d00001 diff --git a/src/fluency_tracker/__pycache__/tracker.cpython-310.pyc b/src/fluency_tracker/__pycache__/tracker.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a1cf48a361c2e7247fe8f70842f1938358190c47 GIT binary patch literal 2004 zcmah~TW=Fb6rP!#U9UGzV!%Lp&9;RKtFo1fTR~9@O=zhqr74688KNFq43b2vvxv2tvaijbLPyM%lXb_qxpGOqM>E2C~ zkUw#9v~ieRBZMYBU<7FpK?MtFpEVdo-Uy67Z}6Pwf!VhjR?eG2p;3^9u`R3#Z4@OJ z1z|s>-w{z1&J!Y>$Luj}IO3#O6y+zpF(*!m6QTlKNtm}u_4IJ%rVL`K5;u+9*jI^k z{ZP0{#*s?h>)*TWU?9WRBR5u2N693qzr=S}sh;!0FiQQj8-)o>i^5O+R^TT%;ah%s ze{*=|mzvwWckb)0)xNLx*6z9ccXz7I9Tz33pX{yGzo?$s27Rloq9I&^M;~nlOs*j; z9|I#vg90?{4gewz!B&YdfO4Q{ilzBBoT-f@RoYCuX&^PJ2^|@kk(_$qWOQt%R%VO~!kEyU@(CT= z6F_{A3F|4FP)bk_@Goo*%|Y6(eFgrs!IzQfh8@ijiU!A*Yr0=$3Lm2|8LCBHRMHn- zD)&?EByj*P>xMGX<@K94)_?fs$GhIv_3iB&w>Gue_tVyWZGvmNv9|m;mZ6w}Vs=zC zh_x9+52dPdbqtOM_rtA;=6IfZA8$PLp(>-oTpsFPu66-67Ml}TJX@!K>7h-SRo@W zEKJ#qJ|oYWC}u3DPG;nEF5{x~jEni_hFItnMrLNfDO~-OnPVmv5q(j9b02teZe-pma0*3a;&jeh}1i4LK z(9IWg>O-bkeMOxF)prptu0lG<{aCFbgbBtW`?W%b%e#YaAiQaTsjmi6%MX&Z`k}VM z=4|FZpxp4DWyaG>2yWk0$4-#}vg-K7d%fyt!deA51`&b z*;W{+@IO2F>%dd-Z=nlV8-wodv^+8;bpes-22#C;=VDQvrZzt02-10l$cux$I{i1S XVJIdQ7&s|0_`oE`u#GZx%mwEk!QtQ~ literal 0 HcmV?d00001 diff --git a/src/fluency_tracker/cli.py b/src/fluency_tracker/cli.py new file mode 100644 index 0000000..8be6636 --- /dev/null +++ b/src/fluency_tracker/cli.py @@ -0,0 +1,31 @@ +"""CLI for AI fluency plan tracker.""" + +from __future__ import annotations + +import argparse +from pathlib import Path + +from .tracker import build_report, parse_tasks + + +def build_parser() -> argparse.ArgumentParser: + parser = argparse.ArgumentParser( + description="Show progress report for AI fluency plan markdown checklist." + ) + parser.add_argument( + "--plan-file", + default="README.md", + help="Path to markdown file with checklist tasks (default: README.md).", + ) + return parser + + +def main() -> int: + parser = build_parser() + args = parser.parse_args() + plan_file = Path(args.plan_file) + if not plan_file.exists(): + parser.error(f"Plan file does not exist: {plan_file}") + tasks = parse_tasks(plan_file) + print(build_report(tasks)) + return 0 diff --git a/src/fluency_tracker/tracker.py b/src/fluency_tracker/tracker.py new file mode 100644 index 0000000..c6a4aea --- /dev/null +++ b/src/fluency_tracker/tracker.py @@ -0,0 +1,49 @@ +"""Helpers to parse and report AI fluency progress.""" + +from __future__ import annotations + +from dataclasses import dataclass +from pathlib import Path +import re + + +CHECKBOX_PATTERN = re.compile(r"^- \[(?P[ xX])\] (?P.+)$") + + +@dataclass(frozen=True) +class Task: + title: str + done: bool + + +def parse_tasks(markdown_path: Path) -> list[Task]: + tasks: list[Task] = [] + for line in markdown_path.read_text(encoding="utf-8").splitlines(): + match = CHECKBOX_PATTERN.match(line.strip()) + if not match: + continue + tasks.append(Task(title=match.group("task"), done=match.group("mark").lower() == "x")) + return tasks + + +def build_report(tasks: list[Task]) -> str: + total = len(tasks) + done = sum(task.done for task in tasks) + pending = total - done + progress = 0.0 if total == 0 else (done / total) * 100 + lines = [ + "AI Fluency Plan Progress Report", + "-" * 32, + f"Total tasks : {total}", + f"Done tasks : {done}", + f"Pending tasks : {pending}", + f"Progress : {progress:.1f}%", + "", + ] + if pending > 0: + lines.append("Pending items:") + for task in (t for t in tasks if not t.done): + lines.append(f"- {task.title}") + else: + lines.append("All tasks are completed.") + return "\n".join(lines)