### Local Project Installation Source: https://github.com/raoulg/codestyle/blob/main/docs/make_a_module.md Demonstrates methods for installing a Python project locally for development. It includes commands using `pip` for editable installs and `uv sync` for faster synchronization with the virtual environment. ```bash # Using pip pip install -e . # Using uv uv sync ``` -------------------------------- ### Environment Setup with uv Source: https://github.com/raoulg/codestyle/blob/main/docs/make_a_module.md Demonstrates using the `uv` tool for project initialization, dependency management, and synchronizing the virtual environment, highlighting its speed advantages over pip. ```bash uv init myproject cd myproject uv add numpy # If you already have a pyproject.toml file, or want to recreate your .venv, use `uv sync` ``` -------------------------------- ### Python Module Import Example Source: https://github.com/raoulg/codestyle/blob/main/docs/make_a_module.md Demonstrates how to import a function from a local module within a Python script or notebook, assuming a standard project structure and virtual environment setup. ```python from mymodule.utils import myfunction ``` -------------------------------- ### Python Module Import Example Source: https://github.com/raoulg/codestyle/blob/main/docs/make_a_module.md Illustrates how to import modules and functions from different files within a Python project, adhering to best practices for maintainability and clarity. ```python # In my_module.py def greet(name): return f"Hello, {name}!" # In main_script.py from my_module import greet print(greet("World")) ``` -------------------------------- ### Python Virtual Environment Setup Source: https://github.com/raoulg/codestyle/blob/main/docs/make_a_module.md Provides commands for creating and activating a Python virtual environment, a crucial step for managing project dependencies and isolating environments. ```bash # Create a virtual environment python -m venv venv # Activate the virtual environment (Windows) .\venv\Scripts\activate # Activate the virtual environment (macOS/Linux) source venv/bin/activate ``` -------------------------------- ### Publishing to PyPI Source: https://github.com/raoulg/codestyle/blob/main/docs/make_a_module.md Details the one-time setup required for publishing a Python project to the Python Package Index (PyPI), including creating an account and obtaining an API token. It then shows the command to publish the built wheel. ```bash # Publish your wheel uv publish --token $YOUR_TOKEN ``` -------------------------------- ### Wheel File Structure and Usage Source: https://github.com/raoulg/codestyle/blob/main/docs/make_a_module.md Explains the nature of a `.whl` (Wheel) file as a pre-built package format that is faster to install than source code. It demonstrates how to save and install wheel files for offline use or from network locations. ```bash # Save wheels for offline use cp dist/myproject-0.1.0-py3-none-any.whl ~/my-wheels/ # Install later pip install ~/my-wheels/myproject-0.1.0-py3-none-any.whl # Or from a network location pip install /mnt/shared/wheels/myproject-0.1.0-py3-none-any.whl ``` -------------------------------- ### Python Wheel File (.whl) Source: https://github.com/raoulg/codestyle/blob/main/docs/make_a_module.md Explains the concept of a Python Wheel file, which is a pre-built distribution format that allows for faster installation compared to source distributions. ```text A .whl file is a built distribution package for Python. It's essentially a ZIP archive with a specific structure that allows for faster installation because it contains pre-compiled code and metadata. Wheels are the standard way to distribute Python packages. ``` -------------------------------- ### Installing Packages with Pip Source: https://github.com/raoulg/codestyle/blob/main/docs/dependencies_management.md Demonstrates how to install a package named 'example-package' into an activated virtual environment using pip. ```bash pip install example-package ``` -------------------------------- ### Executing Python Modules with -m Flag Source: https://github.com/raoulg/codestyle/blob/main/docs/make_a_module.md Explains how to run Python code as a module using the `-m` flag, which is useful for executing scripts within packages. It shows examples for both direct path and installed module execution. ```bash # From project root python -m src.mymodule.main # From project root (with venv synced) python -m mymodule.main ``` -------------------------------- ### Importing Installed Module Source: https://github.com/raoulg/codestyle/blob/main/docs/make_a_module.md Shows how to import modules from an installed local package. After installation, the `src` prefix can be removed from import statements, allowing direct imports like `from mymodule.main import hi`. ```python >>> from mymodule.main import hi >>> hi() hello! ``` -------------------------------- ### Defining Command-Line Scripts in pyproject.toml Source: https://github.com/raoulg/codestyle/blob/main/docs/make_a_module.md Shows how to define executable command-line scripts from Python modules using the [project.scripts] table in pyproject.toml. This allows users to run specific functions as commands after package installation. ```toml [project.scripts] mymodule = "mymodule.main:main" mymodule-init = "mymodule.commands:initialize" mymodule-cleanup = "mymodule.commands:cleanup" ``` -------------------------------- ### TimeSeriesPlot Usage Example Source: https://github.com/raoulg/codestyle/blob/main/docs/abstract_code.md Demonstrates how to instantiate and use the TimeSeriesPlot class with specific settings and data. It shows the process of configuring plot properties and generating the visualization. ```python # Usage - this demonstrates how abstract the code has become # we dont need to specify # ax.set_title("Loyalty Score per Author") etc somewhere deep in the class, # and keep on rewriting and rewriting our class. # we just make a new instance of our settings, because it was # to be expected that we need a title for every plot! time_plot_settings = ColoredPlotSettings( title="Trends Over Time", xlabel="Date", ylabel="Value", legend_title="Group" ) # Create the plot object plotter = TimeSeriesPlot(time_plot_settings) # Configure specific properties for this plot # again, note how different it is to change your mind; # the initial approach was to build a new car for every destination. # now, we have a generic car that is suitable for most situations, # we just need to handle the dashboard to configure our "roadtrip" plotter.set_marker('*') # Generate the plot with our data fig = plotter.plot( data=time_series_data, time_column="date", value_column="score", group_column="group" ) # We can now use the exact same structures for ANY kind of time series data, # not just loyalty scores or category plots! ``` -------------------------------- ### Creating and Activating a Virtual Environment Source: https://github.com/raoulg/codestyle/blob/main/docs/make_a_module.md Provides instructions for creating a Python virtual environment using the built-in `venv` module and activating it on both Windows and Unix-based systems. ```bash # From project root python -m venv .venv # Activate it # Windows .venv\Scripts\activate # Unix/MacOS source .venv/bin/activate ``` -------------------------------- ### Building Distribution Packages Source: https://github.com/raoulg/codestyle/blob/main/docs/make_a_module.md Provides commands to build distribution packages for a Python project using the `uv` tool. It shows how to build both a wheel and a source archive, or just a wheel. ```bash # Build wheel and sdist uv build # Build just the wheel uv build --wheel ``` -------------------------------- ### Path Joining with pathlib vs os.path Source: https://github.com/raoulg/codestyle/blob/main/docs/pathlib.md Demonstrates the more concise way to join path components using the '/' operator with pathlib compared to os.path.join. ```python import os filepath = os.path.join(os.path.expanduser("~"), "data", "file.txt") ``` ```python from pathlib import Path filepath = Path.home() / "data" / "file.txt" ``` -------------------------------- ### Data Folder Structure Examples Source: https://github.com/raoulg/codestyle/blob/main/docs/cookiecutter.md Illustrates two common approaches for organizing the 'data' directory to separate raw and processed data, or assets and artefacts. ```markdown ├── data/ │ ├── raw │ └── processed ``` ```markdown ├── data/ │ ├── assets │ └── artefacts ``` -------------------------------- ### Python Project Building with `pyproject.toml` Source: https://github.com/raoulg/codestyle/blob/main/docs/make_a_module.md Shows the basic structure of a `pyproject.toml` file used for configuring Python project builds, including specifying build backends and project metadata. ```toml [build-system] requires = ["setuptools", "wheel"] build-backend = "setuptools.build_meta" [project] name = "my_package" version = "0.1.0" description = "A sample Python package." authors = [ { name="Your Name", email="your.email@example.com" }, ] license = { file="LICENSE" } readme = "README.md" requires-python = ">=3.8" classifiers = [ "Programming Language :: Python :: 3", "License :: OSI Approved :: MIT License", "Operating System :: OS Independent", ] [project.urls] "Homepage" = "https://github.com/yourusername/my_package" "Bug Tracker" = "https://github.com/yourusername/my_package/issues" ``` -------------------------------- ### Installing Hypothesis for Property-Based Testing Source: https://github.com/raoulg/codestyle/blob/main/docs/testing.md Command to install the Hypothesis library, a powerful tool for property-based testing in Python that automatically generates test cases based on defined properties. ```bash uv install hypothesis ``` -------------------------------- ### Basic Python Package Structure Source: https://github.com/raoulg/codestyle/blob/main/docs/make_a_module.md Illustrates a recommended project structure for Python packages, featuring a `src` directory containing the main package, which aids in clear module naming and importability. ```text project/ |- src/ | |- mypackage/ | | |- __init__.py | | |- main.py |- .venv/ |- README.md |- pyproject.toml ``` -------------------------------- ### Install Dependencies with uv Source: https://github.com/raoulg/codestyle/blob/main/docs/dependencies_management.md Installs all packages and their dependencies specified in pyproject.toml and uv.lock. This command ensures that your project has the correct environment set up. ```bash uv sync ``` -------------------------------- ### Installing pytest-cov Source: https://github.com/raoulg/codestyle/blob/main/docs/testing.md Command to install the pytest-cov plugin, which is used for measuring code coverage during test execution in Python projects. ```bash uv install pytest-cov ``` -------------------------------- ### Git Command Line Basics Source: https://github.com/raoulg/codestyle/blob/main/docs/git_basics.md This section covers fundamental Git commands used for version control. It assumes basic familiarity with the command line and Git concepts. Examples include initializing repositories, staging changes, committing, and viewing history. ```bash git init git add . git commit -m "Initial commit" git status git log ``` -------------------------------- ### pyproject.toml Build System Configuration Source: https://github.com/raoulg/codestyle/blob/main/docs/make_a_module.md Specifies the build system requirements and backend for a Python project using `pyproject.toml`. It configures `hatchling` as the build backend and defines the packages to be included in the build targets. ```toml [build-system] requires = ["hatchling"] build-backend = "hatchling.build" [project] name = "mymodule" [tool.hatch.build.targets.wheel] packages = ["src/mymodule"] ``` -------------------------------- ### LoyaltyAnalyzer Class Initialization Source: https://github.com/raoulg/codestyle/blob/main/docs/abstract_code.md Initializes the LoyaltyAnalyzer with plot settings and loyalty settings. It demonstrates abstraction by using settings objects instead of hardcoded values for plot titles, labels, and loyalty-related configurations. ```python class LoyaltyAnalyzer: """Analyseert de loyaliteit van auteurs op basis van berichtenactiviteit.""" def __init__(self, settings: ColoredPlotSettings): # ABSTRACTION: Instead of hardcoding strings throughout the code, # we initialize settings objects that capture the concept of what # we're trying to do at a more abstract level self.plot_settings = settings # you could choose to add these settings too as an argument, # or you could add an additional method for setting or modifying these # def set_loyalty(settings : LoyaltySettings) etc. # this is dependend on your actual usecase self.loyalty_settings = LoyaltySettings() # ... other initialization ... ``` -------------------------------- ### Basic Typehinting Example Source: https://github.com/raoulg/codestyle/blob/main/docs/typehinting.md Demonstrates the difference between code without and with type hints. Type hints improve code readability and allow static analysis tools like mypy to catch type errors. ```python def impute( df, group_cols, metric = "mean" ): ... ``` ```python from typing import List import pandas as pd def impute( df: pd.DataFrame, group_cols: List[str], metric: str = "mean" ) -> pd.DataFrame: ... ``` -------------------------------- ### Trunk Based Git Development Workflow Example Source: https://github.com/raoulg/codestyle/blob/main/docs/trunk_based_git.md Demonstrates the typical commands used in Scaled Trunk Based Git Development, including creating a feature branch, making commits, pushing to remote, and merging into the main branch. ```bash git checkout -b feature/my-feature # Make changes to the code git commit -m "Implement feature XYZ" git push origin feature/my-feature # send out pull request to others in your team for review # Once the feature is ready, merge it into the trunk branch git checkout main git merge feature/my-feature # Push the changes to the remote trunk branch git push origin main ``` -------------------------------- ### Globbing Files with pathlib Source: https://github.com/raoulg/codestyle/blob/main/docs/pathlib.md Shows how to use pathlib's `glob` method to find files matching a pattern, such as all .txt files in the home directory. ```python from pathlib import Path for filepath in Path.home().glob("*.txt"): print(filepath) ``` -------------------------------- ### Python Import Best Practices Source: https://github.com/raoulg/codestyle/blob/main/docs/make_a_module.md Demonstrates preferred methods for importing modules and specific objects in Python, emphasizing absolute imports over relative ones and importing specific names rather than using wildcard imports. ```python # Absolute import (preferred over relative) from mymodule.utils import helper_function # Relative import (from same directory) from .utils import helper_function # Import specific functions (always preferred over 'import *') from mymodule.constants import ( DEFAULT_TIMEOUT, MAX_RETRIES, ) ``` -------------------------------- ### Running Python Scripts Directly Source: https://github.com/raoulg/codestyle/blob/main/docs/make_a_module.md Illustrates the method of executing a Python script directly from the project root using the `python` interpreter. It also highlights a common pitfall that can lead to import errors. ```bash # From project root python src/mymodule/main.py # This breaks imports! # cd src/mymodule # python main.py ``` -------------------------------- ### Install uv Python Version Manager Source: https://github.com/raoulg/codestyle/blob/main/docs/version_management.md Installs the uv Python version manager using a bash script. This is the recommended tool for managing Python versions and dependencies. ```bash curl -LsSf https://astral.sh/uv/install.sh | sh ``` -------------------------------- ### Project Directory Structure Source: https://github.com/raoulg/codestyle/blob/main/docs/make_a_module.md Illustrates a typical Python project layout with directories for source code (`src`), tests (`tests`), and virtual environments (`.venv`). It highlights the organization within the source directory for main application logic and utility modules. ```tree project/ |- src/ | |- myapp/ | | |- __init__.py | | |- main.py | | |- utils/ | | | |- __init__.py | | | |- filehandler.py | | | |- preprocessing.py |- tests/ | |- test_main.py |- .venv/ |- README.md |- pyproject.toml ``` -------------------------------- ### Python Package Initialization Source: https://github.com/raoulg/codestyle/blob/main/docs/make_a_module.md The __init__.py file designates a directory as a Python package. It can be used to define package-level variables like __version__ or to explicitly expose certain functions or classes from submodules. ```python # src/mymodule/__init__.py from mymodule.main import some_function # Explicitly declare public API __version__ = "0.1.0" # now people can run mymodule.__version__ to check the version ``` -------------------------------- ### Specifying Dependencies in pyproject.toml Source: https://github.com/raoulg/codestyle/blob/main/docs/dependencies_management.md This example shows how to declare project dependencies and their version constraints within a pyproject.toml file. It highlights the specification of the pandas package version. ```toml dependencies = [ "scikit-learn>=1.3.0", "pandas>=2.0.3", <--- this line specifies the pandas version "jupyter>=1.0.0", "numpy>=1.24.4", "datascience-cookiecutter>=0.3.3", ] ``` -------------------------------- ### pyproject.toml Configuration Source: https://github.com/raoulg/codestyle/blob/main/docs/make_a_module.md pyproject.toml is used in modern Python projects for build system requirements, project metadata, and build configurations, adhering to PEP 631. It specifies project name, version, dependencies, and build targets. ```toml [project] name = "mymodule" version = "0.1.0" description = "My Python module" requires-python = ">=3.11" dependencies = [ "requests>=3.38.0", ] [build-system] requires = ["hatchling"] build-backend = "hatchling.build" [tool.hatch.build.targets.wheel] packages = ["src/mymodule"] [project.scripts] mymodule = "mymodule.main:main" ``` -------------------------------- ### ColoredPlotSettings Initialization Source: https://github.com/raoulg/codestyle/blob/main/docs/abstract_code.md Initializes `ColoredPlotSettings` with parameters for plot customization, including title, axis labels, and legend title. This object centralizes plot configuration. ```python settings = ColoredPlotSettings( title="Loyalty Score per Author", xlabel="Author", ylabel="Loyalty Score", legend_title="Loyalty Categorie" ) ``` -------------------------------- ### Pytest Fixture Cleanup with Yield Source: https://github.com/raoulg/codestyle/blob/main/docs/testing.md Illustrates how to perform cleanup actions after a test using the `yield` statement within a fixture. The code before `yield` is setup, and the code after `yield` is teardown. ```python @pytest.fixture def database_connection(): # Setup conn = connect_to_database() yield conn # Provide the resource to the test # Cleanup (executed after the test completes) conn.close() ``` -------------------------------- ### pytest Fixture Example Source: https://github.com/raoulg/codestyle/blob/main/docs/testing.md Demonstrates how to define and use fixtures in pytest for providing test data. The `sample_data` fixture creates a pandas DataFrame, which can then be injected as a parameter into test functions, promoting code reuse and cleaner tests. ```python @pytest.fixture def sample_data(): """Provide sample DataFrame for tests.""" return pd.DataFrame({'A': [1, 2, 3], 'B': ['a', 'b', 'c']}) def test_save_and_load(tmp_path, sample_data): # The sample_data fixture is automatically passed to this test handler = CSVHandler(str(tmp_path / "test.csv")) handler.save(sample_data) # Rest of the test... ``` -------------------------------- ### Python Script Execution (`__name__ == '__main__')` Source: https://github.com/raoulg/codestyle/blob/main/docs/make_a_module.md Demonstrates the common Python idiom `if __name__ == '__main__'` which allows a script to be executed directly or imported as a module without running the main execution block. ```python def main(): print("This is the main function.") if __name__ == "__main__": main() ``` -------------------------------- ### Pytest Fixture Example: Temporary Directory Source: https://github.com/raoulg/codestyle/blob/main/docs/testing.md Illustrates how to use pytest's built-in `tmp_path` fixture to create and manage temporary directories for tests. This is useful for tests that need to read from or write to the file system without affecting the actual project structure. ```python import pytest def test_create_file_in_temp_dir(tmp_path): # tmp_path is a pathlib.Path object representing a temporary directory file_path = tmp_path / "my_test_file.txt" file_path.write_text("Hello, pytest!") assert file_path.read_text() == "Hello, pytest!" assert file_path.exists() ``` -------------------------------- ### Load CSV Data from URL with Mocking Source: https://github.com/raoulg/codestyle/blob/main/docs/testing.md Demonstrates how to load CSV data from a URL using requests and pandas, and how to test this functionality without making actual network requests by mocking the 'requests.get' function. It includes setup for the mock response and assertions to verify the data parsing and function calls. ```python import requests import pandas as pd import io from unittest.mock import patch, Mock class CSVHandler: def load_from_url(self, url): """Load CSV data from a URL.""" response = requests.get(url) response.raise_for_status() # Raise exception for HTTP errors self.data = pd.read_csv(io.StringIO(response.text)) return self.data @patch('requests.get') def test_load_from_url(mock_get): """Test loading CSV data from a URL without making actual requests.""" # Create a mock response mock_response = Mock() mock_response.text = "A,B\n1,a\n2,b\n3,c" mock_response.raise_for_status = Mock() # Mock the raise_for_status method # Configure the mock get function to return our mock response mock_get.return_value = mock_response # Create our handler and call load_from_url handler = CSVHandler() data = handler.load_from_url("https://example.com/data.csv") # Verify requests.get was called with the correct URL mock_get.assert_called_once_with("https://example.com/data.csv") # Verify the data was correctly parsed assert len(data) == 3 assert list(data.columns) == ['A', 'B'] ``` -------------------------------- ### Testing CSVHandler in a Notebook Source: https://github.com/raoulg/codestyle/blob/main/docs/testing.md An example of how to test the CSVHandler class within a Jupyter notebook. This approach demonstrates basic saving and loading functionality and includes an assertion for data verification. It also points out the difficulty in systematically testing edge cases within a notebook environment. ```python # In a Jupyter notebook import pandas as pd from csv_handler import CSVHandler # Create test data test_data = pd.DataFrame({'A': [1, 2, 3], 'B': ['a', 'b', 'c']}) # Test saving handler = CSVHandler('test.csv') handler.save(test_data) print("Save successful") # Test loading loaded_data = handler.load() print("Load successful") print(loaded_data) # Check if data is the same assert test_data.equals(loaded_data), "Data doesn't match!" print("Data verification successful") # What about edge cases? What if the file doesn't exist? # What if the data is empty? # What if the filepath is None? # Hard to systematically test all these cases in a notebook ``` -------------------------------- ### Pydantic Settings Models for Plotting Source: https://github.com/raoulg/codestyle/blob/main/docs/abstract_code.md Defines base and extended settings models for plotting using Pydantic. `PlotSettings` includes common plot attributes like title, labels, and figure size. `ColoredPlotSettings` extends `PlotSettings` by adding a `color_palette` attribute. ```Python from pydantic import BaseModel from typing import List, Optional import pandas as pd import matplotlib.pyplot as plt import seaborn as sns # First, lets think about what EVERY plot needs class PlotSettings(BaseModel): """Base settings for plotting.""" title: str = "" xlabel: str = "" ylabel: str = "" figsize: tuple = (10, 6) rotation: int = 0 legend_title: Optional[str] = None # then, we can extend the settings with additional conig. # this inherits everything from PlotSettings, plus a color_palette class ColoredPlotSettings(PlotSettings): """Settings for plots with color palettes.""" color_palette: str = "coolwarm" ``` -------------------------------- ### TimeSeriesPlot Implementation Source: https://github.com/raoulg/codestyle/blob/main/docs/abstract_code.md Defines a TimeSeriesPlot class that inherits from BasePlot, allowing for custom marker styles and plotting data over time. It reuses base plot functionalities like figure and axes setup. ```python class TimeSeriesPlot(BasePlot): """Plot for showing data over time.""" def __init__(self, settings: ColoredPlotSettings): super().__init__(settings) # lets say we want to add something new to the defaults self.marker = 'o' # Default marker style def set_marker(self, marker: str): """Set the marker style for data points.""" # make it eaiser to change, because it is not directly in the general settings self.marker = marker return self def plot(self, data: pd.DataFrame, time_column: str, value_column: str, group_column: str): self.create_figure() # REUSE: We've already set up the figure, labels, and title in BasePlot! # Now we just need to add the specific visualization # Create a different type of visualization for name, group in data.groupby(group_column): self.ax.plot( group[time_column], group[value_column], marker=self.marker, label=name ) return self.fig ``` -------------------------------- ### Extracting Filename Stem and Suffix Source: https://github.com/raoulg/codestyle/blob/main/docs/pathlib.md Illustrates how pathlib's `.stem` and `.suffix` attributes provide a direct way to get the filename without extension and the extension, respectively, simplifying operations that were more verbose with os.path. ```python import os filepath_str = "/path/to/some/file.txt" basefile = os.path.splitext(os.path.basename(filepath_str))[0] suffix = os.path.splitext(os.path.basename(filepath_str))[-1] ``` ```python from pathlib import Path filepath = Path("/path/to/some/file.txt") basefile = filepath.stem suffix = filepath.suffix ``` -------------------------------- ### Initializing a New Project with uv Source: https://github.com/raoulg/codestyle/blob/main/docs/dependencies_management.md Command to create a new virtual environment and a pyproject.toml file for a project if one does not already exist. This sets up the project for uv-managed dependencies. ```bash uv init ``` -------------------------------- ### Specialized Colored Bar Plot Class Source: https://github.com/raoulg/codestyle/blob/main/docs/abstract_code.md Extends the `BasePlot` class to create a specialized bar plot. It adds functionality for setting x-axis label rotation and utilizes the parent class's `create_figure` method for base plot setup. This demonstrates inheritance for code reuse and specialization. ```python import seaborn as sns import matplotlib.pyplot as plt import pandas as pd from typing import Optional # Assuming BasePlot, PlotSettings, and ColoredPlotSettings are defined # class PlotSettings: # def __init__(self, figsize=(10, 6), xlabel='', ylabel='', title='', legend_title=None): # self.figsize = figsize # self.xlabel = xlabel # self.ylabel = ylabel # self.title = title # self.legend_title = legend_title # class ColoredPlotSettings(PlotSettings): # def __init__(self, figsize=(10, 6), xlabel='', ylabel='', title='', legend_title=None, color_palette='viridis'): # super().__init__(figsize, xlabel, ylabel, title, legend_title) # self.color_palette = color_palette # class BasePlot: # """Base class for creating plots.""" # def __init__(self, settings: 'PlotSettings'): # self.settings = settings # self.fig = None # self.ax = None # # def create_figure(self): # """Create a figure and configure it based on settings.""" # self.fig, self.ax = plt.subplots(figsize=self.settings.figsize) # self.ax.set_xlabel(self.settings.xlabel) # self.ax.set_ylabel(self.settings.ylabel) # self.ax.set_title(self.settings.title) # if self.settings.legend_title is not None: # self.ax.legend(title=self.settings.legend_title) # plt.tight_layout() # return self.fig, self.ax # # def get_figure(self): # """Return the figure, creating it if needed.""" # if self.fig is None: # self.create_figure() # return self.fig class ColoredBarPlot(BasePlot): """Bar plot that extends BasePlot with color options.""" def __init__(self, settings: 'ColoredPlotSettings'): super().__init__(settings) # we pass the settings to the BasePlot self.rotation = 0 # We add a default rotation value def set_rotation(self, rotation: int): """Set the rotation for x-axis labels.""" # however, we make it easy to modify this later on # this is a good idea if you expect this setting needs # a lot of modification later on for different cases self.rotation = rotation return self def plot(self, data: pd.DataFrame, x_column: str, y_column: str, hue_column: Optional[str] = None): """Create a bar plot using the provided data and settings.""" # this uses the BasePlot basic figure, creating the baseplot self.create_figure() # IMPROVEMENT: We leverage inheritance here - all the base plot settings # are already applied by the parent class's create_figure method! # IMPROVEMENT: in the base class we don't hardcode the plot type either - # by creating a specialized class, we can easily make # other plot types without duplicating much code sns.barplot( data=data, x=x_column, y=y_column, hue=hue_column, palette=self.settings.color_palette, ax=self.ax ) # Apply rotation (specific to this plot type) plt.xticks(rotation=self.rotation) return self.fig ``` -------------------------------- ### Traditional Test for Addition Commutativity Source: https://github.com/raoulg/codestyle/blob/main/docs/testing.md A traditional testing approach for the commutativity property of addition (a + b = b + a). This method tests only a few specific examples. ```python def test_addition_commutative_traditional(): calc = Calculator() # Test a few specific examples assert calc.add(2, 3) == calc.add(3, 2) assert calc.add(0, 5) == calc.add(5, 0) assert calc.add(-1, 7) == calc.add(7, -1) ``` -------------------------------- ### Checking File Existence with pathlib Source: https://github.com/raoulg/codestyle/blob/main/docs/pathlib.md Demonstrates the straightforward method of checking if a path exists using pathlib's `.exists()` method. ```python from pathlib import Path path = Path("path/to/file.txt") if not path.exists(): print(f"File {path} does not exist!") ``` -------------------------------- ### Pydantic Field Validation Source: https://github.com/raoulg/codestyle/blob/main/docs/pydantic.md Extending Pydantic models with custom validation logic using the `@field_validator` decorator. This example demonstrates checking if a provided directory path exists. ```python from pydantic import BaseModel, field_validator from typing import Optional from pathlib import Path class SearchSpace(BaseModel): input_size: int output_size: int tune_dir: Optional[Path] data_dir: Path @field_validator('data_dir') @classmethod def check_path(cls, v: Path) -> Path: if not v.exists(): raise FileNotFoundError( f"Make sure the datadir exists.\n Found {v} to be non-existing." ) return v ``` -------------------------------- ### Execute Python Script Source: https://github.com/raoulg/codestyle/blob/main/docs/dependencies_management.md Demonstrates two ways to execute a Python script: directly using the Python interpreter after activating the virtual environment, or using `uv run` which handles environment activation automatically. ```bash # Direct execution python script.py # Using uv run uv run python script.py ``` -------------------------------- ### Resolving ModuleNotFoundError Source: https://github.com/raoulg/codestyle/blob/main/docs/make_a_module.md Provides common causes and solutions for the `ModuleNotFoundError` in Python, such as incorrect execution directory, missing `__init__.py` files, or an unactivated virtual environment. ```bash cd /path/to/myproject # Always run from project root source .venv/bin/activate # make sure your .venv is activated python -m mymodule.main # only if you havent built the package; see section `building your project` ``` -------------------------------- ### Development vs. Source Code Structure Source: https://github.com/raoulg/codestyle/blob/main/docs/cookiecutter.md Demonstrates a project structure that separates exploratory code in a 'dev' folder (including notebooks and scripts) from reusable source code in an 'src' folder. ```markdown ├── dev/ | ├── notebooks | └── scripts ├── src/ │ ├── __init__.py │ └── main.py ``` -------------------------------- ### Makefile for Linting and Formatting Source: https://github.com/raoulg/codestyle/blob/main/docs/linting.md A Makefile to automate code formatting using isort and Black, and linting using Ruff and Pyright. It allows running `make format` for formatting and `make lint` for checking code quality. ```makefile .PHONY: lint format format: isort -v src black src lint: ruff check src --fix pyright src ``` -------------------------------- ### Basic Configuration Dictionary Source: https://github.com/raoulg/codestyle/blob/main/docs/pydantic.md A simple Python dictionary to store configuration parameters. Suitable for small projects or initial prototyping, but lacks type checking and validation. ```python config = {"input_size": 3, "output_size": 20, "data_dir": "."} ``` -------------------------------- ### Class with Initializer and Method Source: https://github.com/raoulg/codestyle/blob/main/docs/use_classes_and_inheritance.md Demonstrates a Python class with an `__init__` method that sets an attribute and a method to interact with that attribute. It shows creating multiple instances with different states. ```python class Lion: def __init__(self, food: str) -> None: self.food = food def give_food(self): print(f"The lion eats the {self.food}") alex = Lion(food="steak") fred = Lion(food="ham") print(alex.food, fred.food) ``` -------------------------------- ### VS Code Git Integration Overview Source: https://github.com/raoulg/codestyle/blob/main/docs/git_basics.md Demonstrates how to leverage the graphical user interface (GUI) in Visual Studio Code for Git operations. It highlights the advantages of using VS Code's built-in Git features and popular extensions like GitLens and GitGraph for enhanced version control management. ```javascript // VS Code Git GUI operations (conceptual) // Stage changes: Click '+' icon next to files // Commit changes: Enter message in input box, click 'Commit' // Push changes: Click '...' menu, select 'Push' ``` -------------------------------- ### Pytest Basics: Setting Up a Tests Folder Source: https://github.com/raoulg/codestyle/blob/main/docs/testing.md Demonstrates the standard convention for organizing test files and directories when using pytest. Pytest automatically discovers tests in files named `test_*.py` or `*_test.py` within a `tests` directory. ```python project_root/ ├── src/ │ └── my_module.py └── tests/ ├── __init__.py └── test_my_module.py ``` -------------------------------- ### Basic Loguru Logging Source: https://github.com/raoulg/codestyle/blob/main/docs/loguru.md Demonstrates the fundamental usage of Loguru for logging informational messages. It shows how to import the logger and log a simple message to standard error by default. ```python from loguru import logger logger.info("That's it!") ``` -------------------------------- ### Custom __init__ Method Source: https://github.com/raoulg/codestyle/blob/main/docs/use_classes_and_inheritance.md Illustrates how to define a custom `__init__` method in a Python class to initialize instance attributes. It also shows how to add methods to the class. ```python class Lion: def __init__(self, food: str) -> None: self.food = food def give_food(self): print(f"The lion eats the {self.food}") leeuw = Lion(food="steak") leeuw.give_food() ``` -------------------------------- ### Calculate Loyalty Scores Source: https://github.com/raoulg/codestyle/blob/main/docs/abstract_code.md Calculates loyalty scores for authors by grouping data and aggregating message counts and timestamps. It utilizes settings for column names and category definitions, promoting maintainability and reducing hardcoding. ```python def calculate_loyalty(self): """Calculate loyalty scores without hardcoding.""" # ... calculation code ... # ABSTRACTION: We reference column names from settings instead of hardcoding! # This means we can change a column name in ONE place # rather than hunting for all occurrences in the code! self.author_stats = self.df.groupby(self.loyalty_settings.author_column).agg( message_count=(self.loyalty_settings.message_column, "count"), first_message=(self.loyalty_settings.timestamp_column, "min"), last_message=(self.loyalty_settings.timestamp_column, "max") ).reset_index() # ABSTRACTION: Categories are now defined as a concept # rather than as literal strings scattered throughout the code self.author_stats["loyalty_category"] = pd.qcut( self.author_stats["loyalty_score"], # note how the value of q was hardcoded before # now, it is inferred automatically! q=self.loyalty_settings.num_categories, labels=self.loyalty_settings.categories ) ``` -------------------------------- ### Git Workflows: GitFlow Overview Source: https://github.com/raoulg/codestyle/blob/main/docs/git_basics.md Provides a brief overview of the GitFlow branching model, a more complex but structured workflow often used in larger development teams. It outlines the main branches (master, develop) and supporting branches (feature, release, hotfix). ```bash # GitFlow conceptual commands # Start a new feature git flow feature start my-feature # Finish a feature git flow feature finish my-feature # Start a release git flow release start 1.0.0 # Finish a release git flow release finish 1.0.0 ``` -------------------------------- ### Python Virtual Environment Creation and Activation Source: https://github.com/raoulg/codestyle/blob/main/docs/dependencies_management.md Commands to create a Python virtual environment using the 'venv' module and activate it on different operating systems (Linux/macOS and Windows). ```bash python -m venv .venv source .venv/bin/activate ``` ```powershell .\.venv\Scripts\activate ..venv\Scripts\Activate.ps1 ``` -------------------------------- ### BabyLion Class Inheriting from Lion Source: https://github.com/raoulg/codestyle/blob/main/docs/use_classes_and_inheritance.md Shows how to create a BabyLion class that inherits from the Lion class. This demonstrates extending functionality by adding a new 'pet' method while retaining all methods from the parent Lion class. Includes example usage. ```python class BabyLion(Lion): def pet(self): print("miauw") simba = BabyLion(food = ["biefstuk"], time = 11) simba.give_food() # Output: The lion enjoys 1 items simba.ideal_feeding_time() # Output: 11 simba.pet() # Output: miauw ``` -------------------------------- ### Python Script Execution Guard Source: https://github.com/raoulg/codestyle/blob/main/docs/make_a_module.md The `if __name__ == '__main__':` block allows code to be executed only when the script is run directly, not when it's imported as a module. This is useful for testing or providing a direct entry point for script execution. ```python # src/mymodule/main.py def main(): print("Hello World") if __name__ == '__main__': main() ``` -------------------------------- ### Using conftest Fixtures in Tests Source: https://github.com/raoulg/codestyle/blob/main/docs/testing.md Demonstrates how to use fixtures defined in conftest.py within test files without explicit imports. Shows accessing sample data and test configuration. ```python # tests/test_csv_handler.py def test_save_functionality(tmp_path, csv_handler, sample_data): # Use fixtures from conftest.py without imports filepath = tmp_path / "test.csv" csv_handler.save(sample_data, str(filepath)) assert os.path.exists(filepath) # tests/test_advanced_features.py def test_encoding_handling(csv_handler, test_config): # Use the same fixtures in different test files assert csv_handler.default_encoding == test_config["default_encoding"] ```