Skip to content

Commit d591053

Browse files
aygp-drClaude
and
Claude
committed
Update CLAUDE.md and format code with Black and isort
Improve CLAUDE.md with comprehensive build/test commands and code style guidelines. Apply code formatting across the repository for consistency. Co-authored-by: Claude <[email protected]> Closes: #5
1 parent 1e4e459 commit d591053

34 files changed

+1671
-384
lines changed

CLAUDE.md

+15-22
Original file line numberDiff line numberDiff line change
@@ -6,34 +6,27 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
66

77
- Install dependencies: `make install` or `poetry install`
88
- Create virtual environment: `make venv` or `python3 -m venv venv`
9-
- Lint code: `make lint` or `poetry run flake8 .`
10-
- Format code: `poetry run black .` and `poetry run isort .`
9+
- Format code: `make format` or `poetry run black . && poetry run isort .`
10+
- Lint code: `make lint` or `poetry run flake8 . && poetry run mypy .`
11+
- Type check: `make typecheck` or `poetry run mypy .`
1112
- Run all tests: `make test` or `poetry run pytest tests/`
12-
- Run single test: `poetry run pytest tests/test_file.py::TestClass::test_method -v`
13+
- Run single test file: `make test-file FILE=tests/test_file.py` or `poetry run pytest tests/test_file.py -v`
14+
- Run single test function: `make test-function FILE=tests/test_file.py::test_function` or `poetry run pytest tests/test_file.py::TestClass::test_method -v`
1315
- Run tests in exercises: `cd exercises && poetry run pytest test_file.py`
1416

1517
## Code Style Guidelines
1618

1719
- Use Python 3.11+ features and syntax
18-
- Follow PEP 8 style guidelines
19-
- Use Black for code formatting and isort for import sorting
20-
- Use type hints for function parameters and return values
21-
- Use docstrings for all classes and functions
20+
- Follow PEP 8 style guidelines with Black (line-length=88) and isort
21+
- Use strict type hints throughout (mypy with disallow_untyped_defs=true)
22+
- Use snake_case for variables/functions, PascalCase for classes
2223
- Organize imports: standard library, third-party, local
23-
- Use snake_case for variables and functions, PascalCase for classes
24-
- Prefer context managers for file handling
25-
- Use proper error handling with specific exceptions
26-
- Organize code using modules and packages appropriately
24+
- Include docstrings for all modules, classes, and functions
25+
- Use context managers for resource handling
26+
- Raise specific exceptions with descriptive messages
27+
- Validate input parameters with assertions or value checks
28+
- Structure code using modules and packages appropriately
2729

28-
## Documentation Standards
30+
## Language Implementation Notes
2931

30-
- Include a docstring for each module, class, and function
31-
- Use descriptive variable and function names
32-
- When creating examples, follow the existing patterns in the repository
33-
34-
## Simple Language Implementation
35-
36-
- The repository includes a simple language implementation with lexer, parser, and evaluator
37-
- Key components: TokenType, Token, Lexer, Parser, Symbol, Environment, Procedure, and Evaluator classes
38-
- The language supports basic arithmetic, conditionals, and functional programming constructs
39-
- The interpreter includes reflection capabilities and a meta-circular evaluator
32+
The repository includes a simple language implementation with lexer, parser, and evaluator supporting functional programming constructs and reflection capabilities.

abstract_base_classes.py

+55-48
Original file line numberDiff line numberDiff line change
@@ -20,25 +20,26 @@
2020
"""
2121

2222
import abc
23-
from abc import ABC, abstractmethod
24-
from collections.abc import Sequence, Mapping
2523
import sys
24+
from abc import ABC, abstractmethod
25+
from collections.abc import Mapping, Sequence
2626
from typing import Protocol, runtime_checkable
2727

28+
2829
# Basic ABC Example
2930
class Shape(ABC):
3031
"""Abstract base class representing a geometric shape."""
31-
32+
3233
@abstractmethod
3334
def area(self):
3435
"""Calculate the area of the shape."""
3536
pass
36-
37+
3738
@abstractmethod
3839
def perimeter(self):
3940
"""Calculate the perimeter of the shape."""
4041
pass
41-
42+
4243
def describe(self):
4344
"""Non-abstract method that subclasses inherit without overriding."""
4445
return f"This shape has area {self.area()} and perimeter {self.perimeter()}"
@@ -47,54 +48,56 @@ def describe(self):
4748
# Concrete implementation of Shape
4849
class Rectangle(Shape):
4950
"""A rectangle implementation of the Shape ABC."""
50-
51+
5152
def __init__(self, width, height):
5253
self.width = width
5354
self.height = height
54-
55+
5556
def area(self):
5657
return self.width * self.height
57-
58+
5859
def perimeter(self):
5960
return 2 * (self.width + self.height)
6061

6162

6263
class Circle(Shape):
6364
"""A circle implementation of the Shape ABC."""
64-
65+
6566
def __init__(self, radius):
6667
self.radius = radius
67-
68+
6869
def area(self):
6970
import math
70-
return math.pi * self.radius ** 2
71-
71+
72+
return math.pi * self.radius**2
73+
7274
def perimeter(self):
7375
import math
76+
7477
return 2 * math.pi * self.radius
7578

7679

7780
# Abstract Properties Example
7881
class DataSource(ABC):
7982
"""Abstract base class for data sources with required properties."""
80-
83+
8184
@property
8285
@abstractmethod
8386
def name(self):
8487
"""The name of the data source."""
8588
pass
86-
89+
8790
@property
8891
@abstractmethod
8992
def connection_string(self):
9093
"""The connection string for the data source."""
9194
pass
92-
95+
9396
@abstractmethod
9497
def connect(self):
9598
"""Connect to the data source."""
9699
pass
97-
100+
98101
@abstractmethod
99102
def fetch_data(self, query):
100103
"""Fetch data from the data source."""
@@ -103,24 +106,24 @@ def fetch_data(self, query):
103106

104107
class DatabaseSource(DataSource):
105108
"""A database implementation of DataSource."""
106-
109+
107110
def __init__(self, db_name, host="localhost", port=5432):
108111
self._db_name = db_name
109112
self._host = host
110113
self._port = port
111-
114+
112115
@property
113116
def name(self):
114117
return f"Database: {self._db_name}"
115-
118+
116119
@property
117120
def connection_string(self):
118121
return f"postgresql://{self._host}:{self._port}/{self._db_name}"
119-
122+
120123
def connect(self):
121124
print(f"Connecting to {self.connection_string}")
122125
# In real code: return psycopg2.connect(self.connection_string)
123-
126+
124127
def fetch_data(self, query):
125128
print(f"Executing query on {self.name}: {query}")
126129
# In real code: return conn.execute(query).fetchall()
@@ -129,12 +132,12 @@ def fetch_data(self, query):
129132
# Advanced: Abstract Base Class Registration
130133
class JSONSerializable(ABC):
131134
"""Abstract base class for objects that can be serialized to JSON."""
132-
135+
133136
@abstractmethod
134137
def to_json(self):
135138
"""Convert the object to a JSON-compatible dictionary."""
136139
pass
137-
140+
138141
@classmethod
139142
def __subclasshook__(cls, subclass):
140143
"""Special method to determine if a class is a subclass without explicit inheritance."""
@@ -149,7 +152,7 @@ class User:
149152
def __init__(self, name, email):
150153
self.name = name
151154
self.email = email
152-
155+
153156
def to_json(self):
154157
return {"name": self.name, "email": self.email}
155158

@@ -162,25 +165,25 @@ def to_json(self):
162165
@runtime_checkable
163166
class Drawable(Protocol):
164167
"""A protocol defining objects that can be drawn."""
165-
168+
166169
def draw(self) -> None:
167170
"""Draw the object."""
168171
...
169172

170173

171174
class Canvas:
172175
"""A canvas that can draw any Drawable object."""
173-
176+
174177
def __init__(self):
175178
self.elements = []
176-
179+
177180
def add_element(self, element):
178181
"""Add an element to the canvas."""
179182
if isinstance(element, Drawable):
180183
self.elements.append(element)
181184
else:
182185
raise TypeError("Element must be Drawable")
183-
186+
184187
def draw_all(self):
185188
"""Draw all elements on the canvas."""
186189
for element in self.elements:
@@ -190,27 +193,27 @@ def draw_all(self):
190193
# This class satisfies the Drawable protocol without explicit inheritance
191194
class Button:
192195
"""A button that can be drawn."""
193-
196+
194197
def __init__(self, label):
195198
self.label = label
196-
199+
197200
def draw(self):
198201
print(f"Drawing button: {self.label}")
199202

200203

201204
# Real-world Example: Custom Container with ABC
202205
class SortedItems(Sequence):
203206
"""A sequence that keeps items in sorted order."""
204-
207+
205208
def __init__(self, items=None):
206209
self._items = sorted(items) if items else []
207-
210+
208211
def __getitem__(self, index):
209212
return self._items[index]
210-
213+
211214
def __len__(self):
212215
return len(self._items)
213-
216+
214217
def add(self, item):
215218
"""Add an item to the collection, maintaining sorted order."""
216219
self._items.append(item)
@@ -221,15 +224,15 @@ def add(self, item):
221224
def exercises():
222225
"""Exercises for abstract base classes"""
223226
print("\nExercises:")
224-
227+
225228
# Exercise 1: Create a FileHandler ABC with concrete implementations
226229
print("Exercise 1: Create a FileHandler ABC with methods read() and write()")
227230
# Your solution here
228-
231+
229232
# Exercise 2: Implement a Validator protocol for data validation
230233
print("Exercise 2: Implement a Validator protocol")
231234
# Your solution here
232-
235+
233236
# Exercise 3: Create a custom ABC for caching mechanisms
234237
print("Exercise 3: Create a Cacheable ABC")
235238
# Your solution here
@@ -238,17 +241,17 @@ def exercises():
238241
# Main function
239242
if __name__ == "__main__":
240243
print("Abstract Base Classes in Python\n")
241-
244+
242245
# Demonstrate basic ABC
243246
rectangle = Rectangle(5, 10)
244247
circle = Circle(7)
245-
248+
246249
print("Basic ABC Example:")
247250
print(f"Rectangle area: {rectangle.area()}, perimeter: {rectangle.perimeter()}")
248251
print(f"Circle area: {circle.area():.2f}, perimeter: {circle.perimeter():.2f}")
249252
print(f"Rectangle description: {rectangle.describe()}")
250253
print()
251-
254+
252255
# Demonstrate abstract properties
253256
db = DatabaseSource("customers_db")
254257
print("Abstract Properties Example:")
@@ -257,15 +260,19 @@ def exercises():
257260
db.connect()
258261
db.fetch_data("SELECT * FROM customers")
259262
print()
260-
263+
261264
# Demonstrate ABC registration
262265
user = User("Alice", "[email protected]")
263266
print("ABC Registration Example:")
264-
print(f"Is User a subclass of JSONSerializable? {issubclass(User, JSONSerializable)}")
265-
print(f"Is user an instance of JSONSerializable? {isinstance(user, JSONSerializable)}")
267+
print(
268+
f"Is User a subclass of JSONSerializable? {issubclass(User, JSONSerializable)}"
269+
)
270+
print(
271+
f"Is user an instance of JSONSerializable? {isinstance(user, JSONSerializable)}"
272+
)
266273
print(f"User as JSON: {user.to_json()}")
267274
print()
268-
275+
269276
# Demonstrate Protocol
270277
if sys.version_info >= (3, 8):
271278
print("Protocol Example (Python 3.8+):")
@@ -277,11 +284,11 @@ def exercises():
277284
canvas.draw_all()
278285
except TypeError as e:
279286
print(f"Error: {e}")
280-
287+
281288
# This would fail:
282289
# canvas.add_element("not drawable")
283290
print()
284-
291+
285292
# Demonstrate custom container with ABC
286293
print("Custom Container Example:")
287294
sorted_items = SortedItems([3, 1, 5, 2, 4])
@@ -291,6 +298,6 @@ def exercises():
291298
print(f"Item at index 2: {sorted_items[2]}")
292299
print(f"Length: {len(sorted_items)}")
293300
print()
294-
301+
295302
# Run exercises
296-
exercises()
303+
exercises()

0 commit comments

Comments
 (0)