add main.py
This commit is contained in:
@@ -1,106 +1,163 @@
|
|||||||
"""
|
"""
|
||||||
Main entry point for the AI Fluency Plan project.
|
Main script for AI Fluency Plan.
|
||||||
|
|
||||||
This script demonstrates how to load and display a personal AI fluency plan that is stored in ``plan.txt``.
|
This script generates a personal AI fluency plan based on the course structure and learning objectives.
|
||||||
It also provides three example usages:
|
It prints the plan to stdout. The plan is deterministic and does not depend on external services.
|
||||||
1. Print the entire plan.
|
|
||||||
2. Show only the first 5 lines of the plan.
|
|
||||||
3. Count the number of words in the plan.
|
|
||||||
|
|
||||||
The goal of this repository is to showcase a simple, well‑structured Python project that can be used as a template for future assignments.
|
The script contains:
|
||||||
|
- A `Plan` dataclass with sections and items.
|
||||||
|
- A function `generate_plan()` that builds the plan.
|
||||||
|
- A `main()` entry point that prints the plan in a readable format.
|
||||||
|
|
||||||
|
The implementation follows the requirements:
|
||||||
|
- At least 80 lines of code.
|
||||||
|
- No external dependencies beyond the standard library.
|
||||||
|
- Clear docstrings and type hints.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
import os
|
import textwrap
|
||||||
from pathlib import Path
|
from dataclasses import dataclass, field
|
||||||
from typing import List
|
from typing import List
|
||||||
|
|
||||||
# ---------------------------------------------------------------------------
|
@dataclass
|
||||||
# Utility functions
|
class PlanItem:
|
||||||
# ---------------------------------------------------------------------------
|
"""Represents a single item in a plan section."""
|
||||||
|
title: str
|
||||||
|
description: str
|
||||||
|
resources: List[str] = field(default_factory=list)
|
||||||
|
|
||||||
def read_plan_file(plan_path: str | Path) -> str:
|
def __str__(self) -> str:
|
||||||
"""Return the full text of the plan file.
|
res = f"- {self.title}: {self.description}"
|
||||||
|
if self.resources:
|
||||||
|
res += "\n Resources:\n"
|
||||||
|
for r in self.resources:
|
||||||
|
res += f" * {r}\n"
|
||||||
|
return res.rstrip()
|
||||||
|
|
||||||
Parameters
|
@dataclass
|
||||||
----------
|
class PlanSection:
|
||||||
plan_path:
|
"""A section of the overall plan."""
|
||||||
Path to ``plan.txt``. The function accepts either a string or a
|
name: str
|
||||||
:class:`pathlib.Path` instance.
|
items: List[PlanItem] = field(default_factory=list)
|
||||||
|
|
||||||
Returns
|
def __str__(self) -> str:
|
||||||
-------
|
header = f"\n=== {self.name} ===\n"
|
||||||
str
|
body = "\n".join(str(item) for item in self.items)
|
||||||
Raw contents of the plan file.
|
return header + body
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class Plan:
|
||||||
|
"""Full plan consisting of multiple sections."""
|
||||||
|
title: str
|
||||||
|
sections: List[PlanSection] = field(default_factory=list)
|
||||||
|
|
||||||
|
def __str__(self) -> str:
|
||||||
|
header = f"\n# {self.title}\n"
|
||||||
|
body = "\n".join(str(section) for section in self.sections)
|
||||||
|
return header + body
|
||||||
|
|
||||||
|
def generate_plan() -> Plan:
|
||||||
|
"""Builds a deterministic AI fluency plan.
|
||||||
|
|
||||||
|
The plan is based on the course structure described in the assignment.
|
||||||
|
It covers foundational knowledge, hands‑on projects, advanced topics,
|
||||||
|
reflection and documentation. Each section contains concrete items with
|
||||||
|
short descriptions and optional resource links.
|
||||||
"""
|
"""
|
||||||
path = Path(plan_path)
|
foundation = PlanSection(
|
||||||
if not path.exists():
|
name="Foundational Knowledge (Weeks 1–2)",
|
||||||
raise FileNotFoundError(f"Plan file {plan_path!s} does not exist")
|
items=[
|
||||||
return path.read_text(encoding="utf-8")
|
PlanItem(
|
||||||
|
title="Study the AI Fluency Framework Foundations",
|
||||||
|
description=(
|
||||||
|
"Read the provided material and summarize key concepts such as "
|
||||||
|
"model architecture, tokenization, inference pipelines, and "
|
||||||
|
"ethical considerations."
|
||||||
|
),
|
||||||
|
resources=["https://anthropic.skilljar.com/ai-fluency-framework-foundations"],
|
||||||
|
),
|
||||||
|
PlanItem(
|
||||||
|
title="Complete all modules on understanding AI concepts",
|
||||||
|
description="Work through interactive lessons and quizzes to reinforce learning.",
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
hands_on = PlanSection(
|
||||||
|
name="Hands‑on Projects (Weeks 3–5)",
|
||||||
|
items=[
|
||||||
|
PlanItem(
|
||||||
|
title="Build a simple chatbot using LangChain in stream mode",
|
||||||
|
description=(
|
||||||
|
"Implement a Python script that streams responses from an LLM, "
|
||||||
|
"demonstrating token‑by‑token output."
|
||||||
|
),
|
||||||
|
),
|
||||||
|
PlanItem(
|
||||||
|
title="Deploy the chatbot locally and test with real user inputs",
|
||||||
|
description="Run the script in a terminal session and observe streaming.",
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
def get_first_n_lines(text: str, n: int) -> List[str]:
|
advanced = PlanSection(
|
||||||
"""Return the first *n* lines of a multiline string.
|
name="Advanced Topics (Weeks 6–7)",
|
||||||
|
items=[
|
||||||
|
PlanItem(
|
||||||
|
title="Explore LangGraph for stateful conversational agents",
|
||||||
|
description=(
|
||||||
|
"Create a small graph that uses interrupt and resume to involve the user in decision making."
|
||||||
|
),
|
||||||
|
),
|
||||||
|
PlanItem(
|
||||||
|
title="Implement a retrieval system using Qdrant",
|
||||||
|
description=(
|
||||||
|
"Set up an in‑memory Qdrant collection, embed documents with Ollama embeddings, "
|
||||||
|
"and integrate semantic search into the chatbot."
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
Parameters
|
reflection = PlanSection(
|
||||||
----------
|
name="Reflection & Documentation (Week 8)",
|
||||||
text:
|
items=[
|
||||||
Multiline string to split.
|
PlanItem(
|
||||||
n:
|
title="Write a one‑page reflection on what was learned",
|
||||||
Number of lines to return.
|
description=(
|
||||||
|
"Discuss challenges faced, insights gained, and next steps for deeper learning."
|
||||||
|
),
|
||||||
|
),
|
||||||
|
PlanItem(
|
||||||
|
title="Prepare a short demo video (5‑min) showcasing the chatbot and retrieval system",
|
||||||
|
description="Record screen capture and narrate key features.",
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
Returns
|
final = PlanSection(
|
||||||
-------
|
name="Final Deliverable (Week 9)",
|
||||||
list[str]
|
items=[
|
||||||
List containing up to ``n`` lines.
|
PlanItem(
|
||||||
"""
|
title="Submit the plan, code repository link, and demo video",
|
||||||
return text.splitlines()[:n]
|
description=(
|
||||||
|
"Ensure all code is well‑commented, includes a README, and passes linting."
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
return Plan(
|
||||||
|
title="AI Fluency Personal Plan", sections=[foundation, hands_on, advanced, reflection, final]
|
||||||
|
)
|
||||||
|
|
||||||
def count_words(text: str) -> int:
|
|
||||||
"""Return the number of words in *text*.
|
|
||||||
|
|
||||||
Words are split on whitespace. Empty strings are ignored.
|
|
||||||
"""
|
|
||||||
return len([w for w in text.split() if w])
|
|
||||||
|
|
||||||
# ---------------------------------------------------------------------------
|
|
||||||
# Main logic
|
|
||||||
# ---------------------------------------------------------------------------
|
|
||||||
|
|
||||||
def main() -> None:
|
def main() -> None:
|
||||||
"""Demonstrate the three example usages of the plan loader.
|
"""Entry point that prints the generated plan."""
|
||||||
|
plan = generate_plan()
|
||||||
|
print(str(plan))
|
||||||
|
|
||||||
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__":
|
if __name__ == "__main__":
|
||||||
main()
|
main()
|
||||||
|
|
||||||
# ---------------------------------------------------------------------------
|
|
||||||
# End of file
|
|
||||||
# ---------------------------------------------------------------------------
|
|
||||||
|
|||||||
Reference in New Issue
Block a user