Skip to content

Conventions #100

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 64 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
64 commits
Select commit Hold shift + click to select a range
fd393ad
Create PYTHON_API_CONVENTIO.md
sDos280 Sep 21, 2022
27f494a
Create CONTRIBUTING.md
sDos280 Sep 21, 2022
c9bf3d7
Rename PYTHON_API_CONVENTIO.md to PYTHON_API_CONVENTIONS.md
sDos280 Sep 21, 2022
6ccefce
Update PYTHON_API_CONVENTIONS.md
sDos280 Sep 21, 2022
e4ae515
Update PYTHON_API_CONVENTIONS.md
sDos280 Sep 21, 2022
9b387f0
Update PYTHON_API_CONVENTIONS.md
sDos280 Sep 21, 2022
3ae0e32
Update PYTHON_API_CONVENTIONS.md
sDos280 Sep 21, 2022
aba2cd5
Update PYTHON_API_CONVENTIONS.md
sDos280 Sep 21, 2022
4573412
Update PYTHON_API_CONVENTIONS.md
sDos280 Sep 21, 2022
4012fc9
update PYTHON_API_CONVENTIONS.md
sDos280 Sep 22, 2022
7f8cec9
make shapes_draw_rounded_rectangle.py stand for the conventions
sDos280 Sep 22, 2022
3ddec64
update shapes_draw_rounded_rectangle.py
sDos280 Sep 22, 2022
6487977
update shapes_draw_rounded_rectangle.py
sDos280 Sep 22, 2022
9c9ac08
make shapes_following_eyes.py stand for the convention
sDos280 Sep 22, 2022
e604d7a
make shapes_lines_bezier.py stand for the conventions
sDos280 Sep 22, 2022
46cac6b
make shapes_logo_raylib.py stand for the conventions
sDos280 Sep 22, 2022
078f185
make core_input_keys.py stand for the conventions
sDos280 Sep 22, 2022
4a09f17
make core_input_gestures.py stand for the conventions
sDos280 Sep 22, 2022
e609d7d
update core_input_gestures.py
sDos280 Sep 22, 2022
ba5b591
make core_scissor_test.py stand for the conventions
sDos280 Sep 22, 2022
be5ff75
make core_window_should_close.py stand for the conventions
sDos280 Sep 22, 2022
abc23c7
make core_random_values.py stand for the conventions
sDos280 Sep 22, 2022
427caab
update core_random_values.py stand for the conventions
sDos280 Sep 22, 2022
8398f0d
Update PYTHON_API_CONVENTIONS.md
sDos280 Sep 22, 2022
15497ba
update shapes_following_eyes.py
sDos280 Sep 22, 2022
32b2efc
made core_2d_camera.py stand for the conventions
sDos280 Sep 22, 2022
0ec7b92
Update PYTHON_API_CONVENTIONS.md
sDos280 Sep 22, 2022
350fc2f
Merge remote-tracking branch 'origin/Conventions' into Conventions
sDos280 Sep 22, 2022
fd3e06f
Update shapes_draw_rounded_rectangle.py
sDos280 Sep 22, 2022
d123e25
Update shapes_lines_bezier.py
sDos280 Sep 22, 2022
3a4b90c
Update shapes_logo_raylib.py
sDos280 Sep 22, 2022
de6a98c
removing unused line in the end
sDos280 Sep 22, 2022
785df90
Update PYTHON_API_CONVENTIONS.md
sDos280 Sep 22, 2022
e0315f2
Update PYTHON_API_CONVENTIONS.md
sDos280 Sep 22, 2022
bc629b3
made shapes_logo_raylib.py stand for the conventions
sDos280 Sep 22, 2022
ddc7f0f
Merge remote-tracking branch 'origin/Conventions' into Conventions
sDos280 Sep 22, 2022
c63f203
Merge branch 'electronstudio:master' into Conventions
sDos280 Sep 23, 2022
d248500
Update PYTHON_API_CONVENTIONS.md
sDos280 Sep 24, 2022
fd4140f
make core_2d_camera.py and core_2d_camera_mouse_zoom.py stand for the…
sDos280 Sep 24, 2022
8159c68
commenting core_2d_camera_mouse_zoom.py and fixing bugs
sDos280 Sep 24, 2022
30dceaa
making core_2d_camera_platformer.py stand for the conventions
sDos280 Sep 24, 2022
cb3292f
making core_2d_camera_platformer.py stand for the conventions
sDos280 Sep 24, 2022
f3197d4
redefine the PYTHON_API_CONVENTIONS.md to python conventions.
sDos280 Sep 24, 2022
602e243
Update PYTHON_API_CONVENTIONS.md
sDos280 Sep 24, 2022
615366f
making shapes_draw_rounded_rectangle.py stand for the Python API conv…
sDos280 Sep 24, 2022
9fffa31
making shapes_following_eyes.py stand for the Python API conventions
sDos280 Sep 24, 2022
a219601
making shapes_lines_bezier.py stand for the Python API conventions
sDos280 Sep 24, 2022
022d7ba
making shapes_logo_raylib.py stand for the Python API conventions. an…
sDos280 Sep 24, 2022
d534dc3
making textures_to_image.py stand for the Python API conventions. and…
sDos280 Sep 24, 2022
c37b16a
making textures_bunnymark_more_pythonic.py stand for the Python API c…
sDos280 Sep 24, 2022
41aede3
making textures_bunnymark_more_pythonic.py more efficient
sDos280 Sep 24, 2022
ff6512e
making textures_bunnymark_more_pythonic.py more efficient
sDos280 Sep 24, 2022
dd0b11f
making textures_mouse_painting.py stand to the Python API conventions
sDos280 Sep 24, 2022
57b5e61
Update PYTHON_API_CONVENTIONS.md
sDos280 Sep 24, 2022
0939ca3
made core_window_should_close.py stand for the Python API conventions
sDos280 Sep 25, 2022
b506ebb
made core_scissor_test.py stand for the Python API conventions
sDos280 Sep 25, 2022
6d14882
made core_random_values.py stand for the Python API conventions
sDos280 Sep 25, 2022
5903c3d
made core_input_mouse_wheel.py stand for the Python API conventions
sDos280 Sep 25, 2022
60a3555
made core_input_mouse.py stand for the Python API conventions, with s…
sDos280 Sep 25, 2022
98ec505
made core_input_keys.py stand for the Python API conventions
sDos280 Sep 25, 2022
5933ab1
made core_input_keys.py stand for the Python API conventions again :)
sDos280 Sep 25, 2022
0183323
made core_input_gestures.py stand for the Python API conventions
sDos280 Sep 25, 2022
2a29b73
made core_input_gestures.py stand for the Python API conventions agai…
sDos280 Sep 25, 2022
7382a28
Merge branch 'electronstudio:master' into Conventions
sDos280 Jan 6, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 52 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
## Contributing to raylib-python-cffi

Hello contributors! Welcome to **raylib-python-cffi** AKA **pyray**!

Do you enjoy pyray and want to contribute? Nice! You can help with the following points:

- `Python programming` - Can you write/review/test/improve the code?
- `Documentation/Tutorials/Example` - Can you write some tutorial/example?
- `Porting Examples from C to Python` - Can you port the raylib examples in c to python?
- `Build For Web` - Can you help [the issue](https://github.com/electronstudio/raylib-python-cffi/issues/58)?
- `Testing` - Can you find some bugs in pyray?

This document contains a set of guidelines to contribute to the project. These are mostly guidelines, not rules.
Use your best judgement, and feel free to propose changes to this document in a pull request.

### raylib philosophy

- raylib is a tool to **ENJOY** videogames programming, every function in raylib is designed as a mini-tutorial on itself.
- raylib is **SIMPLE** and **EASY-TO-USE**, I tried to keep it compact with a small set of functions, if a function is too complex, better not including it.
- raylib is open source and free; educators and institutions can use this tool to **TEACH** videogames programming completely for free.
- raylib is collaborative; contribution of tutorials / code examples / bug fixes / code comments are highly appreciated.
- raylib's license (and its external libs respective licenses) allow using raylib on commercial projects.

### raylib python coding conventions

Despite being written in C, pyray is a python bindings for raylib. so the conventions are also python independent
look at [Python API Coding Style Conventions](https://github.com/raysan5/raylib/wiki/raylib-coding-conventions),

Source code is extensively commented for that purpose, raylib primary learning method is:

> `Learn by reading code and examples`

### Opening new Issues

To open new issue for raylib (bug, enhancement, discussion...), just try to follow these rules:

- Make sure the issue has not already been reported before by searching on GitHub under Issues.
- If you're unable to find an open issue addressing the problem, open a new one. Be sure to include a
title and clear description, as much relevant information as possible, and a code sample demonstrating the unexpected behavior.
- If applies, attach some screenshot of the issue and a .zip file with the code sample and required resources.
- On issue description, add a brackets tag about the raylib module that relates to this issue.
If don't know which module, just report the issue, I will review it.
- You can check other issues to see how is being done!

### Sending a Pull-Request

- Make sure the PR description clearly describes the problem and solution. Include the relevant issue number if applicable.
- Don't send big pull requests (lots of changelists), they are difficult to review. It's better to send small pull requests, one at a time.
- Verify that changes don't break the build (at least on Windows platform). As many platforms where you can test it, the better, but don't worry
if you cannot test all the platforms.

Thank you very much for your time! :)
193 changes: 193 additions & 0 deletions PYTHON_API_CONVENTIONS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,193 @@
## Python API Coding Style Conventions

Here is a list with some code conventions used by raylib in python:

| Code element | Convention | Example |
|---------------------|:-----------------------------------:|-------------------------------------------|
| Variables | lower_case | `delta_time = 0`, `player_age = 18` |
| Local variables | lower_case | `player_position = Vector2(0, 0)` |
| Global variables | lower_case | `window_ready = False` |
| Constants variables | ALL_CAPS | `MAX_VALUE = 8`, `SCREEN_WIDTH = 800` |
| Definitions values | ALL_CAPS | `MAX_BUILDINGS = 5`[^1] |
| string values | always "" | `output = "Hello"`, `"welcome"` |
| float values | always x.x | `gravity = 10.0` |
| Operators | value1 * value2 | `product = value * 6` |
| Operators | value1 / value2 | `division = value / 4` |
| Operators | value1 + value2 | `sum = value + 10` |
| Operators | value1 - value2 | `res = value - 5` |
| Class | TitleCase | `class TextureFormat` |
| Enum Class members | ALL_CAPS | `PIXELFORMAT_UNCOMPRESSED_R8G8B8` |
| Class members | lowerCase | `texture.width`, `color.r` |
| Functions | lowerCase & wordSeparationBy_ | `init_window()`, `update_camera_center()` |
| Functions params | lowerCase | `width`, `height` |
| Ternary Operator | result1 if condition else result2 | `print("yes" if value == 0 else "no")` |
[^1] like `macro definitions` of value in C

Some other conventions to follow:
- **ALWAYS** initialize all defined variables.
- **use TABS / 4 spaces**.
- Avoid trailing spaces, please, avoid them
- Avoid using **semicolon** as you can
Comment on lines +26 to +30
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are linters and formatters for that. ruff, black and isort will be enough to not bothering with those rules.

- Control flow statements always are followed **by a space**:
Copy link
Contributor

@pkulev pkulev Nov 7, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is strange one, never saw that rule neither on production nor in open source projects. Why?
PEP8 says something like "don't write if-statements in one line"

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fair

```python
if condition : value = 0
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You have if-expressions for that.

value = 0 if condition else value

Or if it is initialization thing:

value = value or 0

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That isn't an "if statement" that is the ternary operator


while not window_should_close():
#Do something here!

for i in range(NUM_VALUES): print(i)
```
- All conditions checks are **always between parenthesis** but not boolean values:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay that's big whaat.

  • Why always?
  • Why booleans are different?

50 and True will return 50. Should it be between parenthesis?

Copy link
Contributor Author

@sDos280 sDos280 Nov 11, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, as you see the conventions haven't really been reviewed by electrostudio so yeah they aren't perfect, feel free to fork my doing and implementing your conventions

p.s. and yeah the conventions aren't perfect because in the beginning they were made to mimic the raylib code style conventions but maybe following PEP 8 would be better...

```python
if value > 1 and value1 < 50 and valueActive:
#Do something here!
```

**If proposing new functions, please try to use a clear naming for function-name and functions-parameters, in case of doubt, open an issue for discussion.**

## Import libraries and Module
- import libraries with the form `from library import *`
- import modules/variables from libraries with the form `from library import (module1, ..., variable1, ...)`
```python
from pyray import *
from raylib.colors import (
RAYWHITE,
DARKGRAY,
...
)
```

## Files and Directories Naming Conventions

- Directories will be named using `snake_case`: `resources/models`, `resources/fonts`

- Files will be named using `snake_case`: `main_title.png`, `cubicmap.png`, `sound.wav`

_NOTE: Avoid any space or special character in the files/dir naming!_

## Games/Examples Directories Organization Conventions

- Data files should be organized by context and usage in the game, think about the loading requirements for data and put all the resources that need to be loaded at the same time together.
- Use descriptive names for the files, it would be perfect if just reading the name of the file, it was possible to know what is that file and where fits in the game.
- Here is an example, note that some resources require to be loaded all at once while other require to be loaded only at initialization (gui, font).

```
resources/audio/fx/long_jump.wav
resources/audio/music/main_theme.ogg
resources/screens/logo/logo.png
resources/screens/title/title.png
resources/screens/gameplay/background.png
resources/characters/player.png
resources/characters/enemy_slime.png
resources/common/font_arial.ttf
resources/common/gui.png
```

## Example Conventions For Python API
- examples ***should*** have the following structure
```python
"""

raylib [raylib module] example - Name Of The Example

"""

# Import
# ------------------------------------------------------------------------------------
# Do something here!
# ------------------------------------------------------------------------------------

# Definitions
# ------------------------------------------------------------------------------------
# Define you functions/global variables here
# ------------------------------------------------------------------------------------

# Program main entry point
# ------------------------------------------------------------------------------------
def main():
# Initialization
# ------------------------------------------------------------------------------------
# Do something here!
# ------------------------------------------------------------------------------------

# Main game loop
while ... :
# Update
# ----------------------------------------------------------------------------------
# Do something here!
# ----------------------------------------------------------------------------------

# Draw
# ----------------------------------------------------------------------------------
# Do something here!
# ----------------------------------------------------------------------------------

# De-Initialization
# ----------------------------------------------------------------------------------
# Do something here!
# ----------------------------------------------------------------------------------

# Execute the main function
if __name__ == '__main__':
main()
```
- temple (basic window example):
```python
"""

raylib [core] example - Basic Window

"""

# Import
# ------------------------------------------------------------------------------------
from pyray import *
# ------------------------------------------------------------------------------------

# ------------------------------------------------------------------------------------
# Program main entry point
# ------------------------------------------------------------------------------------
def main():
# Initialization
# ------------------------------------------------------------------------------------
SCREEN_WIDTH = 800
SCREEN_HEIGHT = 450

init_window(SCREEN_WIDTH, SCREEN_HEIGHT, "raylib [core] example - basic window")

# TODO: Load resources / Initialize variables at this point

set_target_fps(60) # Set our game to run at 60 frames-per-second
# ------------------------------------------------------------------------------------

# Main game loop
while not window_should_close(): # Detect window close button or ESC key
# Update
# ----------------------------------------------------------------------------------
# TODO: Update variables / Implement example logic at this point
# ----------------------------------------------------------------------------------

# Draw
# ----------------------------------------------------------------------------------
begin_drawing()

clear_background(RAYWHITE)
draw_text("Congrats! You created your first window!", 190, 200, 20, LIGHTGRAY)

end_drawing()
# ----------------------------------------------------------------------------------

# De-Initialization
# ----------------------------------------------------------------------------------

# TODO: Unload all loaded resources at this point

close_window() # Close window and OpenGL context
# ----------------------------------------------------------------------------------


# Execute the main function
if __name__ == '__main__':
main()

```
Loading