diff --git a/main.py b/main.py index afe7ed8..83b4374 100644 --- a/main.py +++ b/main.py @@ -1,91 +1,106 @@ """ -Main entry point for the Personal AI Fluency Plan project. +Main entry point for the AI Fluency Plan project. -The script demonstrates how to use the :class:`plan.Plan` data model, create a default plan, -add custom milestones and export the plan as JSON. It also shows three distinct usage -examples that satisfy the "at least 3 examples" requirement. +This script demonstrates how to load and display a personal AI fluency plan that is stored in ``plan.txt``. +It also provides three example usages: +1. Print the entire plan. +2. Show only the first 5 lines of the plan. +3. Count the number of words in the plan. -Running ``python main.py`` will print the results of each example to stdout. +The goal of this repository is to showcase a simple, well‑structured Python project that can be used as a template for future assignments. """ from __future__ import annotations -import json -from datetime import date, timedelta - -# Import the plan module we created earlier -from plan import Plan, WeekPlan, Milestone +import os +from pathlib import Path +from typing import List # --------------------------------------------------------------------------- -# Example 1: Create a default 9‑week plan and print it +# Utility functions # --------------------------------------------------------------------------- -def example_default_plan() -> None: - """Instantiate a :class:`~plan.Plan` with the built‑in default weeks. +def read_plan_file(plan_path: str | Path) -> str: + """Return the full text of the plan file. - The constructor automatically populates nine weeks if no custom weeks are supplied. + Parameters + ---------- + plan_path: + Path to ``plan.txt``. The function accepts either a string or a + :class:`pathlib.Path` instance. + + Returns + ------- + str + Raw contents of the plan file. """ - plan = Plan(start_date=date.today()) - print("\n=== Example 1: Default 9‑week plan ===") - print(plan) + path = Path(plan_path) + if not path.exists(): + raise FileNotFoundError(f"Plan file {plan_path!s} does not exist") + return path.read_text(encoding="utf-8") -# --------------------------------------------------------------------------- -# Example 2: Add a custom week with two milestones and display the updated plan -# --------------------------------------------------------------------------- -def example_custom_week() -> None: - """Create a plan, add a user‑defined week and show the result. +def get_first_n_lines(text: str, n: int) -> List[str]: + """Return the first *n* lines of a multiline string. - The new week starts one month after the default start date. Two milestones are added - to illustrate how the :class:`~plan.Milestone` objects can be constructed. + Parameters + ---------- + text: + Multiline string to split. + n: + Number of lines to return. + + Returns + ------- + list[str] + List containing up to ``n`` lines. """ - base_plan = Plan(start_date=date.today()) - custom_start = date.today() + timedelta(days=30) - week = WeekPlan(number=10, start_date=custom_start) - week.add_milestone( - Milestone( - title="Deep Dive into LangGraph", - description=( - "Implement a stateful conversational agent that uses interrupt hooks to confirm tool calls." - ), - due_date=custom_start + timedelta(days=6), - ) - ) - week.add_milestone( - Milestone( - title="Deploy the Agent", - description=( - "Containerise the agent and expose it via a FastMCP server for external clients." - ), - due_date=custom_start + timedelta(days=13), - ) - ) - base_plan.add_week(week) + return text.splitlines()[:n] - print("\n=== Example 2: Plan with custom week added ===") - print(base_plan) -# --------------------------------------------------------------------------- -# Example 3: Export the plan to a JSON string and pretty‑print it -# --------------------------------------------------------------------------- +def count_words(text: str) -> int: + """Return the number of words in *text*. -def example_export_json() -> None: - """Export a :class:`~plan.Plan` instance to JSON. - - The function demonstrates that the data model can be serialised for storage or API - consumption. It uses ``json.dumps`` with indentation for readability. + Words are split on whitespace. Empty strings are ignored. """ - plan = Plan(start_date=date.today()) - json_str = json.dumps(plan.to_dict(), indent=2, ensure_ascii=False) - print("\n=== Example 3: Exported JSON ===") - print(json_str) + return len([w for w in text.split() if w]) # --------------------------------------------------------------------------- -# Main entry point – run all examples when executed as a script +# Main logic +# --------------------------------------------------------------------------- + +def main() -> None: + """Demonstrate the three example usages of the plan loader. + + The function prints output to stdout. It is intentionally simple so + that it can be run in any environment without external dependencies. + """ + plan_path = Path(__file__).parent / "plan.txt" + try: + full_plan = read_plan_file(plan_path) + except FileNotFoundError as exc: + print(exc) + return + + # Example 1: Print the entire plan. + print("\n=== Full AI Fluency Plan ===") + print(full_plan) + + # Example 2: Show only the first five lines. + print("\n=== First 5 lines of the plan ===") + for line in get_first_n_lines(full_plan, 5): + print(line) + + # Example 3: Count words. + word_count = count_words(full_plan) + print(f"\nWord count: {word_count}") + +# --------------------------------------------------------------------------- +# Entry point guard # --------------------------------------------------------------------------- if __name__ == "__main__": - example_default_plan() - example_custom_week() - example_export_json() + main() -# End of main.py +# --------------------------------------------------------------------------- +# End of file +# ---------------------------------------------------------------------------