AI Skill Report Card
Working with Python Data Types
Quick Start13 / 15
Pythonfrom datetime import datetime, date, timedelta from collections import defaultdict, Counter, namedtuple from enum import Enum, auto # Common patterns now = datetime.now() tomorrow = date.today() + timedelta(days=1) counts = Counter(["a", "b", "a"]) # Counter({'a': 2, 'b': 1}) Point = namedtuple("Point", ["x", "y"]) p = Point(1, 2) class Color(Enum): RED = auto() GREEN = auto()
Recommendation▾
Add more diverse examples covering deque, defaultdict, and array usage with concrete input/output pairs rather than concentrating on datetime/enum/namedtuple.
Workflow13 / 15
- Identify the need: dates/times, structured records, counting/grouping, fixed sets of constants, or memory-efficient sequences.
- Pick the right module/type (see decision table below).
- Check mutability requirements — use
namedtuple/dataclassfor immutable records, plain classes or dicts for mutable state. - Consider performance —
arrayfor homogeneous numeric data,dequefor queue-like operations,set/frozensetfor membership tests. - Verify timezone handling for datetime — always prefer timezone-aware objects (
datetime.now(timezone.utc)) over naive ones in production code.
Progress checklist for a data-modeling task:
- Determine if data is temporal, categorical, or collection-based
- Choose the specific type/module
- Handle edge cases (timezones, empty collections, enum uniqueness)
- Add type hints referencing the chosen types
Recommendation▾
Include a 'bad outcome' example (e.g., mutating a namedtuple or naive datetime bug) to show contrast, not just best practices as prose.
Decision Table
| Need | Use |
|---|---|
| Calendar dates only | datetime.date |
| Date + time | datetime.datetime |
| Time deltas/arithmetic | datetime.timedelta |
| Timezone-aware time | datetime.timezone, zoneinfo.ZoneInfo |
| Month/year calendar utilities | calendar module |
| Fixed set of named constants | enum.Enum / enum.IntEnum / enum.Flag |
| Bitwise combinable flags | enum.Flag or enum.IntFlag |
| Fast counting | collections.Counter |
| Default values on missing keys | collections.defaultdict |
| Ordered key-value with move-to-end | collections.OrderedDict |
| Lightweight immutable record | collections.namedtuple or typing.NamedTuple |
| Double-ended queue | collections.deque |
| Compact numeric arrays | array.array |
| Fast membership/uniqueness | set / frozenset |
| Weak references to avoid leaks | weakref |
| Sortable priority structures | heapq with lists |
| Copy semantics (shallow/deep) | copy.copy / copy.deepcopy |
Examples14 / 20
Example 1: Input: Need to count word frequency in a list of strings. Output:
Pythonfrom collections import Counter freq = Counter(words) freq.most_common(3) # top 3 words
Example 2: Input: Need an immutable, lightweight coordinate object with named fields. Output:
Pythonfrom typing import NamedTuple class Point(NamedTuple): x: float y: float p = Point(1.0, 2.0)
Example 3: Input: Need a set of mutually exclusive status constants with string values for logging. Output:
Pythonfrom enum import Enum class Status(Enum): PENDING = "pending" ACTIVE = "active" DONE = "done" print(Status.ACTIVE.value) # "active"
Example 4: Input: Need to compute the date 90 days from now, timezone-aware. Output:
Pythonfrom datetime import datetime, timedelta, timezone future = datetime.now(timezone.utc) + timedelta(days=90)
Recommendation▾
The decision table is excellent but could be tied more directly to the workflow steps with cross-references for faster navigation.
Best Practices
- Always use timezone-aware
datetimeobjects (timezone.utcorzoneinfo.ZoneInfo) rather than naive datetimes to avoid ambiguity across systems. - Prefer
enum.Enumover plain string/int constants for closed sets of values — it gives type safety and IDE support. - Use
collections.namedtuple/NamedTupleordataclasses.dataclass(frozen=True)instead of raw tuples/dicts for structured, self-documenting data. - Use
defaultdictinstead of manually checkingif key not in dict. - Prefer
dequeoverlistfor queue/stack operations requiring O(1) appends/pops from both ends. - Use
array.arrayonly when memory efficiency for large homogeneous numeric data matters; otherwise alistis simpler.
Common Pitfalls
- Don't use naive
datetimeobjects when comparing across timezones — this silently produces wrong results. - Don't mutate a
namedtuple— it's immutable by design; use._replace()to create a modified copy. - Don't use
listfor frequent front-insertion/removal — it's O(n); usedeque. - Don't compare
Enummembers by value equality when identity (is) comparisons are expected — useisfor enum members. - Don't forget that
IntEnum/IntFlagmembers compare equal to plain ints, which can hide bugs if strict typing is desired — prefer plainEnumunless int compatibility is required. - Don't deep-copy objects containing unpicklable resources (file handles, sockets) — implement
__deepcopy__explicitly if needed.