From 00839eb071f8b457a48c5a9b08c7170f61aeecff Mon Sep 17 00:00:00 2001 From: ChunelFeng Date: Mon, 5 May 2025 16:19:25 +0800 Subject: [PATCH] [doc] add code style doc, change english readme --- CODE_OF_CONDUCT.md | 154 +++++++++++++++++++++++++++++++++++++++++++++ README.md | 3 + README_en.md | 120 ++++++++++++++++------------------- 3 files changed, 212 insertions(+), 65 deletions(-) create mode 100644 CODE_OF_CONDUCT.md diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 00000000..f4e8aa93 --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,154 @@ + +# CGraph Code of Conduct + +## Coding Guidelines + +### C++ +Please ensure your code follows the CGraph coding guidelines. Consistent coding style helps maintain the codebase. + +Based on Google style guide, with some differences(perhaps): + +- Function naming: First letter lowercase, camelCase + ``` + int getCode() { + return 0; + } + ``` + +- Class and struct naming: First letter uppercase, camelCase + ``` + class MyClass { + } + + struct MyStruct { + } + ``` + +- Variable naming: First letter lowercase, camelCase + ``` + int myVar = 0; + ``` + +- Member variable naming: First letter lowercase, words connected by underscore, ends with underscore + ``` + class MyClass { + int my_var_; + } + + struct MyStruct { + int my_var_; + } + ``` + +- Macro naming: All uppercase, words connected by underscore + ``` + #define MY_MACRO (1) + ``` + +- Enum naming: All uppercase, words connected by underscore + ``` + enum MyEnum { + MY_ENUM_VALUE1, + MY_ENUM_VALUE2, + MY_ENUM_VALUE3, + }; + ``` + +### Python + +Based on the Google Python Style Guide, the basic requirements are as follows: + +1. Files and Encoding + - **File Encoding**: Files should be encoded in UTF-8 and usually do not need an encoding declaration at the top of the file (Python 3 uses UTF-8 by default). + - **File Naming**: First letter uppercase, camelCase, e.g., `MyModule.py`. + +2. Comments + - **Module Comments**: Each module should start with a module-level docstring describing the module's purpose, functionality, and main classes or functions. For example: + ```python + """ + This module provides utility functions for handling strings. + + It includes functions for string formatting, splitting, and joining. + """ + ``` + - **Function and Method Comments**: Functions and methods also require docstrings explaining their purpose, parameters, return values, and possible exceptions. For example: + ```python + def addNumbers(a: int, b: int): + """ + Add two numbers together. + + Args: + a (int): The first number. + b (int): The second number. + + Returns: + int: The sum of a and b. + """ + return a + b + ``` + - **Inline Comments**: Use inline comments in the code to explain complex or non-intuitive parts, but don't overuse them. Comments should be concise and clear. + +3. Classes and Objects + - **Class Naming**: Class names should use CapWords convention, e.g., `MyClass`. + - **Class Docstrings**: Classes should include a docstring describing their purpose and main functionality. + ```python + class MyClass: + """ + A simple class that represents a person. + + Attributes: + name (str): The name of the person. + age (int): The age of the person. + """ + def __init__(self, name: str, age: int): + self.name = name + self.age = age + + def getInfo(self): + """ + Get the person's information. + + Returns: + str: A string containing the person's name and age. + """ + return f"Name: {self.name}, Age: {self.age}" + ``` + - **Member Variable and Method Naming**: Member variables and method names should use lowercase with words separated by underscores, e.g., `my_variable` and `my_method`. + +4. Functions and Methods + - **Function Naming**: Function names should use lowercase first letter, camelCase, e.g., `checkResult()`. + - **Parameter Naming**: Parameter names should also use lowercase first letter, camelCase, and be descriptive, e.g., `myResultValue`. + - **Function Length**: Functions should be kept short and focused on a single task. Avoid excessively long functions. + +5. Code Layout + - **Indentation**: Use 4 spaces for indentation, not tabs. + - **Line Length**: Limit each line of code to a maximum of 120 characters. If it exceeds, break the line while maintaining code readability. Usually break after operators. For example: + ```python + result = getResult(arg1, arg2, + arg3, arg4) + ``` + - **Blank Lines**: Use blank lines to separate logical sections, e.g., two blank lines between functions and classes, one blank line between methods within a class. + +6. Import Statements + - **Import Order**: Group import statements in the order of standard library, third-party libraries, and local modules, with a blank line between each group. For example: + ```python + import os + import sys + + import requests + + from MyModule import MyClass + ``` + - **Avoid Wildcard Imports**: Avoid using wildcard imports like `from module import *` as they can lead to naming conflicts and reduced code readability. + +7. Exception Handling + - **Specific Exception Types**: When catching exceptions, specify the exact exception type instead of using a generic `except` statement. For example: + ```python + try: + result = 1 / 0 + except ZeroDivisionError: + print("Division by zero occurred.") + ``` + +8. Testing + - **Write Unit Tests**: Write unit tests for your code to ensure correctness and stability. You can use Python's `unittest` or `pytest` testing frameworks. diff --git a/README.md b/README.md index 79e35dbe..85746008 100644 --- a/README.md +++ b/README.md @@ -392,6 +392,9 @@ if __name__ == '__main__': * 提供 Python 和 C++ 混合编程功能 * 提供 Python 打包功能,支持 `pip3 install PyCGraph` 安装 +[2025.05.05 - v3.1.1 - Chunel] +* 提供 `CODE_OF_CONDUCT.md` 文档 + ------------ diff --git a/README_en.md b/README_en.md index ca5ecfa1..3e2fea76 100644 --- a/README_en.md +++ b/README_en.md @@ -18,9 +18,9 @@ ## 1. Introduction -CGraph, short for Color Graph, is a cross-platform DAG computing framework without any third-party dependencies. With the scheduling via `GPipeline`, the purpose of sequential and concurrent executing elements is realized. +CGraph, short for Color Graph, is a cross-platform DAG computing framework. It is written by C++11 without any third-party dependencies, Python APIs are also supported. -You only need to inherit `GNode` class, implement the `run()` method in the subclass, and set the dependencies as needed to achieve the graphical execution of tasks. +With the scheduling via `GPipeline`, the purpose of sequential and concurrent executing elements is realized. You only need to inherit `GNode` class, implement the `run()` method in the subclass, and set the dependencies as needed to achieve the graphical execution of tasks. At the same time, you can also control the graph conditional judgment, loop or concurrent execution logic by setting various `GGroup`s, which containing multi-node information by themselves. @@ -29,90 +29,47 @@ You can transfer your params in many scenes. It is also possible to extend the f ![CGraph Skeleton](https://github.com/ChunelFeng/CGraph/blob/main/doc/image/CGraph%20Skeleton.jpg)
-## 2. Compile -* This project supports MacOS, Linux, and Windows systems without any third-party dependencies. C++11 is default and lowest version, C++17 is recommended. - -* For developers using `CLion` as IDE within all platform, open the `CMakeLists.txt` file as project to compile. - -* Developers on Windows system, using `Visual Studio`(2013 version at least) as IDE, with cmake, enter commands as flowers to build `CGraph.sln` file. - ```shell - $ git clone https://github.com/ChunelFeng/CGraph.git - $ cd CGraph - $ cmake . -Bbuild - ``` - -* Developers on MacOS system, using `Xcode` as IDE, with cmake, enter commands as flowers to build `CGraph.xcodeproj` file. - ```shell - $ git clone https://github.com/ChunelFeng/CGraph.git - $ cd CGraph - $ mkdir build && cd build - $ cmake .. -G Xcode - ``` - -* Developers on Linux system, enter commands as flowers to compile. - ```shell - $ git clone https://github.com/ChunelFeng/CGraph.git - $ cd CGraph - $ cmake . -Bbuild - $ cd build - $ make -j8 - ``` - -* Compile online, enter [CGraph env online](https://gitpod.io/#/github.com/ChunelFeng/CGraph), log in with your Github id, enter commands as flowers to compile and run your first tutorial. - ```shell - $ sudo apt-get install cmake -y - $ ./CGraph-build.sh - $ ./build/tutorial/T00-HelloCGraph - ``` - -## 3. Demo - -#### MyNode.h +## 2. Demo + +> C++ version + ```cpp #include "CGraph.h" -class MyNode1 : public CGraph::GNode { +using namespace CGraph; + +class MyNode1 : public GNode { public: - CStatus run () override { - CStatus status; - printf("[%s], Sleep for 1 second ... \n", this->getName().c_str()); + CStatus run() override { + printf("[%s], sleep for 1 second ...\n", this->getName().c_str()); CGRAPH_SLEEP_SECOND(1) - return status; + return CStatus(); } }; - -class MyNode2 : public CGraph::GNode { +class MyNode2 : public GNode { public: - CStatus run () override { - CStatus status; - printf("[%s], Sleep for 1 second ... \n", this->getName().c_str()); + CStatus run() override { + printf("[%s], sleep for 2 second ...\n", this->getName().c_str()); CGRAPH_SLEEP_SECOND(2) - return status; + return CStatus(); } }; -``` -#### main.cpp -```cpp -#include "MyNode.h" - -using namespace CGraph; int main() { - /* build a pipeline */ GPipelinePtr pipeline = GPipelineFactory::create(); GElementPtr a, b, c, d = nullptr; - /* register node with dependency info */ - pipeline->registerGElement(&a, {}, "nodeA"); // register nodeA with no dependency - pipeline->registerGElement(&b, {a}, "nodeB"); // b depends a + pipeline->registerGElement(&a, {}, "nodeA"); + pipeline->registerGElement(&b, {a}, "nodeB"); pipeline->registerGElement(&c, {a}, "nodeC"); - pipeline->registerGElement(&d, {b, c}, "nodeD"); // d depends b and c + pipeline->registerGElement(&d, {b, c}, "nodeD"); + + pipeline->process(); - /* run dag pipeline */ - status = pipeline->process(); GPipelineFactory::remove(pipeline); + return 0; } ``` @@ -120,3 +77,36 @@ int main() { ![CGraph Demo](https://github.com/ChunelFeng/CGraph/blob/main/doc/image/CGraph%20Demo.jpg)
As is shown on the picture, run `a` firstly. Then, run `b` and `c` parallelized. Run `d` at last after `b` and `c` finished. + +> Python version +```python +import time +from datetime import datetime + +from PyCGraph import GNode, GPipeline, CStatus + + +class MyNode1(GNode): + def run(self): + print("[{0}] {1}, enter MyNode1 run function. Sleep for 1 second ... ".format(datetime.now(), self.getName())) + time.sleep(1) + return CStatus() + +class MyNode2(GNode): + def run(self): + print("[{0}] {1}, enter MyNode2 run function. Sleep for 2 second ... ".format(datetime.now(), self.getName())) + time.sleep(2) + return CStatus() + + +if __name__ == '__main__': + pipeline = GPipeline() + a, b, c, d = MyNode1(), MyNode2(), MyNode1(), MyNode2() + + pipeline.registerGElement(a, set(), "nodeA") + pipeline.registerGElement(b, {a}, "nodeB") + pipeline.registerGElement(c, {a}, "nodeC") + pipeline.registerGElement(d, {b, c}, "nodeD") + + pipeline.process() +```