diff --git a/style_guide.md b/style_guide.md index 8f1872b..0660474 100644 --- a/style_guide.md +++ b/style_guide.md @@ -1,64 +1,79 @@ -# Style Guide for Julia and Python - -Most of the styles we follow are in line with QuantLib’s conventions. More styles and variable naming conventions in Julialang. More styles for Python. - -## Indentation - -Use four spaces per indentation level. - -## Notebooks - -Each notebook will have one section (`#`) and several subsections (`##`), subsubsections (`###`), etc. Each sub/sub/section should be followed by one descriptive paragraph with one to ten sentences. You don't need to assign a sectioning for each cell. In fact, each sub/sub/section could consist of a series of cells following the same purpose. - -## Naming Conventions - -- File names, folder names: UpperCamelCase [julia] or Python packages should also have short, all-lowercase names although the use of underscores is discouraged. [python] -- Names of variables, functions, and macros: lowerCamelCase [julia] or snake_case [python] Exceptions: `Δprice` lowercase with words separated by underscores as necessary to improve readability [python] -- The arguments of function (including constructors) are aligned with the indent of the first argument. -- Always use `self` for the first argument to instance methods. Always use `cls` for the first argument to class methods. If a function argument’s name clashes with a reserved keyword, it is generally better to append a single trailing underscore rather than use an abbreviation or spelling corruption. Thus `class_` is better than `clss`. -- Use of underscores is discouraged unless the name would be hard to read otherwise. -- Names of Types, Modules, Classes, Structs, Dictionaries: UpperCamelCase -- Functions that write to their arguments have names that end in `!`. These are sometimes called "mutating" or "in-place" functions because they are intended to produce changes in their arguments after the function is called, not just return a value. -- A constant or a static variable: ALL_CAPS_AND_UNDERSCORES -- Refrain from using `get` in the name of a function (e.g. use `PCA` instead of `getPCA` or `get_PCA`). -- Conciseness is valued, but avoid abbreviation (`indexin` rather than `indxin`) as it becomes difficult to remember whether and how particular words are abbreviated. -- List of abbreviations: `math`, `cov`, `corr`, `vol`, `max`, `min`. -- Number of something is named `nSomething` [julia] or `n_something` [python] (not `numSomething`, `numberSomething`, etc.) - -## Commenting - -- Each line is commented. -- Use the settings of your VS Code to hide comments unless your cursor is on a line. -- Files -> Preferences -> Settings -> search for “editor.token” -> Edit in settings.json -> add the following lines: - ```json - "editor.renderWhitespace": "none", - "workbench.colorCustomizations": { - "editor.lineHighlightBackground": "#2C3E50" - }, - "editor.tokenColorCustomizations": { - "comments": "#201c1c" - } - ``` - -## Copying variables - -- The `=` operator does not make a copy. It is assigning a new variable (i.e., way to refer to an object) the same reference (actual object in memory). If you want a copy, you can use `copy`. - -## Dataframes - -- In the Julia programming language: no use of pandas. Use `DataFrames` and `TimeArray`. +# Style Guide (Python & Julia) + +This guide governs the RiskLabAI **Python** (`RiskLabAI.py`) and **Julia** +(`RiskLabAI.jl`) packages. The two packages aim to mirror each other's public +API and structure where it makes sense (cross-language parity is a first-class +goal), so the conventions below are shared in spirit and differ only where the +languages do. + +Where an automated tool enforces a rule, the tool is the source of truth and +this document does not restate the mechanics. + +## Python + +### Formatting and linting — enforced by tooling + +Formatting and import order are owned by **black** and **ruff**; do not format +by hand. Both are pinned in `pyproject.toml` (`[tool.black]`, `[tool.ruff]`) and +in the `dev` extra, and both run in CI on every push and pull request. Before +committing: + +``` +python -m ruff check --fix RiskLabAI test +python -m black RiskLabAI test +``` + +This covers indentation (4 spaces), spacing around operators, argument +wrapping/alignment, line length, and import sorting — so none of those are +specified here. + +### Naming — PEP 8 (the 2.0.0 canon) + +Since 2.0.0 the public API follows standard Python naming (see +`NAMING_CANON_2.0.0.md`): + +- Functions, methods, variables, and parameters: `snake_case`. +- Classes: `CapWords`. +- Constants: `UPPER_SNAKE_CASE`, ASCII identifiers only. +- "Number of X" is `n_x` (e.g. `n_threads`, `n_splits`), not `numX`. +- First argument is `self` for instance methods, `cls` for class methods. If a + name clashes with a keyword, append a trailing underscore (`class_`), never a + misspelling. +- Prefer descriptive names over `get`-prefixes and over abbreviations + (`compute_sigmoid_width`, not `getW`). Accepted short forms: `cov`, `corr`, + `vol`, `min`, `max`. + +Public renames must follow the deprecation policy in `CLAUDE.md`: never break +the public API without a major version bump and a deprecation shim that keeps +the old name working (with a `DeprecationWarning`) for one minor cycle. + +### Documentation + +Public functions, classes, and methods carry NumPy-style docstrings (Parameters, +Returns, Raises, References). Comments explain *why*, not *what*; avoid +line-by-line narration. + +## Julia + +- Formatting: **JuliaFormatter** (4-space indent). +- File and folder names, types, modules, structs: `UpperCamelCase`. +- Functions, variables, macros: `lower_snake_case` (mirroring the Python API for + parity; document any deliberate divergence). +- Mutating functions that write to their arguments end in `!`. +- Constants: `ALL_CAPS_AND_UNDERSCORES`. +- "Number of X" is `n_x`. +- DataFrames/time series: prefer `DataFrames`/`TimeArray`; do not use the pandas + Julia wrapper. Convert to a `DataFrame` inside a code block when convenient and + back to `TimeArray` afterward. + +## Notebooks (both languages) + +Each notebook has one top-level section (`#`) and nested subsections +(`##`, `###`, …). Each section is followed by a short descriptive paragraph +(roughly one to ten sentences). Cells need not map one-to-one to sections; a +series of cells may share a section. Notebooks must run top-to-bottom against a +pinned environment with seeded randomness. ## Figures -- Should be transparent. - -## Time Series - -- All time-series data (pd.Series, pd.DataFrame, etc.) in Python should be converted to `TimeArray` structs in Julia. We strongly advise against using the Pandas Julia wrapper or the Julia DataFrame. `TimeArray` structs can be converted to DataFrames in the code blocks and then converted back to `TimeArrays` for convenience. - -## Spacing - -- `=`, `>`, `=>`, `<`, `=<`, `+=`, `-=`, `*=`, `==`, `===`, `&&`, `||`: leave a space before and after -- `*`, `/`, `^`: do not leave spaces before and after -- `+`, `-`: leave spaces before and after -- `;`: put a space after (and not before) comma and semicolon \ No newline at end of file +Figures should have transparent backgrounds.