I started a game project with the python packages pygame and agentpy in the Fedora Linux distribution.
You can find it on my fedora pagure repo

Python tutorials with source code, examples, guides, and tips and tricks for Windows and Linux development.

[mythcat@fedora ~]$ pip install duckdb --upgrade
Defaulting to user installation because normal site-packages is not writeable
Collecting duckdb
...
Installing collected packages: duckdb
Successfully installed duckdb-1.1.0
[mythcat@fedora ~]$ pip install pygame
Defaulting to user installation because normal site-packages is not writeable
Requirement already satisfied: pygame in ./.local/lib/python3.12/site-packages (2.5.2)
[mythcat@fedora ~]$ pip install agentpy
...
Installing collected packages: scipy, networkx, kiwisolver, joblib, fonttools, dill, cycler, contourpy, pandas, multiprocess, matplotlib, SALib, agentpy
Successfully installed SALib-1.5.1 agentpy-0.1.5 contourpy-1.3.0 cycler-0.12.1 dill-0.3.8 fonttools-4.53.1 joblib-1.4.2 kiwisolver-1.4.7 matplotlib-3.9.2 multiprocess-0.70.16 networkx-3.3 pandas-2.2.2 scipy-1.14.1pip install agentpy
Collecting agentpy
...
Successfully installed SALib-1.5.1 agentpy-0.1.5 contourpy-1.3.0 cycler-0.12.1 dill-0.3.8 fonttools-4.53.1
joblib-1.4.2 kiwisolver-1.4.7 matplotlib-3.9.2 multiprocess-0.70.16 networkx-3.3 packaging-24.1
pillow-10.4.0 pyparsing-3.1.4 scipy-1.14.1import agentpy as ap
import matplotlib.pyplot as plt
# define Agent class
class RandomWalker(ap.Agent):
def setup(self):
self.position = [0, 0]
def step(self):
self.position += self.model.random.choice([[1, 0], [-1, 0], [0, 1], [0, -1]])
# define Model class
class RandomWalkModel(ap.Model):
def setup(self):
self.agents = ap.AgentList(self, self.p.agents, RandomWalker)
self.agents.setup()
def step(self):
self.agents.step()
def update(self):
self.record('Positions', [agent.position for agent in self.agents])
def end(self):
positions = self.log['Positions']
plt.figure()
for pos in positions:
plt.plot(*zip(*pos))
plt.show()
# configuration and running
parameters = {'agents': 5, 'steps': 20}
model = RandomWalkModel(parameters)
results = model.run()python test001.py
Matplotlib is building the font cache; this may take a moment.
Completed: 20 steps
Run time: 0:00:50.823483
Simulation finished
from PyQt6.QtWidgets import QApplication, QMainWindow, QTextEdit, QVBoxLayout, QHBoxLayout, QWidget, QPushButton, QCheckBox, QLineEdit, QLabel
from PyQt6.QtGui import QTextDocument
from PyQt6.QtCore import Qt
import re
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("HTML Cleaner")
self.text_edit = QTextEdit()
self.clean_button = QPushButton("Clean HTML")
self.transform_div_checkbox = QCheckBox("Transform tags")
self.realtime_checkbox = QCheckBox("Realtime")
self.regex_edit = QLineEdit()
self.regex_edit.setPlaceholderText("Enter regex pattern")
self.regex_edit.setEnabled(False) # Dezactivăm inițial
top_layout = QHBoxLayout()
top_layout.addWidget(self.clean_button)
top_layout.addWidget(self.transform_div_checkbox)
top_layout.addWidget(QLabel("Regex:"))
top_layout.addWidget(self.regex_edit)
top_layout.addWidget(self.realtime_checkbox)
main_layout = QVBoxLayout()
main_layout.addLayout(top_layout)
main_layout.addWidget(self.text_edit)
container = QWidget()
container.setLayout(main_layout)
self.setCentralWidget(container)
self.clean_button.clicked.connect(self.clean_html)
self.realtime_checkbox.stateChanged.connect(self.toggle_realtime)
self.regex_edit.textChanged.connect(self.realtime_update)
def clean_html(self):
html_text = self.text_edit.toPlainText()
clean_text = self.remove_html_tags(html_text)
self.text_edit.setPlainText(clean_text)
def remove_html_tags(self, text):
# Remove CSS
text = re.sub(r'.*?', '', text, flags=re.DOTALL)
# Remove JavaScript
text = re.sub(r'.*?', '', text, flags=re.DOTALL)
# Remove HTML comments
text = re.sub(r'', '', text, flags=re.DOTALL)
# Transform tags if checkbox is checked
if self.transform_div_checkbox.isChecked():
text = re.sub(r']*>', '', text)
# Remove HTML tags but keep content
clean = re.compile('<.*?>')
text = re.sub(clean, '', text)
# Remove empty lines
text = re.sub(r'\n\s*\n', '\n', text)
return text
def toggle_realtime(self):
if self.realtime_checkbox.isChecked():
self.regex_edit.setEnabled(True) # Activăm editbox-ul
self.text_edit.textChanged.connect(self.realtime_update)
else:
self.regex_edit.setEnabled(False) # Dezactivăm editbox-ul
self.text_edit.textChanged.disconnect(self.realtime_update)
def realtime_update(self):
if self.realtime_checkbox.isChecked():
html_text = self.text_edit.toPlainText()
regex_pattern = self.regex_edit.text()
if regex_pattern:
try:
html_text = re.sub(regex_pattern, '', html_text)
except re.error:
pass # Ignore regex errors
self.text_edit.blockSignals(True)
self.text_edit.setPlainText(html_text)
self.text_edit.blockSignals(False)
app = QApplication([])
window = MainWindow()
window.show()
app.exec()
Posted by
Cătălin George Feștilă
Labels:
2024,
module,
modules,
packages,
PyQt6,
python,
python 3,
python modules,
python packages,
re,
tutorial,
tutorials
pip install duckdb --upgrade
Collecting duckdb
...
Installing collected packages: duckdb
Successfully installed duckdb-1.0.0python test_memory_duckdb_sqlite_db.py
[]
[('table', 'users', 'users', 0, 'CREATE TABLE users(id BIGINT PRIMARY KEY, first_name VARCHAR, last_name VARCHAR, occupation VARCHAR, hobby VARCHAR, year_of_birth BIGINT, age BIGINT);')]import duckdb
# Conectare la baza de date în memorie
con = duckdb.connect(database=':memory:')
# Instalează extensia sqlite
con.execute("INSTALL sqlite")
# Încarcă extensia sqlite
con.execute("LOAD sqlite")
# Verifică dacă extensia este încărcată
result = con.execute("SELECT * FROM sqlite_master").fetchall()
print(result)
# Conectare la baza de date pe disc
con_disk = duckdb.connect(database='sqlite_database.db', read_only=False)
# Instalează extensia sqlite pentru baza de date pe disc
con_disk.execute("INSTALL sqlite")
# Încarcă extensia sqlite pentru baza de date pe disc
con_disk.execute("LOAD sqlite")
# Verifică dacă extensia este încărcată pentru baza de date pe disc
result_disk = con_disk.execute("SELECT * FROM sqlite_master").fetchall()
print(result_disk)pip install faker
Collecting faker
...
Installing collected packages: six, python-dateutil, faker
Successfully installed faker-28.1.0 python-dateutil-2.9.0.post0 six-1.16.0pip install pandas
...
Successfully built pandas
Installing collected packages: pytz, tzdata, pandas
Successfully installed pandas-2.2.2 pytz-2024.1 tzdata-2024.1import sys
from PyQt6.QtWidgets import QApplication, QMainWindow, QTableView
from PyQt6.QtCore import Qt, QAbstractTableModel
import pandas as pd
from faker import Faker
# Generăm date false folosind Faker
fake = Faker()
data = {
'Name': [fake.name() for _ in range(100)],
'Address': [fake.address() for _ in range(100)],
'Email': [fake.email() for _ in range(100)],
'IP Address': [fake.ipv4() for _ in range(100)] # Adăugăm adresa IP
}
# Creăm un DataFrame Pandas
df = pd.DataFrame(data)
# Definim un model pentru QTableView
class PandasModel(QAbstractTableModel):
def __init__(self, df):
super().__init__()
self._df = df
def rowCount(self, parent=None):
return len(self._df)
def columnCount(self, parent=None):
return self._df.shape[1]
def data(self, index, role=Qt.ItemDataRole.DisplayRole):
if index.isValid():
if role == Qt.ItemDataRole.DisplayRole:
return str(self._df.iloc[index.row(), index.column()])
return None
def headerData(self, section, orientation, role=Qt.ItemDataRole.DisplayRole):
if role == Qt.ItemDataRole.DisplayRole:
if orientation == Qt.Orientation.Horizontal:
return self._df.columns[section]
else:
return str(section)
return None
# Aplicatia PyQt6
app = QApplication(sys.argv)
window = QMainWindow()
view = QTableView()
# Setăm modelul pentru QTableView
model = PandasModel(df)
view.setModel(model)
# Configurăm fereastra principală
window.setCentralWidget(view)
window.resize(800, 600)
window.show()
# Rulăm aplicația
sys.exit(app.exec())

import sys
from PyQt6.QtWidgets import QApplication, QWidget, QVBoxLayout, QSlider
from PyQt6.QtCore import Qt
class SliderWindow(QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle("Two Slideres")
self.setGeometry(100, 100, 640, 200)
layout = QVBoxLayout()
self.slider_max = QSlider(Qt.Orientation.Horizontal)
self.slider_max.setMinimum(0)
self.slider_max.setMaximum(100)
self.slider_max.setValue(100)
self.slider_max.valueChanged.connect(self.update_min_slider)
self.slider_min = QSlider(Qt.Orientation.Horizontal)
self.slider_min.setMinimum(0)
self.slider_min.setMaximum(100)
self.slider_min.setValue(0)
self.slider_min.valueChanged.connect(self.update_max_slider)
layout.addWidget(self.slider_max)
layout.addWidget(self.slider_min)
self.setLayout(layout)
def update_min_slider(self, value):
self.slider_min.blockSignals(True)
self.slider_min.setValue(100 - value)
self.slider_min.blockSignals(False)
def update_max_slider(self, value):
self.slider_max.blockSignals(True)
self.slider_max.setValue(100 - value)
self.slider_max.blockSignals(False)
if __name__ == "__main__":
app = QApplication(sys.argv)
window = SliderWindow()
window.show()
sys.exit(app.exec())
pip install --upgrade setuptoolspip install msvc-runtime
ERROR: Could not find a version that satisfies the requirement msvc-runtime (from versions: none)
ERROR: No matching distribution found for msvc-runtimepip install pyqt6
Collecting pyqt6
Using cached PyQt6-6.7.1-cp38-abi3-win_amd64.whl.metadata (2.1 kB)
...
Successfully built PyQt6-sip
Installing collected packages: PyQt6-Qt6, PyQt6-sip, pyqt6
Successfully installed PyQt6-Qt6-6.7.2 PyQt6-sip-13.8.0 pyqt6-6.7.1PythonProjects\test_pydoc>python -m pydoc sysPythonProjects\test_pydoc>python -m pydoc -w sys
wrote sys.htmlPythonProjects\test_pydoc>python -m pydoc -k url
nturl2path - Convert a NT pathname to a file URL and vice versa.
test_sqlite3: testing with SQLite version 3.45.3
test.test_urllib - Regression tests for what was in Python 2's "urllib" module
test.test_urllib2
test.test_urllib2_localnet
test.test_urllib2net\PythonProjects\test_pydoc>python -m pydoc -p 1234
Server ready at http://localhost:1234/
Server commands: [b]rowser, [q]uit
"""
my python module
====
This is documentation
"""
def test():
"""
Function test
"""
print("test")python -m pydoc test
PythonProjects\test_pydoc>python -m pydoc test
Help on module test:
NAME
test
FILE
...from flask import Flask, request, jsonify, render_template_string
import sqlite3
from datetime import datetime
app = Flask(__name__)
# Clasa pentru serverul SQL
class SQLiteServer:
def __init__(self, db_name):
self.db_name = db_name
self.init_db()
def init_db(self):
conn = sqlite3.connect(self.db_name)
c = conn.cursor()
c.execute('''
CREATE TABLE IF NOT EXISTS users (
id INTEGER PRIMARY KEY,
first_name TEXT,
last_name TEXT,
occupation TEXT,
hobby TEXT,
year_of_birth INTEGER,
age INTEGER
)
''')
conn.commit()
conn.close()
def calculate_age(self, year_of_birth):
# Adjust year_of_birth if only two digits are provided
if len(str(year_of_birth)) == 2:
if year_of_birth > int(str(datetime.now().year)[-2:]):
year_of_birth += 1900
else:
year_of_birth += 2000
current_year = datetime.now().year
return current_year - year_of_birth
def add_user(self, first_name, last_name, occupation, hobby, year_of_birth):
age = self.calculate_age(year_of_birth)
conn = sqlite3.connect(self.db_name)
c = conn.cursor()
c.execute('''
INSERT INTO users (first_name, last_name, occupation, hobby, year_of_birth, age)
VALUES (?, ?, ?, ?, ?, ?)
''', (first_name, last_name, occupation, hobby, year_of_birth, age))
conn.commit()
conn.close()
def get_users(self):
conn = sqlite3.connect(self.db_name)
c = conn.cursor()
c.execute("SELECT * FROM users")
users = c.fetchall()
conn.close()
return users
def get_users_jsonify():
conn = sqlite3.connect('sqlite_database.db')
c = conn.cursor()
c.execute("SELECT * FROM users")
users = c.fetchall()
conn.close()
return jsonify(users)
# Clasa pentru serverul web
class WebServer:
def __init__(self, sqlite_server):
self.sqlite_server = sqlite_server
def run(self):
app.run(debug=True)
# adauga user si buton de redirect la pagina users
@app.route('/')
def index():
users = sqlite_server.get_users()
return render_template_string('''
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Flask website for testing cypress with sqlite</title>
</head>
<body>
<h2>Add User</h2>
<form action="/add_user" method="post">
First Name: <input type="text" name="first_name"><br>
Last Name: <input type="text" name="last_name"><br>
Occupation: <input type="text" name="occupation"><br>
Hobby: <input type="text" name="hobby"><br>
Year of Birth: <input type="text" name="year_of_birth"><br>
<input type="submit" value="Add User">
</form>
<a href="http://127.0.0.1:5000/users"><button type="button">Show Users</button></a>
</body>
</html>
''', users=users)
@app.route('/add_user', methods=['POST'])
def add_user():
first_name = request.form['first_name']
last_name = request.form['last_name']
occupation = request.form['occupation']
hobby = request.form['hobby']
year_of_birth = int(request.form['year_of_birth'])
sqlite_server.add_user(first_name, last_name, occupation, hobby, year_of_birth)
return 'User added successfully! <a href="/">Go back</a>'
@app.route('/users', methods=['GET'])
def get_users():
query_type = request.args.get('query_type', 'simple')
conn = sqlite3.connect('sqlite_database.db')
c = conn.cursor()
try:
c.execute('SELECT name FROM sqlite_master WHERE type="table" AND name="users"')
if not c.fetchone():
return jsonify({"error": "Table 'users' does not exist"})
if query_type == 'advanced':
# Advanced query logic
first_name = request.args.get('first_name')
last_name = request.args.get('last_name')
occupation = request.args.get('occupation')
hobby = request.args.get('hobby')
year_of_birth = request.args.get('year_of_birth')
query = 'SELECT * FROM users WHERE 1=1'
params = []
# Exemple query simple
# Basic query: /users
# Simple query: /users?query_type=simple for simple selection
# Addvanced query: /users?query_type=advanced&first_name=John&occupation=Engineer for advanced querying
# Advanced query with name search: /users?query_type=advanced&first_name=John&last_name=Doe
# Query by occupation: /users?query_type=advanced&occupation=Engineer
# Query by hobby: /users?query_type=advanced&hobby=Reading
# Query by year of birth: /users?query_type=advanced&year_of_birth=1990
if first_name:
query += ' AND first_name LIKE ?'
params.append(f'%{first_name}%')
if last_name:
query += ' AND last_name LIKE ?'
params.append(f'%{last_name}%')
if occupation:
query += ' AND occupation LIKE ?'
params.append(f'%{occupation}%')
if hobby:
query += ' AND hobby LIKE ?'
params.append(f'%{hobby}%')
if year_of_birth:
query += ' AND year_of_birth = ?'
params.append(year_of_birth)
# Query by minimum age: /users?query_type=advanced&min_age=30
# Query by maximum age: /users?query_type=advanced&max_age=50
# Query with ordering: /users?query_type=advanced&order_by=last_name
# Query with limit: /users?query_type=advanced&limit=10
# Combined query: /users?query_type=advanced&first_name=John&occupation=Engineer&min_age=25&order_by=year_of_birth&limit=5
# Additional advanced query options
for param, value in request.args.items():
match param:
case 'min_age':
query += ' AND (? - year_of_birth) >= ?'
params.extend([datetime.now().year, int(value)])
case 'max_age':
query += ' AND (? - year_of_birth) <= ?'
params.extend([datetime.now().year, int(value)])
case 'order_by':
query += f' ORDER BY {value}'
case 'limit':
query += ' LIMIT ?'
params.append(int(value))
c.execute(query, params)
else:
# Simple query logic
c.execute('SELECT * FROM users')
users = c.fetchall()
except sqlite3.OperationalError as e:
return jsonify({"error": str(e)})
finally:
conn.close()
return jsonify(users)
# Instanțierea serverului SQL și a serverului web
sqlite_server = SQLiteServer('sqlite_database.db')
web_server = WebServer(sqlite_server)
if __name__ == '__main__':
web_server.run()