✔ one shared main interface ✔ multiple project modules (MCLP, Transport, Scheduling, etc.) ✔ each project isolated in its own folder ✔ a clean separation between GUI and logic ✔ a future NestJS API integration layer
RO-Project/
│
├── main.py
│
├── interface/ # Global GUI
│ ├── main_window.py # Home screen with project selection
│ ├── base_project_window.py # Abstract class for all project interfaces
│ ├── wifi_mclp_window.py # Your Wi-Fi GUI
│ ├── transport_window.py # Example project 2
│ ├── scheduling_window.py # Example project 3
│ ├── graphs_window.py # Example project 4
│ ├── facility_location_window.py # Example project 5
│ └── resources/ # Icons, style, .ui files
│
├── projects/ # Each project’s logic lives here
│ ├── wifi_mclp/ # Your project
│ │ ├── data/
│ │ │ ├── data_loader.py
│ │ │ └── preprocessing.py
│ │ ├── models/
│ │ │ ├── mclp_model.py
│ │ │ └── constraints.py
│ │ ├── solver/
│ │ │ └── gurobi_solver.py
│ │ ├── services/
│ │ │ └── wifi_service.py # Core function exposed for API or UI
│ │ └── utils/
│ │ ├── geometry.py
│ │ ├── map_visualizer.py
│ │ └── logger.py
│ │
│ ├── transport/ # Project 2 (Transport Problem)
│ │ ├── models/…
│ │ ├── solver/…
│ │ ├── services/transport_service.py
│ │ └── data/...
│ │
│ ├── scheduling/ # Project 3 (Shift Scheduling)
│ │ ├── models/…
│ │ ├── solver/…
│ │ ├── services/scheduling_service.py
│ │ └── data/...
│ │
│ ├── graphs/ # Project 4 (Graph Coloring)
│ │ ├── models/…
│ │ ├── solver/…
│ │ ├── services/graph_service.py
│ │ └── data/...
│ │
│ └── facility_location/ # Project 5 (Location-Allocation for example)
│ ├── models/…
│ ├── solver/…
│ ├── services/facility_service.py
│ └── data/...
│
├── api/ # For NestJS to call Python
│ ├── run_service.py # ONE entry point for ALL projects
│ └── dispatch.py # Routes API calls to correct service
│
├── tests/
│ ├── test_wifi.py
│ ├── test_transport.py
│ ├── test_scheduling.py
│ └── ...
│
├── requirements.txt
└── README.md
Below is a simple but professional-level description.
Starts the app:
from interface.main_window import MainWindow
from PyQt5.QtWidgets import QApplication
import sys
app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec_())Nothing more. No business logic. No data. No models.
This is the homepage, showing buttons:
- Wi-Fi MCLP
- Transport
- Scheduling
- Graph Coloring
- Facility Location
Each button opens the corresponding project window:
# Example
def open_wifi_project(self):
from interface.wifi_mclp_window import WifiMCLPWindow
self.child = WifiMCLPWindow()
self.child.show()This ensures isolation between projects.
Your GUI:
- fields: radius, number of repeaters, capacity, etc.
- load data buttons
- run optimization button
- show map / results
When the user clicks "Run":
from projects.wifi_mclp.services.wifi_service import run_mclp
params = {
"radius": self.radius_input.value(),
"max_repeaters": self.k_input.value(),
"capacity": self.cap_input.value()
}
result = run_mclp(params)
self.display_results(result)GUI only talks to services, never to models.
This is the heart of your system.
It is used by:
✔ PyQt GUI ✔ NestJS API ✔ Unit tests ✔ Command-line test
Example:
def run_mclp(params):
# 1. Load data
points = data_loader.load_points()
# 2. Preprocess
coverage_matrix = preprocessing.compute_coverage_matrix(points, params["radius"])
# 3. Build model
model = mclp_model.build_model(coverage_matrix, params)
# 4. Solve
solution = gurobi_solver.solve(model)
# 5. Format result
return {
"selected_sites": solution.sites,
"coverage_percentage": solution.coverage,
"objective": solution.obj_value
}This function returns a clean dictionary → perfect for JSON.
Builds the mathematical program:
def build_model(coverage_matrix, params):
m = gp.Model("MCLP")
# variables
x = m.addVars(num_sites, vtype=GRB.BINARY)
y = m.addVars(num_points, vtype=GRB.BINARY)
# coverage constraint
for i in points:
m.addConstr(y[i] <= gp.quicksum(x[j] for j in sites if coverage[i][j] == 1))
# limit on repeater count
m.addConstr(x.sum() <= params["max_repeaters"])
# objective
m.setObjective(gp.quicksum(demand[i] * y[i] for i in points), GRB.MAXIMIZE)
return mThis is pure OR science, no GUI.
This is what NestJS will call.
Example:
python api/run_service.py --project wifi_mclp --radius 200 --max_repeaters 6
The script does:
from api.dispatch import dispatch_request
params = parse_args()
output = dispatch_request(params)
print(json.dumps(output))Routes API calls:
from projects.wifi_mclp.services.wifi_service import run_mclp
from projects.transport.services.transport_service import run_transport
...
def dispatch_request(params):
project = params["project"]
if project == "wifi_mclp":
return run_mclp(params)
elif project == "transport":
return run_transport(params)
# etc.
else:
raise Exception("Unknown project")NestJS will execute:
const result = await execa('python', [
'api/run_service.py',
'--project', 'wifi_mclp',
'--radius', '150',
'--max_repeaters', '5'
]);You receive stdout, parse JSON:
return JSON.parse(result.stdout);The Python service returns:
{
"selected_sites": [3, 7, 9],
"coverage_percentage": 88.5,
"objective": 1450,
"map_path": "output/map.png"
}This is clean and maintainable.
✔ 5 people can work independently. ✔ Every project is isolated (clean code boundaries). ✔ GUI is separate from logic. ✔ Python services reusable by NestJS API. ✔ Easy unit testing. ✔ Code stays readable and professional.