Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
1172c4b
build: setup docker postgres database
rafittu Oct 11, 2024
7a16237
chore: update secrets
rafittu Oct 11, 2024
5db8954
build: add flask as requirement
rafittu Oct 14, 2024
58f8b7b
chore: update docker ignore
rafittu Oct 14, 2024
b9ab351
feat: setup websocket to receive random color
rafittu Oct 14, 2024
ee6eaaf
chore: setup flask app
rafittu Oct 14, 2024
bc11d56
build: add eventlet as requirement
rafittu Oct 14, 2024
f6cb530
feat: receive color timestamp
rafittu Oct 14, 2024
f233e9e
Merge pull request #2 from rafittu/feat/websocket
rafittu Oct 15, 2024
7417c7d
feat: setup db with sql alchemy
rafittu Oct 15, 2024
b3f11f8
feat: color model
rafittu Oct 16, 2024
e4e2ac4
feat: color map dict
rafittu Oct 16, 2024
8fe593d
feat: function to parse rgb
rafittu Oct 16, 2024
165e280
feat: function to get color name
rafittu Oct 16, 2024
12a25ab
feat: function to save color in database
rafittu Oct 16, 2024
2efc6bc
feat: start database on app init
rafittu Oct 16, 2024
a33548a
build: add new app requirements
rafittu Oct 16, 2024
d1ee3c6
fix: update imports
rafittu Oct 16, 2024
173bc28
build: add new app requirements
rafittu Oct 16, 2024
5ac263b
build: remove obsolete version line
rafittu Oct 16, 2024
2abf67b
chore: new env examples
rafittu Oct 16, 2024
6ca03a9
feat: __init__ file
rafittu Oct 16, 2024
f359c64
Merge pull request #3 from rafittu/feat/save-color-db
rafittu Oct 16, 2024
0d3e4b1
Update README.md
rafittu Oct 17, 2024
79ddc84
Merge pull request #5 from rafittu/memo/readme
rafittu Oct 17, 2024
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
5 changes: 5 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
venv
__pycache__
*.pyc
*.pyo
*.pyd
8 changes: 8 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# PostgreSQL database setup
POSTGRES_DB=database_name
POSTGRES_USER=user
POSTGRES_PASSWORD=password
POSTGRES_HOST=database_host
POSTGRES_PORT=port_number

DATABASE_URL=postgresql+psycopg2://user:password@db:port_number/database_name
65 changes: 64 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,64 @@
# 🎨 Genius
# 🎨 Genius

###

<br>

O projeto **Genius** é um sistema que prevê a próxima cor e sequência de cores em padrões similares ao clássico jogo **Genius**!

Utilizando redes neurais e aprendizado incremental em tempo real, o sistema aprende continuamente a partir de sequências de cores geradas dinamicamente, proporcionando uma experiência única de predição baseada em cores.

<br>

## Tecnologias

Este projeto utiliza as seguintes tecnologias:

- **Python** como linguagem principal;
- **SQLAlchemy ORM** para integração com o banco de dados **PostgreSQL**;
- **Flask** para construção de uma aplicação web responsiva;
- **Socket.IO** para comunicação em tempo real entre o servidor e o cliente;
- **TensorFlow** para criação e treinamento de uma rede neural do tipo **LSTM (Long Short-Term Memory)**,
- **Docker** como uma ferramenta de containerização;

<br>

## Arquitetura do Sistema

A rede neural LSTM é configurada para realizar **aprendizado incremental**, processando novas entradas de dados continuamente. A cada nova cor recebida, o modelo é atualizado com o histórico e re-treinado, garantindo que a predição de padrões e sequência de cores se torne mais precisa à medida que o sistema evolui.

O banco de dados registra as cores em suas respectivas componentes RGB, assim como o `timestamp` de cada entrada, facilitando a análise e o processamento dos dados em tempo real.

<br>

## Configuração do Projeto

### Requisitos para rodar a aplicação

- Python (versão 3.11 ou superior)
- Docker e Docker Compose;

### Instalação

1. Clonando o repositório:

```bash
$ git clone git@github.com:rafittu/python-genius.git
$ cd python-genius
```

2. Crie um arquivo `.env` na raiz do projeto e preencha as informações de acordo com o arquivo `.env.example` disponível.

3. Inicie o ambiente de desenvolvimento:

```bash
$ docker-compose up --build
```

<br>

##

<p align="right">
<a href="https://www.linkedin.com/in/rafittu/">Rafael Ribeiro 🚀</a>
</p>
28 changes: 23 additions & 5 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,10 +1,28 @@
version: '3.8'

services:
app:
build: .
env_file: .env
build:
context: .
dockerfile: Dockerfile
command: python src/main.py
volumes:
- ./src:/app/src
- .:/app
ports:
- "8000:8000"
env_file:
- .env
depends_on:
- db

db:
image: postgres:15.3
environment:
POSTGRES_DB: ${POSTGRES_DB}
POSTGRES_USER: ${POSTGRES_USER}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
volumes:
- pgdata:/var/lib/postgresql/data
ports:
- "5432:5432"

volumes:
pgdata:
6 changes: 6 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1 +1,7 @@
python-dotenv==1.0.0
flask-socketio==5.4.1
eventlet==0.37.0
Flask==2.2.5
Flask-SQLAlchemy==2.5.1
SQLAlchemy==1.4.22
psycopg2-binary==2.9.10
Empty file added src/api/__init__.py
Empty file.
59 changes: 59 additions & 0 deletions src/api/color_api.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import re
import logging
from flask_socketio import SocketIO
from flask import Blueprint
from database.models.color import Color
from database.database import db

color_api_bp = Blueprint('color_api', __name__)
socketio = SocketIO(cors_allowed_origins="*")
logger = logging.getLogger(__name__)

COLOR_MAP = {
"rgb(0, 0, 255)": "blue",
"rgb(0, 255, 255)": "blue-green",
"rgb(0, 255, 0)": "green",
"rgb(128, 255, 0)": "yellow-green",
"rgb(255, 255, 0)": "yellow",
"rgb(255, 192, 0)": "yellow-orange",
"rgb(255, 128, 0)": "orange",
"rgb(255, 64, 0)": "red-orange",
"rgb(255, 0, 0)": "red"
}


def init_sockets(app):
socketio.init_app(app)


def parse_rgb(color_str):
match = re.match(r'rgb\((\d+),\s*(\d+),\s*(\d+)\)', color_str)
if match:
return int(match.group(1)), int(match.group(2)), int(match.group(3))
raise ValueError("Invalid color format")


def get_color_name(color_str):
return COLOR_MAP.get(color_str, "unknown")


@socketio.on('send_color')
def handle_receive_color(data):
color_str = data.get('color')
timestamp = data.get('timestamp')

try:
red, green, blue = parse_rgb(color_str)
color_name = get_color_name(color_str)

new_color = Color(
color_name=color_name,
red=red,
green=green,
blue=blue,
timestamp=timestamp
)
db.session.add(new_color)
db.session.commit()
except ValueError as e:
logger.error(f"Error processing color: {e}")
Empty file added src/database/__init__.py
Empty file.
10 changes: 10 additions & 0 deletions src/database/database.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
from flask_sqlalchemy import SQLAlchemy
from flask import Flask
import os

db = SQLAlchemy()

def init_app(app: Flask):
app.config['SQLALCHEMY_DATABASE_URI'] = os.getenv("DATABASE_URL")
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db.init_app(app)
Empty file added src/database/models/__init__.py
Empty file.
11 changes: 11 additions & 0 deletions src/database/models/color.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
from sqlalchemy import Column, Integer, String, DateTime, func
from database.database import db

class Color(db.Model):
__tablename__ = 'colors'
id = Column(Integer, primary_key=True, index=True)
color_name = Column(String(50), nullable=False)
red = Column(Integer, nullable=False)
green = Column(Integer, nullable=False)
blue = Column(Integer, nullable=False)
timestamp = Column(DateTime(timezone=True), server_default=func.now())
23 changes: 23 additions & 0 deletions src/main.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,29 @@
from dotenv import load_dotenv
from flask import Flask
from api.color_api import color_api_bp, init_sockets, socketio
from database.database import init_app, db

load_dotenv()


def create_app():
app = Flask(__name__)
init_app(app)
app.register_blueprint(color_api_bp)
init_sockets(app)

with app.app_context():
db.create_all()

return app


def main():
print("🎨 Genius!")

app = create_app()
socketio.run(app, host='0.0.0.0', port=8000, debug=True)


if __name__ == "__main__":
main()