Skip to content

Commit 2bca5e2

Browse files
committed
documentation #37: add all documentation
1 parent 143959e commit 2bca5e2

File tree

9 files changed

+199
-17
lines changed

9 files changed

+199
-17
lines changed

README.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,10 @@ Then, if all tests are sucessful:
150150
The documentation is generated with [pdoc](https://pdoc.dev), automatically with the CI. To generate it locally you can run:
151151

152152
```
153-
pdoc example --output-dir docs --logo https://www.pollen-robotics.com/wp-content/themes/bambi-theme-main/assets/images/pollen_robotics_logo.webp --logo-link https://www.pollen-robotics.com
153+
pdoc example --output-dir docs --logo https://www.pollen-robotics.com/wp-content/themes/bambi-theme-main/assets/images/pollen_robotics_logo.webp --logo-link https://www.pollen-robotics.com --docformat google
154+
```
154155

156+
The documentation relies on the provided docstings with the google style. [pydocstyle](http://www.pydocstyle.org/en/stable/) is used to enforced this style.
157+
```
158+
pydocstyle src/ --convention google --count
155159
```

setup.cfg

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ dev = black==24.10.0
3333
mypy==1.8.0
3434
isort==5.13.2
3535
pdoc==14.7.0
36+
pydocstyle==6.3.0
3637

3738
[options.entry_points]
3839
console_scripts =

src/config_files/__init__.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
"""config_files module.
2+
3+
Contains example of config files that are accessible by the modules.
4+
"""

src/example/__init__.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
"""Example module.
2+
3+
Illustrates various use cases.
4+
"""

src/example/cam_config.py

Lines changed: 51 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,50 @@
1+
"""Camera Configuration Management.
2+
3+
This module provides classes and functions for managing camera configuration data stored in JSON
4+
files. It includes a class for reading and displaying camera configuration data, as well as
5+
functions for retrieving the names of available configuration files and their paths.
6+
"""
7+
18
import json
29
from importlib.resources import files
310
from typing import Any, List
411

512

613
class CamConfig:
7-
def __init__(
8-
self,
9-
cam_config_json: str,
10-
) -> None:
14+
"""A class to manage camera configuration data from a JSON file.
15+
16+
This class reads a JSON file containing camera configuration data and provides methods to
17+
access and display the information.
18+
19+
Attributes:
20+
cam_config_json (str): The path to the JSON file containing the camera configuration data.
21+
socket_to_name (dict): A dictionary mapping socket IDs to camera names.
22+
inverted (bool): A boolean indicating whether the camera is inverted.
23+
fisheye (bool): A boolean indicating whether the camera is a fisheye camera.
24+
mono (bool): A boolean indicating whether the camera is a monochrome camera.
25+
"""
26+
27+
def __init__(self, cam_config_json: str) -> None:
28+
"""Initialize the camera configuration data from the given JSON file.
29+
30+
Args:
31+
cam_config_json (str): The path to the JSON file containing the camera configuration data.
32+
"""
1133
self.cam_config_json = cam_config_json
1234

13-
config = json.load(open(self.cam_config_json, "rb"))
14-
self.socket_to_name = config["socket_to_name"]
15-
self.inverted = config["inverted"]
16-
self.fisheye = config["fisheye"]
17-
self.mono = config["mono"]
35+
with open(self.cam_config_json, "rb") as f:
36+
config = json.load(f)
37+
self.socket_to_name = config["socket_to_name"]
38+
self.inverted = config["inverted"]
39+
self.fisheye = config["fisheye"]
40+
self.mono = config["mono"]
1841

1942
def to_string(self) -> str:
43+
"""Return a string representation of the camera configuration data.
44+
45+
Returns:
46+
str: A string containing the camera configuration data in a human-readable format.
47+
"""
2048
ret_string = "Camera Config: \n"
2149
ret_string += "Inverted: {}\n".format(self.inverted)
2250
ret_string += "Fisheye: {}\n".format(self.fisheye)
@@ -26,11 +54,25 @@ def to_string(self) -> str:
2654

2755

2856
def get_config_files_names() -> List[str]:
57+
"""Return a list of the names of the JSON configuration files in the config_files package.
58+
59+
Returns:
60+
List[str]: A list of the names of the JSON configuration files in the config_files package.
61+
"""
2962
path = files("config_files")
3063
return [file.stem for file in path.glob("**/*.json")] # type: ignore[attr-defined]
3164

3265

3366
def get_config_file_path(name: str) -> Any:
67+
"""Return the path to the JSON configuration file with the given name in the config_files package.
68+
69+
Args:
70+
name (str): The name of the JSON configuration file.
71+
72+
Returns:
73+
Any: The path to the JSON configuration file with the given name in the config_files package.
74+
If the file is not found, returns None.
75+
"""
3476
path = files("config_files")
3577
for file in path.glob("**/*"): # type: ignore[attr-defined]
3678
if file.stem == name:

src/example/celcius.py

Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,81 @@
1+
"""Celsius Temperature Conversion and Management.
2+
3+
This module provides a class for managing Celsius temperatures and converting them to Fahrenheit.
4+
It also includes a main function that demonstrates the usage of the class.
5+
"""
6+
17
import logging
28

39

410
class Celsius:
5-
"""Manage celcius temperature and other format."""
11+
"""A class to manage Celsius temperature and convert it to other formats.
12+
13+
This class provides a way to store and manipulate Celsius temperatures, as well as convert
14+
them to Fahrenheit. It also includes a check to ensure that the temperature is not below
15+
absolute zero (-273.15°C).
16+
17+
Attributes:
18+
_temperature (float): The current temperature in Celsius.
19+
"""
620

721
def __init__(self, temperature: float = 0):
22+
"""Initialize the logger and the temperature attribute.
23+
24+
Args:
25+
temperature (float, optional): The initial temperature in Celsius. Defaults to 0.
26+
"""
827
self._logger = logging.getLogger(__name__)
928
self._temperature = temperature
1029

1130
def to_fahrenheit(self) -> float:
31+
"""Convert the current temperature from Celsius to Fahrenheit.
32+
33+
Returns:
34+
float: The temperature in Fahrenheit.
35+
"""
1236
return (self._temperature * 1.8) + 32
1337

1438
@property
1539
def temperature(self) -> float:
40+
"""A property decorator that allows access to the temperature attribute.
41+
42+
This property decorator provides a way to access the temperature attribute from outside
43+
the class. It also logs a message indicating that the value is being retrieved.
44+
45+
Returns:
46+
float: The current temperature in Celsius.
47+
"""
1648
self._logger.info("Getting value...")
1749
return self._temperature
1850

1951
@temperature.setter
2052
def temperature(self, value: float) -> None:
53+
"""A setter for the temperature property.
54+
55+
This method allows the value of the temperature attribute to be changed from outside the
56+
class. It also logs a message indicating that the value is being set and checks that the
57+
temperature is not below absolute zero.
58+
59+
Args:
60+
value (float): The new temperature in Celsius.
61+
62+
Raises:
63+
ValueError: If the temperature is below -273.15°C.
64+
"""
2165
self._logger.info("Setting value...")
2266
if value < -273.15:
2367
raise ValueError("Temperature below -273 is not possible")
2468
self._temperature = value
2569

2670

2771
def main() -> None:
72+
"""The main function that demonstrates the usage of the Celsius class.
73+
74+
This function creates an instance of the Celsius class, sets its temperature, and prints
75+
the equivalent temperature in Fahrenheit. It also activates logging at the INFO level.
76+
"""
77+
logging.basicConfig(level=logging.INFO)
78+
2879
print("Test entry point")
2980
temp = Celsius(37)
3081
temp.temperature = -30

src/example/foo.py

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,24 +5,43 @@
55

66

77
class Foo:
8-
"""This is a template class"""
8+
"""This is a template class."""
99

1010
def __init__(self) -> None:
11-
"""Set up empty slots."""
11+
"""Set up empty slots and initialize the logger and private variable.
12+
13+
This method is called when an object of the class is created. It sets up the logger and
14+
initializes the private variable.
15+
"""
1216
self._logger = logging.getLogger(__name__)
1317
self._logger.info("Constructor")
1418
self._private_variable = "private"
1519
self.public_variable = "public"
1620

1721
@property
1822
def private_variable(self) -> str:
23+
"""A property decorator that allows access to the private variable.
24+
25+
This property decorator provides a way to access the private variable from outside
26+
the class. It returns the value of the private variable.
27+
"""
1928
return self._private_variable
2029

2130
@private_variable.setter
2231
def private_variable(self, value: str) -> None:
32+
"""A setter for the private_variable property.
33+
34+
This method allows the value of the private variable to be changed from outside the
35+
class. It sets the value of the private variable to the provided argument.
36+
"""
2337
self._private_variable = value
2438

2539
def __del__(self) -> None:
40+
"""The destructor method called when the object is about to be destroyed.
41+
42+
This method is called when an object of the class is about to be destroyed. It logs a
43+
message indicating that the destructor has been called.
44+
"""
2645
self._logger.info("Destructor")
2746

2847
@overload
@@ -32,6 +51,12 @@ def doingstuffs(self, var: int, var2: float) -> None: ...
3251
def doingstuffs(self, var: int) -> None: ...
3352

3453
def doingstuffs(self, var: Any = None, var2: Any = None) -> None:
54+
"""An overloaded method that takes one or two arguments and logs their values and types.
55+
56+
This method demonstrates the use of overloading in Python. It takes one or two arguments
57+
and logs their values and types using the logger. If no arguments are provided, it does
58+
nothing.
59+
"""
3560
if var is not None:
3661
self._logger.info(f"{var} {type(var)} ")
3762
if var2 is not None:

src/example/xterrabot.py

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,31 @@
1+
"""XTerraBot.
2+
3+
Illustrate Maths notation based on
4+
https://www.mecharithm.com/
5+
homogenous-transformation-matrices-configurations-in-robotics/.
6+
"""
7+
18
import logging
29

310
import numpy as np
411
import numpy.typing as npt
512

613

714
class XTerraBot:
8-
"""Illustrate Maths notation based on
9-
https://www.mecharithm.com/
10-
homogenous-transformation-matrices-configurations-in-robotics/."""
15+
"""XTerraBot class.
16+
17+
This class illustrates the use of homogeneous transformation matrices to represent the
18+
configuration of a robot in the context of robotics. It demonstrates the calculation of
19+
the transformation matrix of an object with respect to the gripper frame using matrix
20+
multiplication and inversion.
21+
"""
1122

1223
def __init__(self) -> None:
24+
"""Constructor.
25+
26+
Initialize the logger and the homogeneous transformation matrices representing the
27+
configuration of the robot.
28+
"""
1329
self._logger = logging.getLogger(__name__)
1430
# b is the mobile base
1531
# d is the camera
@@ -27,6 +43,19 @@ def __init__(self) -> None:
2743
self._T_a_d = np.array([[0, 0, -1, 400], [0, -1, 0, 50], [-1, 0, 0, 300], [0, 0, 0, 1]]) # a is the root
2844

2945
def get_object_in_gripper_frame(self) -> npt.NDArray[np.float64]:
46+
"""Get the object in the gripper frame.
47+
48+
Calculate and return the homogeneous transformation matrix representing the
49+
configuration of the object with respect to the gripper frame.
50+
51+
This method calculates the transformation matrix (T_c_e) by performing matrix
52+
multiplication and inversion on the given transformation matrices. It returns the
53+
resulting matrix as a NumPy array.
54+
55+
Returns:
56+
np.ndarray: The homogeneous transformation matrix representing the configuration
57+
of the object with respect to the gripper frame.
58+
"""
3059
T_c_e = (
3160
np.linalg.inv(self._T_b_c)
3261
@ np.linalg.inv(self._T_d_b)

src/main.py

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,12 @@
1+
"""Main script for the application.
2+
3+
This script processes command-line arguments, performs various operations using classes and
4+
methods from the `example` module, and uses data stored in configuration files. It logs
5+
information about the provided arguments and demonstrates the usage of the application's
6+
features.
7+
8+
"""
9+
110
import argparse
211
import logging
312
import sys
@@ -8,8 +17,21 @@
817
from example.xterrabot import XTerraBot
918

1019

11-
# the main function could be called from somewhere else
1220
def main(args: argparse.Namespace) -> int:
21+
"""The main function that processes command-line arguments and performs various operations.
22+
23+
This function logs information about the provided arguments, demonstrates the usage of
24+
classes and methods from the example module, and uses data stored in configuration
25+
files. It returns 0 to indicate successful execution.
26+
27+
Args:
28+
args (argparse.Namespace): The namespace containing the command-line arguments.
29+
30+
Returns:
31+
int: Exit code indicating the success (0) of the application.
32+
33+
34+
"""
1335
logging.info("str param: {}".format(args.str_param))
1436
logging.info("bool param: {}".format(args.bool_param))
1537
logging.info("int param: {}".format(args.int_param))

0 commit comments

Comments
 (0)