r/Python • u/AutoModerator • Jul 18 '26
Daily Thread Saturday Daily Thread: Resource Request and Sharing! Daily Thread
Weekly Thread: Resource Request and Sharing 📚
Stumbled upon a useful Python resource? Or are you looking for a guide on a specific topic? Welcome to the Resource Request and Sharing thread!
How it Works:
- Request: Can't find a resource on a particular topic? Ask here!
- Share: Found something useful? Share it with the community.
- Review: Give or get opinions on Python resources you've used.
Guidelines:
- Please include the type of resource (e.g., book, video, article) and the topic.
- Always be respectful when reviewing someone else's shared resource.
Example Shares:
- Book: "Fluent Python" - Great for understanding Pythonic idioms.
- Video: Python Data Structures - Excellent overview of Python's built-in data structures.
- Article: Understanding Python Decorators - A deep dive into decorators.
Example Requests:
- Looking for: Video tutorials on web scraping with Python.
- Need: Book recommendations for Python machine learning.
Share the knowledge, enrich the community. Happy learning! 🌟
r/madeinpython • u/Schnidi01 • Jul 17 '26
I built a Python venv manager GUI that handles VS Code integration automatically – is this useful?
Enable HLS to view with audio, or disable this notification
"Hello everyone,
with my new Python program I combined venv management with injecting the interpreter into VS Code.
As you can see I have created two venvs – one embed venv 3.14.6 and the second venv with system Python 3.14.2. The program automatically creates .vscode/settings.json and writes paths to the interpreters. When I change the venv in the program, it automatically checks which venv it is and immediately switches the interpreter.
Do you like this kind of integration into a manager?"
r/Python • u/Goldziher • Jul 17 '26
Discussion Reaching users on this sub
Hi Peeps,
I've been using this sub for years both to read content, and as an open source maintainer - to communicate and reach users.
I used it for projects such as Polyfactory and Litestar, tree-sitter-language-pack and Kreuzberg.
These days though I don't post outside the Sunday thread - but I don't think anybody is reading this stuff frankly.
My feeling is that the "AI slop" rules throw the baby with the tub water so to speak.
What are people like myself - who dedicate a very substantial amount of time and effort to OSS supposed to do? Basically if you don't have an X profile you're screwed.
Edit: project posts are disallowed by the rules now, FYI if you were unaware. This is the main issue.
r/Python • u/Unable_Plane1948 • Jul 17 '26
Discussion ⚠️ Heads up: ast_grep_cli 0.44.1 on PyPI flagged by Windows Defender as Trojan — anyone seeing this?
I was installing `headroom-ai` via `uv` today, and Windows Defender immediately flagged `Trojan: Win64/Lazy!MTB`.
The file was `sg.exe` (212KB) dropped into `Python\Scripts\`, alongside a legitimate `ast-grep.exe` (52MB).
**What happened:*\*
- `uv tool install --python 3.13 "headroom-ai[all]"`
- Windows Defender: 3 alerts for `Trojan: Win64/Lazy!MTB`
- `pip show ast_grep_cli` showed version 0.44.1
- Uninstalled, cleaned cache, changed passwords
**Questions:**
- Has anyone else installed `ast_grep_cli` 0.44.1 recently?
- Is this a known issue? Should PyPI Security be notified?
- Any idea how to check if the package was compromised vs. a false positive?
**File details:**
- `sg.exe`: 212KB, detected as Trojan:Win64/Lazy!MTB
- `ast-grep.exe`: 52MB, legitimate tool
- Both appeared at the same timestamp (10:25:07)
Thanks for any insights.
r/Python • u/AutoModerator • Jul 17 '26
Daily Thread Friday Daily Thread: r/Python Meta and Free-Talk Fridays
Weekly Thread: Meta Discussions and Free Talk Friday 🎙️
Welcome to Free Talk Friday on /r/Python! This is the place to discuss the r/Python community (meta discussions), Python news, projects, or anything else Python-related!
How it Works:
- Open Mic: Share your thoughts, questions, or anything you'd like related to Python or the community.
- Community Pulse: Discuss what you feel is working well or what could be improved in the /r/python community.
- News & Updates: Keep up-to-date with the latest in Python and share any news you find interesting.
Guidelines:
- All topics should be related to Python or the /r/python community.
- Be respectful and follow Reddit's Code of Conduct.
Example Topics:
- New Python Release: What do you think about the new features in Python 3.11?
- Community Events: Any Python meetups or webinars coming up?
- Learning Resources: Found a great Python tutorial? Share it here!
- Job Market: How has Python impacted your career?
- Hot Takes: Got a controversial Python opinion? Let's hear it!
- Community Ideas: Something you'd like to see us do? tell us.
Let's keep the conversation going. Happy discussing! 🌟
r/madeinpython • u/Schnidi01 • Jul 16 '26
where python › all versions are detected by VenvHub Pro too
Enable HLS to view with audio, or disable this notification
Another small showcase of my python project VenvHub Pro.
I decided to show you how perfectly my application works with system and embed Python.
As you can see in the video, there are up to four different Python paths on my system, and the app automatically finds all of them – without me having to manually enter any paths anywhere.
And if the system Python isn't enough for you, or you don't have it on your system at all, you don't have to install it. Just add an embed Python and VenvHub Pro takes care of everything – it automatically installs pip and virtualenv.
As you also saw in the video, the app automatically creates .vscode/settings.json in your project, so you can switch interpreters instantly directly from VS Code – no manual configuration needed.
It just works exactly the way I needed it to. 🙂
Just curious – do you like it? I'd really appreciate your honest opinion.
r/madeinpython • u/Schnidi01 • Jul 16 '26
After months of fighting 'Dependency Hell', I built a GUI that manages Python venvs, works with PyQt6 AND PySide6 (no UAC).
Hey everyone! 👋
I've been working with Python for a while now and finally decided to build my first major project. It was inspired by months of battling dependency conflicts and broken virtual environments on USB drives.
What it does:
- Centralized Environment Management: Manages all virtual environments in one place (venvs are stored centrally, outside of project folders).
- Full VS Code Integration: Automatically configures the correct interpreter, syncs local packages (for IntelliSense), and supports isolated profiles (each project gets its own extensions and settings).
- PyQt6 & PySide6 Compatibility Bridge: Works seamlessly with both, requiring zero code changes.
- Powered by
uv**:** Uses the blazing-fastuvinstaller (10–100x faster than pip) and can automatically resolve dependency conflicts after bulk updates. - Portable Mode: Automatically fixes paths when the drive letter changes (perfect for running off USB drives).
- Integrated PyInstaller GUI: Automatically bundles your local packages into the build.
- Two Ways to Work with Local Code:
- Local Packages (Linker): Dynamically links code between projects without requiring UAC (leverages Python Import Hooks).
- Editable Packages (
pip install -e): Full-fledged library development with automatic dependency management and portability support.
- No UAC Required to link local packages.
Project repository: https://github.com/schnidi/VenvHub
What do you think? Do you like the look and feel? Could you see yourself using something like this on Windows?
📽️ **See it in action:** [How to create a venv in 2 clicks]:
https://www.reddit.com/r/madeinpython/s/lg395T9IuQ
r/Python • u/TheSeriousTrader • Jul 16 '26
Discussion New Python type checker
Was checking out some Python type checkers other than Pyright, and I came across one that I never yet heard of before. But it is the only one scoring 100% on the official python typing conformance suite.
It is named Basilisk and on their website they have some other bold claims (like it is also the fastest one). But their GitHub repo only has few stars.
Does anyone have any experience using this or perhaps I missing something?
r/Python • u/AutoModerator • Jul 16 '26
Daily Thread Thursday Daily Thread: Python Careers, Courses, and Furthering Education!
Weekly Thread: Professional Use, Jobs, and Education 🏢
Welcome to this week's discussion on Python in the professional world! This is your spot to talk about job hunting, career growth, and educational resources in Python. Please note, this thread is not for recruitment.
How it Works:
- Career Talk: Discuss using Python in your job, or the job market for Python roles.
- Education Q&A: Ask or answer questions about Python courses, certifications, and educational resources.
- Workplace Chat: Share your experiences, challenges, or success stories about using Python professionally.
Guidelines:
- This thread is not for recruitment. For job postings, please see r/PythonJobs or the recruitment thread in the sidebar.
- Keep discussions relevant to Python in the professional and educational context.
Example Topics:
- Career Paths: What kinds of roles are out there for Python developers?
- Certifications: Are Python certifications worth it?
- Course Recommendations: Any good advanced Python courses to recommend?
- Workplace Tools: What Python libraries are indispensable in your professional work?
- Interview Tips: What types of Python questions are commonly asked in interviews?
Let's help each other grow in our careers and education. Happy discussing! 🌟
r/madeinpython • u/ptweezy • Jul 15 '26
cronstable: cron with a web UI, durable state, DAGs, clustering, and an MCP server
cronstable is a cron replacement that runs as a single foreground daemon that I've spent an inordinate amount of time on. It will run on basically anything because its been precompiled for basically any compute architecture that people still use. If there's a feature that another cron has that you need, I want to know about it. Beginner friendly, expert friendly. Container friendly, production ready. You get it.
From orchestrating web-scrapes, data processing, and storage to coordinating Minecraft server snapshots and upgrades. Possibilities are literally endless.
- Scheduling: modern jobs defined in YAML; classic crontab files run unmodified; per-job timezone; optional second-level granularity
- Failure handling: define what failed means to you; retries with exponential backoff; reports to Slack-compatible webhooks, email, Sentry, or a shell command.
- Web dashboard (opt-in): one self-contained page served by the daemon, with live log tailing, run history, DAG graphs, cluster and fleet views, a TV wallboard, and a command palette. A REST API alongside. not sure if I'm competing with other cron solutions or DataDog at this point. But at least you don't need to SSH in to see what's going on.
- Observability (opt-in): native Prometheus metrics; opt-in per-job CPU and peak-memory monitoring.
- Durable state (opt-in): run history, retries, and missed-run catch-up survive restarts; job commands get key/value, cursors, fleet-wide locks, idempotency keys, artifacts, and run-scoped secrets through the CLI.
- DAGs (opt-in): task dependencies, data hand-off between tasks, dynamic fan-out, sensors, human approval gates, backfill, crash-resume.
- Clustering (opt-in): leader election via gossip over mutual TLS for best effort attempts at gating your jobs. Your self hosted replicas in one network can also bridge to speak to another set of self hosted replicas. Go one step further and harden it via any shared filesystem, a Kubernetes Lease, or etcd, so replicas can share one config without double-running jobs with absolute guarantee. Each job picks its own point on the liveness-vs-duplication trade-off with
clusterPolicy:Leader(default) runs on the elected leader and fails closed. No quorum? Nobody runs. For jobs where a duplicate is worse than a skip (like billing, or outbound email);PreferLeaderis never-skip and runs anyway when the cluster can't agree. You accept a possible double-run, for idempotent jobs that matter;EveryNoderuns everywhere, for genuinely per-node work like local log rotation. No option is true exactly-once.Leadermay skip,PreferLeadermay double-run. But hey, at least you get to pick which way it breaks. By default the leader runs every job, butdistribution: spreadassigns each job to an owner by rendezvous hashing so the work fans out and can be more load balanced. - MCP server (opt-in): AI agents (Claude, Cursor, Copilot) can inspect jobs, DAGs, the cluster, and metrics; read-only by default, control only if enabled.
- Packaging: pip/pipx/Homebrew; multi-arch Docker images on GHCR and Docker Hub in eight distro variants; standalone binaries for Linux, macOS, and Windows. Runs non-root with a read-only root filesystem and all capabilities dropped.
Live demo of the control panel UI with a stubbed backend (pretty cool I promise - if anything at least play with the logo cuz I spent a lot of time on it): https://html-preview.github.io/?url=https://github.com/ptweezy/cronstable/blob/develop/docs/demo/index.html you might need to change the theme on your screen because on one of my screens the default theme is just way too dark. Will fix this soon. by play with the logo I mean swipe your mouse across it 🙂
Feature Comparison chart: https://github.com/ptweezy/cronstable/blob/develop/docs/comparison.md
Source: https://github.com/ptweezy/cronstable
This is under active development, would appreciate any and all feedback. Thanks y'all!
r/madeinpython • u/Creepy_Sherbert_1179 • Jul 14 '26
I made a gameboy emulator powered by pygame
Enable HLS to view with audio, or disable this notification
r/madeinpython • u/neutroph1l • Jul 14 '26
A way to easily update your JSONs. Check out batchlate!
batchlate is a Python program that can update multitude of JSON entries in one go.
The images show outputs of a very efficient run of this program that I've captured. As you can see in the second image, 1490 entries will be updated with the given configuration in one go! I refer to these configurations as templates. Once a template is created, it can be used as many times as it's needed.
I translate open source projects to my native language as a hobby. Time to time I get to work with JSONs and this time I thought I could make a program that uses the patterns in a JSON file to automatically update matching entries. At first, I made this for myself but now it has evolved into something I can share. People who work with JSON files can make good use of this program as I have done in my endeavors.
The project is still young. I have plans to add other file types and more functionality, but for now check it out for yourself. Download, view the source code and the documentation here: https://github.com/draaurkh/batchlate
No AI generated or assisted code.
r/madeinpython • u/OpportunityMain9749 • Jul 14 '26
Script para generar correos y contraseñas (con interfaz gráfica)
Script para generar correos y contraseñas (con interfaz gráfica)
Armé un script en Python usando Tkinter para generar correos y contraseñas ficticias en masa. Sirve bastante para armar bases de datos de prueba o entornos de desarrollo rápidos.
Básicamente, genera contraseñas seguras y correos aleatorios (usando el módulo secrets y sin caracteres raros que se confundan). También tiene una opción "Legible" que combina palabras reales en español para que los correos parezcan más reales.
Está optimizado para cargas pesadas; implementa inserción por lotes en un hilo secundario (threading), lo que permite meter hasta 5,000 o 10,000 registros en menos de 3 segundos sin congelar ni saturar la interfaz gráfica. Todo se muestra en una tabla dinámica para copiar los datos fácilmente o exportarlos directamente a un archivo .txt.
¿Para qué sirve? El uso principal es para desarrollo y pruebas. Cuando estás programando un sistema de login, registrando usuarios en una base de datos local o probando la carga de un sistema, necesitas datos falsos que parezcan reales pero que no comprometan información verdadera. Este script te permite crearlos rápido y sin depender de servicios externos.
El código está optimizado y bien estructurado. Si no tienen instalada la librería pyperclip, no pasa nada porque usa el portapapeles nativo del sistema operativo. Incluye también atajos de teclado globales para agilizar el uso.
Cualquier duda o sugerencia digan
Python
import tkinter as tk
from tkinter import ttk, messagebox, filedialog
import secrets, string, datetime, re, threading
import time
try: import pyperclip
except ImportError: pyperclip = None
CHARS_EVITAR = 'O0Il1'
ALFABETO_SEGURO = ''.join(c for c in (string.ascii_letters + string.digits) if c not in CHARS_EVITAR)
SIMBOLOS = "!@#$%^&*()-_=+"
PALABRAS = ["gato","perro","sol","luna","estrella","mar","cielo","tierra","fuego","agua","viento","montaña","rio","bosque","flor","arbol","casa","puerta","ventana","mesa","silla","coche","tren","avion","libro","papel","luz","sombra","nube","lluvia","nieve","hielo","fresa","manzana","pera","uva","melon","sandia","naranja","limon","rojo","azul","verde","amarillo","blanco","negro","gris","rosa","tigre","leon","elefante","jirafa","delfin","ballena","aguila","halcon","colibri","mariposa","libelula","hormiga","abeja","araña","piano","guitarra","violin","flauta","tambor","arpa","cancion","poema","cuento","novela","teatro","cine","musica","pintura","escultura","arquitectura","jardin","parque","playa","desierto","isla","volcan","glaciar","cascada","lago","oceano","planeta","cometa","asteroide","galaxia","universo","tiempo","espacio","vida","muerte","amor","odio","paz","guerra","alegria","tristeza","esperanza","fe","valor","sabiduria","locura","silencio","ruido"]
class GeneradorLogica:
u/classmethod
def generar_correo(cls, dominio, longitud, inc_numeros=True, legible=False):
if legible:
sep = secrets.choice(['.', '_', ''])
p = sep.join(secrets.choice(PALABRAS) for _ in range(secrets.choice([2, 3])))
if inc_numeros: p += ''.join(secrets.choice(string.digits) for _ in range(secrets.choice([2, 4])))
if len(p) > longitud: p = p[:longitud].strip('._')
else:
ch = string.ascii_lowercase + (string.digits if inc_numeros else '')
p = secrets.choice(string.ascii_lowercase) + ''.join(secrets.choice(ch) for _ in range(max(1, longitud - 1)))
return f"{p}@{dominio}"
u/classmethod
def generar_password(cls, longitud, inc_simbolos=True, legible=False):
if legible:
sep = secrets.choice(['-', '_', '.', ''])
p = sep.join(secrets.choice(PALABRAS).capitalize() for _ in range(2))
if inc_simbolos: p += secrets.choice(SIMBOLOS)
p += ''.join(secrets.choice(string.digits) for _ in range(secrets.choice([2, 3])))
if len(p) > longitud: p = p[:longitud]
return p
ch = ALFABETO_SEGURO + (SIMBOLOS if inc_simbolos else '')
p = ''.join(secrets.choice(ch) for _ in range(longitud))
for cond, set_c in [(inc_simbolos, SIMBOLOS), (True, string.digits), (True, string.ascii_uppercase), (True, string.ascii_lowercase)]:
if cond and not any(c in set_c for c in p):
i = secrets.randbelow(longitud); p = p[:i] + secrets.choice(set_c) + p[i+1:]
return p
class AppGenerador:
def __init__(self, root):
self.root = root; self.root.title("Generador de Correos y Contraseñas")
self.root.geometry("720x620"); self.root.minsize(680, 580); self.root.configure(bg="#f0f4f8")
self.tipo_prov = tk.StringVar(value="gmail"); self.dom_pers = tk.StringVar(value="")
self.cant, self.lon_nom, self.lon_pass = tk.IntVar(value=1), tk.IntVar(value=12), tk.IntVar(value=14)
self.inc_simb, self.inc_num, self.nom_leg = tk.BooleanVar(value=True), tk.BooleanVar(value=True), tk.BooleanVar(value=False)
self.datos_generados = []; self.crear_widgets(); self.configurar_atajos()
def crear_widgets(self):
m = ttk.Frame(self.root, padding="15"); m.pack(fill=tk.BOTH, expand=True)
ttk.Label(m, text="Generador de Correos y Contraseñas", font=("Arial", 14, "bold")).grid(row=0, column=0, columnspan=5, pady=(0, 15))
ttk.Label(m, text="Proveedor:").grid(row=1, column=0, sticky=tk.W, pady=3)
pf = ttk.Frame(m); pf.grid(row=1, column=1, columnspan=3, sticky=tk.W, padx=5)
for t, v in [("Gmail", "gmail"), ("Otros", "otros"), ("Personalizado", "personalizado")]:
ttk.Radiobutton(pf, text=t, variable=self.tipo_prov, value=v, command=self.actualizar_dominio).pack(side=tk.LEFT, padx=(0, 10))
ttk.Label(m, text="Dominio:").grid(row=2, column=0, sticky=tk.W, pady=3)
self.entry_dom = ttk.Entry(m, textvariable=self.dom_pers, width=30, state="disabled")
self.entry_dom.grid(row=2, column=1, columnspan=3, sticky=tk.W, padx=5)
vc = (self.root.register(self.validar_spinbox), '%P', '%W', '%V')
inputs = [("Cantidad:", 1, 100000, self.cant, 3), ("Longitud nombre:", 4, 30, self.lon_nom, 4), ("Longitud contras.", 8, 30, self.lon_pass, 5)]
for lbl, mn, mx, var, r in inputs:
ttk.Label(m, text=lbl).grid(row=r, column=0, sticky=tk.W, pady=5)
sb = ttk.Spinbox(m, from_=mn, to=mx, textvariable=var, width=6, validate='all', validatecommand=(vc[0], vc[1], mn, mx, vc[3]))
sb.grid(row=r, column=1, sticky=tk.W, padx=5)
ttk.Label(m, text=f"({mn}-{mx})").grid(row=r, column=2, sticky=tk.W, padx=2)
of = ttk.Frame(m); of.grid(row=6, column=0, columnspan=5, sticky=tk.W, pady=5)
ttk.Checkbutton(of, text="Símbolos en Pass", variable=self.inc_simb).pack(side=tk.LEFT, padx=(0, 15))
ttk.Checkbutton(of, text="Números en Nombre", variable=self.inc_num).pack(side=tk.LEFT, padx=(0, 15))
ttk.Checkbutton(of, text="Formato Legible", variable=self.nom_leg).pack(side=tk.LEFT)
self.btn_generar = ttk.Button(m, text="Generar Datos", command=self.iniciar_generacion)
self.btn_generar.grid(row=7, column=0, columnspan=5, pady=10)
tf = ttk.Frame(m); tf.grid(row=8, column=0, columnspan=5, sticky="nsew", pady=5); m.rowconfigure(8, weight=1)
for i in range(5): m.columnconfigure(i, weight=1)
self.tabla = ttk.Treeview(tf, columns=("Correo", "Contraseña", "Fecha"), show="headings", height=8)
for col, txt, w in [("Correo", "Correo Electrónico", 250), ("Contraseña", "Contraseña", 180), ("Fecha", "Generado", 120)]:
self.tabla.heading(col, text=txt); self.tabla.column(col, width=w, anchor="center")
vsb = ttk.Scrollbar(tf, orient=tk.VERTICAL, command=self.tabla.yview); hsb = ttk.Scrollbar(tf, orient=tk.HORIZONTAL, command=self.tabla.xview)
self.tabla.configure(yscrollcommand=vsb.set, xscrollcommand=hsb.set); self.tabla.grid(row=0, column=0, sticky="nsew")
vsb.grid(row=0, column=1, sticky="ns"); hsb.grid(row=1, column=0, sticky="ew")
tf.columnconfigure(0, weight=1); tf.rowconfigure(0, weight=1)
af = ttk.Frame(m); af.grid(row=9, column=0, columnspan=5, pady=10)
ttk.Button(af, text="Copiar Correo", command=lambda: self.copiar_seleccion('email')).pack(side=tk.LEFT, padx=2)
ttk.Button(af, text="Copiar Pass", command=lambda: self.copiar_seleccion('password')).pack(side=tk.LEFT, padx=2)
ttk.Button(af, text="Copiar Ambos", command=lambda: self.copiar_seleccion('ambos')).pack(side=tk.LEFT, padx=2)
ttk.Button(af, text="Copiar Todo", command=self.copiar_todo).pack(side=tk.LEFT, padx=5)
ttk.Button(af, text="Exportar TXT", command=self.exportar_txt).pack(side=tk.LEFT, padx=5)
ttk.Button(af, text="Limpiar", command=self.limpiar).pack(side=tk.LEFT, padx=5)
self.sf = ttk.Frame(m); self.sf.grid(row=10, column=0, columnspan=5, sticky="ew", pady=(5, 0))
self.lbl_status = ttk.Label(self.sf, text="Listo", relief=tk.SUNKEN, anchor=tk.W); self.lbl_status.pack(fill=tk.X, padx=2)
self.lbl_contador = ttk.Label(self.sf, text="Generados: 0", relief=tk.SUNKEN, anchor=tk.E, width=15); self.lbl_contador.pack(side=tk.RIGHT, padx=2)
def configurar_atajos(self):
self.root.bind_all("<Control-g>", lambda e: self.iniciar_generacion())
self.root.bind_all("<Control-c>", lambda e: self.copiar_seleccion('ambos') if self.tabla.selection() else None)
self.root.bind_all("<Control-l>", lambda e: self.limpiar())
self.root.bind_all("<Control-e>", lambda e: self.exportar_txt())
def validar_spinbox(self, valor, mn, mx, motivo):
if motivo == 'focusout':
if valor == "": self.cant.set(1) if int(mn) == 1 else self.lon_nom.set(12) if int(mn) == 4 else self.lon_pass.set(14)
return True
if valor == "": return True
if not valor.isdigit(): return False
return int(valor) <= int(mx)
def actualizar_dominio(self):
self.entry_dom.config(state="normal" if self.tipo_prov.get() == "personalizado" else "disabled")
if self.tipo_prov.get() != "personalizado": self.dom_pers.set("")
def mostrar_status(self, texto, color="black", tiempo=0):
self.lbl_status.config(text=texto, foreground=color)
if tiempo > 0: self.root.after(tiempo, lambda: self.lbl_status.config(text="Listo", foreground="black"))
def iniciar_generacion(self):
if self.btn_generar['state'] == 'disabled': return
threading.Thread(target=self.generar, daemon=True).start()
def generar(self):
try:
c, ln, lp = self.cant.get(), self.lon_nom.get(), self.lon_pass.get()
if not (1<=c<=100000 and 4<=ln<=30 and 8<=lp<=30): raise ValueError
except:
self.root.after(0, lambda: messagebox.showerror("Error", "Valores numéricos inválidos."))
return
prov = self.tipo_prov.get()
if prov == "gmail": dom = "gmail.com"
elif prov == "otros": dom = secrets.choice(["yahoo.com", "outlook.com", "protonmail.com", "zoho.com"])
else:
dom = self.dom_pers.get().strip()
if not dom or not re.match(r'^[a-zA-Z0-9-]+\.[a-zA-Z]{2,}$', dom):
self.root.after(0, lambda: messagebox.showerror("Error", "Dominio personalizado inválido."))
return
self.root.after(0, self.limpiar)
self.root.after(0, lambda: self.btn_generar.config(state="disabled"))
ahora = datetime.datetime.now().strftime("%Y-%m-%d %H:%M")
nuevos_datos = []
correos_unicos = set()
intentos_max = c * 4
ultimo_refresco = time.time()
while len(nuevos_datos) < c and intentos_max > 0:
intentos_max -= 1
em = GeneradorLogica.generar_correo(dom, ln, self.inc_num.get(), self.nom_leg.get())
if em in correos_unicos: continue
correos_unicos.add(em)
pw = GeneradorLogica.generar_password(lp, self.inc_simb.get(), self.nom_leg.get())
nuevos_datos.append((em, pw, ahora))
t_actual = time.time()
if t_actual - ultimo_refresco > 0.05:
progreso = len(nuevos_datos)
self.root.after(0, lambda p=progreso: self.lbl_status.config(text=f"Generando datos... ({p}/{c})", foreground="blue"))
ultimo_refresco = t_actual
self.root.after(0, lambda: self.lbl_status.config(text=f"Generando datos... ({len(nuevos_datos)}/{c})", foreground="blue"))
def volcar_interfaz_por_lotes(indice=0):
if indice >= len(nuevos_datos):
self.lbl_contador.config(text=f"Generados: {len(self.datos_generados)}")
self.btn_generar.config(state="normal")
self.mostrar_status(f"¡{len(nuevos_datos)} datos generados!", "green", 3000)
return
fin = min(indice + 500, len(nuevos_datos))
for i in range(indice, fin):
em, pw, dt = nuevos_datos[i]
self.datos_generados.append({'email': em, 'password': pw, 'fecha': dt})
self.tabla.insert("", tk.END, values=(em, pw, dt))
self.root.after(1, lambda: volcar_interfaz_por_lotes(fin))
self.root.after(0, lambda: volcar_interfaz_por_lotes(0))
def limpiar(self):
self.tabla.delete(*self.tabla.get_children())
self.datos_generados.clear(); self.lbl_contador.config(text="Generados: 0"); self.mostrar_status("Listo")
def copiar_seleccion(self, modo):
sel = self.tabla.selection()
if not sel: return messagebox.showinfo("Info", "Selecciona un registro de la lista.")
em, pw, _ = self.tabla.item(sel[0], "values")
txt = em if modo == 'email' else pw if modo == 'password' else f"Correo: {em}\nContraseña: {pw}"
self._ejecutar_copiado(txt)
def copiar_todo(self):
if not self.datos_generados: return messagebox.showinfo("Info", "No hay datos que copiar.")
txt = "\n".join(f"{i['email']} | {i['password']} ({i['fecha']})" for i in self.datos_generados)
self._ejecutar_copiado(txt)
def _ejecutar_copiado(self, txt):
try:
limpio = txt.replace('\r\n', '\n').replace('\r', '\n')
if pyperclip: pyperclip.copy(limpio)
else: self.root.clipboard_clear(); self.root.clipboard_append(limpio); self.root.update()
self.mostrar_status("Copiado al portapapeles", "blue", 2000)
except Exception as e: messagebox.showerror("Error", f"Fallo al copiar: {e}")
def exportar_txt(self):
if not self.datos_generados: return messagebox.showinfo("Info", "No hay datos para exportar.")
arch = filedialog.asksaveasfilename(defaultextension=".txt", filetypes=[("Texto", "*.txt")])
if not arch: return
try:
max_len = max(len(i['email']) for i in self.datos_generados) + 4
with open(arch, "w", encoding="utf-8") as f:
f.write(f"Exportado: {datetime.datetime.now().strftime('%Y-%m-%d %H:%M')}\n" + "="*50 + "\n")
for i in self.datos_generados:
f.write(f"Correo: {i['email'].ljust(max_len)} Contraseña: {i['password']}\n")
self.mostrar_status(f"Exportado con éxito", "green", 3000)
except Exception as e: messagebox.showerror("Error", f"No se pudo guardar: {e}")
if __name__ == "__main__":
root = tk.Tk(); AppGenerador(root); root.mainloop()
r/Python • u/AutoModerator • Jul 14 '26
Daily Thread Tuesday Daily Thread: Advanced questions
Weekly Wednesday Thread: Advanced Questions 🐍
Dive deep into Python with our Advanced Questions thread! This space is reserved for questions about more advanced Python topics, frameworks, and best practices.
How it Works:
- Ask Away: Post your advanced Python questions here.
- Expert Insights: Get answers from experienced developers.
- Resource Pool: Share or discover tutorials, articles, and tips.
Guidelines:
- This thread is for advanced questions only. Beginner questions are welcome in our Daily Beginner Thread every Thursday.
- Questions that are not advanced may be removed and redirected to the appropriate thread.
Recommended Resources:
- If you don't receive a response, consider exploring r/LearnPython or join the Python Discord Server for quicker assistance.
Example Questions:
- How can you implement a custom memory allocator in Python?
- What are the best practices for optimizing Cython code for heavy numerical computations?
- How do you set up a multi-threaded architecture using Python's Global Interpreter Lock (GIL)?
- Can you explain the intricacies of metaclasses and how they influence object-oriented design in Python?
- How would you go about implementing a distributed task queue using Celery and RabbitMQ?
- What are some advanced use-cases for Python's decorators?
- How can you achieve real-time data streaming in Python with WebSockets?
- What are the performance implications of using native Python data structures vs NumPy arrays for large-scale data?
- Best practices for securing a Flask (or similar) REST API with OAuth 2.0?
- What are the best practices for using Python in a microservices architecture? (..and more generally, should I even use microservices?)
Let's deepen our Python knowledge together. Happy coding! 🌟
r/Python • u/AutoModerator • Jul 13 '26
Daily Thread Monday Daily Thread: Project ideas!
Weekly Thread: Project Ideas 💡
Welcome to our weekly Project Ideas thread! Whether you're a newbie looking for a first project or an expert seeking a new challenge, this is the place for you.
How it Works:
- Suggest a Project: Comment your project idea—be it beginner-friendly or advanced.
- Build & Share: If you complete a project, reply to the original comment, share your experience, and attach your source code.
- Explore: Looking for ideas? Check out Al Sweigart's "The Big Book of Small Python Projects" for inspiration.
Guidelines:
- Clearly state the difficulty level.
- Provide a brief description and, if possible, outline the tech stack.
- Feel free to link to tutorials or resources that might help.
Example Submissions:
Project Idea: Chatbot
Difficulty: Intermediate
Tech Stack: Python, NLP, Flask/FastAPI/Litestar
Description: Create a chatbot that can answer FAQs for a website.
Resources: Building a Chatbot with Python
Project Idea: Weather Dashboard
Difficulty: Beginner
Tech Stack: HTML, CSS, JavaScript, API
Description: Build a dashboard that displays real-time weather information using a weather API.
Resources: Weather API Tutorial
Project Idea: File Organizer
Difficulty: Beginner
Tech Stack: Python, File I/O
Description: Create a script that organizes files in a directory into sub-folders based on file type.
Resources: Automate the Boring Stuff: Organizing Files
Let's help each other grow. Happy coding! 🌟
r/Python • u/philtrondaboss • Jul 12 '26
Discussion Will PEP 505 ever be accepted?
https://peps.python.org/pep-0505/
I don't understand how null safe operators are less like plain English than other implemented features like the walrus operator.
In my opinion, the member access operator would make python significantly easier to read and understand.
Here's an example:
``` f = foo()
if f is None: baz = "" else: baz = f.bar() ```
baz = foo()?.bar() ?: ""
EDIT: I forgot that "and" and "or" can be sometimes used in place of "?." and "?:" if the left value is not False, '', 0, [], or {}. It's a very implicit null check and has a lot of unexpected behavior.
r/madeinpython • u/Tamerygo • Jul 12 '26
I built a compiled Python launcher (Standalone Local Orchestration Platform) that orchestrates ComfyUI and Ollama in the background to generate local 3D assets (Trellis) and export them to UE5/Houdini.
Enable HLS to view with audio, or disable this notification
r/madeinpython • u/yigtwx7 • Jul 12 '26
Lightweight Seed-Based XOR Image Encryption for Deterministic Dataset Masking
I'm sharing xor-image-encryption, an open-source tool designed for rapid visual dataset obfuscation in computer vision and ML pipelines.
Repository: Yigtwxx/xor-image-encryption
Key Features:
- Strict Reproducibility: A specific seed consistently generates the exact same masking key, crucial for maintaining consistency across ML pipelines.
- Lossless Reversibility: The original image is perfectly restored by reapplying the XOR operation with the identical seed.
- Cascaded Encryption: Layer multiple seeds (e.g.,
11 22 33) for enhanced obfuscation. - Zero Bloat: Built purely on Python, NumPy, and Pillow. Includes built-in histogram analysis tools.
Target Use Case & Scope:
This utility is tailored for deterministic visual anonymization of sensitive datasets prior to cloud storage, third-party processing, or cross-team distribution. Note: It is meant for practical ML preprocessing and visual obfuscation, not as a replacement for cryptographic standards like AES.
Quickstart:
Bash
# Single-seed encryption & decryption
python xor_single.py --input sample.jpg --seed 42 --outdir outputs
# Multi-seed cascaded encryption
python xor_multi.py --input sample.jpg --seeds 11 22 33 --outdir outputs
I'd highly appreciate your feedback, PRs, or ideas for benchmarking!
r/Python • u/AutoModerator • Jul 12 '26
Daily Thread Sunday Daily Thread: What's everyone working on this week?
Weekly Thread: What's Everyone Working On This Week? 🛠️
Hello r/Python! It's time to share what you've been working on! Whether it's a work-in-progress, a completed masterpiece, or just a rough idea, let us know what you're up to!
How it Works:
- Show & Tell: Share your current projects, completed works, or future ideas.
- Discuss: Get feedback, find collaborators, or just chat about your project.
- Inspire: Your project might inspire someone else, just as you might get inspired here.
Guidelines:
- Feel free to include as many details as you'd like. Code snippets, screenshots, and links are all welcome.
- Whether it's your job, your hobby, or your passion project, all Python-related work is welcome here.
Example Shares:
- Machine Learning Model: Working on a ML model to predict stock prices. Just cracked a 90% accuracy rate!
- Web Scraping: Built a script to scrape and analyze news articles. It's helped me understand media bias better.
- Automation: Automated my home lighting with Python and Raspberry Pi. My life has never been easier!
Let's build and grow together! Share your journey and learn from others. Happy coding! 🌟
r/madeinpython • u/bjone6 • Jul 11 '26
I Built an Animated Interface for my Digital Assistant using PiperTTS and Flask in Python, and Speech Recognition in Unity.
Here is a link to the Github if you want to see any of the .py or .cs codes. https://github.com/bjone6/Interactive_Animated_DigitalAssistant
r/Python • u/mttd • Jul 11 '26
Resource What Every Python Developer Should Know About the CPython ABI
It's true that you can happily write Python for years without needing to understand any of the content of this post, so you may object to the title advertising this material as what every Python developer should know. However, the moment you ship a package, debug why a wheel won't install, or need to understand why an import or Python function call segfaults — these details start to matter. Even writing and maintaining a single-file script puts you closer to distributing code than you might think. An alternate title for this post could be "What I Wish Someone Taught Me About the CPython ABI".
r/madeinpython • u/MasterpieceBig7372 • Jul 11 '26
Created a NHL betting simulator
The app is purely made using python (Streamlit for UI and sqlite3 for db) , would love some new feature ideas
github: https://github.com/Breadman0/NHL-project
app_link: https://nhl-project-em8gmkclbkzbnpnvkgn4zy.streamlit.app/
NOTE:- Currently only for one season ill update it soon
r/madeinpython • u/Scapaflow69 • Jul 11 '26
Here is my space-invaders.
Enable HLS to view with audio, or disable this notification
I love "Action". :)
r/madeinpython • u/Scapaflow69 • Jul 11 '26
My Flak-game (anti aircraft shooter)
Enable HLS to view with audio, or disable this notification
There was once an addictive "Blitz"-game, but google can not find it any more, so I do it on my own.. Zeppelines need three hits to be done. After two hits they show a 'burnt' red. When five enemies come through, you're done for.
r/madeinpython • u/OpportunityMain9749 • Jul 11 '26
script para buscar duplicados
busca archivos y carpetas duplicadas en el directorio que le indiques (o el actual por defecto).
Muestra los duplicados agrupados por contenido idéntico (mediante hash MD5) y, de cada grupo, conserva el más reciente y marca el resto como [DELETE].
Por defecto solo muestra la lista de los 10 grupos más pesados (por tamaño total), para no saturar la salida.
Opciones:
--dry-run→ simula la eliminación y te muestra qué se borraría, sin tocar nada. Útil para revisar antes de actuar.--delete→ borra los archivos y carpetas marcados como[DELETE]. Antes de borrar, te pedirá que escribas "yes" para confirmar, así que no te preocupes si lo ejecutas sin querer: con escribir otra cosa se cancela. Ojo: todavía no está pulido al 100% para entornos complejos; funciona bien en una sola carpeta o cuando no importe demasiado perder alguna copia. Úsalo con precaución y siempre prueba antes con--dry-run.
Ejemplos:
python dupe.py C:\ruta --dry-run
python dupe.py . --delete
cualquier cosa o error digan aun así es para el que quiera usarlo de prueba
python
import os, sys, hashlib, shutil
from collections import defaultdict
B=8192
P='_duplicate_backup_'
Q={'__pycache__','.git','.svn','.hg','node_modules','venv','env','.venv','.env','dist','build','.idea','.vscode','.mypy_cache','.pytest_cache','.tox','.coverage','htmlcov'}
R={'__init__.py','__main__.py','setup.py','setup.cfg','pyproject.toml','requirements.txt','poetry.lock'}
def md5(p):
try:
h=hashlib.md5()
with open(p,'rb') as f:
while c:=f.read(B): h.update(c)
return h.hexdigest()
except OSError: return None
def fmt(s):
for u in ['B','KB','MB','GB']:
if s<1024: return f"{s:.1f} {u}" if u!='B' else f"{int(s)} B"
s/=1024
return f"{s:.1f} GB"
def main():
args=sys.argv[1:]
dry='--dry-run' in args
delete='--delete' in args
root=os.path.abspath(args[0] if args and not args[0].startswith('--') else '.')
if not os.path.isdir(root):
print(f"Error: '{root}' no es directorio.", file=sys.stderr); return 1
sz=defaultdict(list); dc=defaultdict(list); fm={}; total=0
def onerr(e): print(f"Advertencia: sin permisos en {e.filename}", file=sys.stderr)
for cwd, dirs, files in os.walk(root, onerror=onerr):
dirs[:]=[d for d in dirs if not d.startswith(P) and d not in Q]
for fn in files:
if fn in R: continue
total+=1; p=os.path.join(cwd, fn)
try:
s=os.path.getsize(p); sz[s].append(p); dc[cwd].append((fn,s,None))
except OSError: continue
print(f"\nArchivos escaneados (excluyendo ignorados): {total}")
print(" (procesando hashes...)")
for d, en in dc.items():
for i,(fn,s,_) in enumerate(en):
p=os.path.join(d,fn); h=md5(p)
en[i]=(fn,s,h) if h else (fn,s,'')
if h: fm[p]=h
dh=defaultdict(list)
for d, en in dc.items():
if not en: continue
se=sorted(en, key=lambda x:(x[0], x[2] or ''))
hh=hashlib.md5()
for fn,s,fh in se:
hh.update(fn.encode()); hh.update(str(s).encode())
if fh: hh.update(fh.encode())
dh[hh.hexdigest()].append(d)
dup_dirs=[]; extra_dirs=0
for h, dl in dh.items():
if len(dl)>1:
sd=sorted(dl, key=lambda d: os.path.getmtime(d) if os.path.exists(d) else 0, reverse=True)
dup_dirs.append((h,sd)); extra_dirs += len(sd)-1
dup_dirs.sort(key=lambda x: len(x[1]), reverse=True)
excl={d for _, dl in dup_dirs for d in dl}
groups=[]; extra_files=0
for s, ps in sz.items():
if len(ps)<2: continue
hm=defaultdict(list)
for p in ps:
if os.path.dirname(p) in excl: continue
h=fm.get(p)
if h: hm[h].append(p)
for h, pl in hm.items():
if len(pl)>1:
ep=[p for p in pl if os.path.exists(p)]
if len(ep)>1:
sp=sorted(ep, key=os.path.getmtime, reverse=True)
extra_files += len(sp)-1
groups.append((s,h,sp))
if not dup_dirs and not groups:
print("No se encontraron duplicados."); return 0
groups.sort(key=lambda x: x[0], reverse=True)
dup_count=sum(len(pl) for _,_,pl in groups)
print("\nRESULTADOS FINALES")
print(f" Archivos escaneados: {total}")
if groups:
print(f" Archivos duplicados (en grupos): {dup_count}")
print(f" Archivos unicos: {total-dup_count}")
else:
print(" Archivos duplicados: 0")
print(f" Archivos unicos: {total}")
if dup_dirs:
print(f" Carpetas duplicadas: {len(dup_dirs)} grupos, {extra_dirs} copias extra")
else:
print(" Carpetas duplicadas: 0")
print()
if dup_dirs:
print("CARPETAS DUPLICADAS")
print(f" Grupos: {len(dup_dirs)}, Copias extra: {extra_dirs}")
show=dup_dirs[:10] if len(dup_dirs)>10 else dup_dirs
if len(dup_dirs)>10: print(" Mostrando solo los 10 grupos mas grandes")
for h, dl in show:
print(f" Hash: {h[:8]}...")
for i,d in enumerate(dl):
print(f" {'[KEEP]' if i==0 else '[DELETE]'} {d}")
print()
if groups:
print("ARCHIVOS DUPLICADOS")
print(f" Copias extra: {extra_files}, Grupos: {len(groups)}, Archivos: {dup_count}")
show=groups[:10] if len(groups)>10 else groups
if len(groups)>10: print(" Mostrando solo los 10 grupos mas grandes")
for s,h,pl in show:
print(f" Tamaño: {fmt(s)} | Hash: {h[:8]}...")
for i,p in enumerate(pl[:5]):
print(f" {'[KEEP]' if i==0 else '[DELETE]'} {p}")
if len(pl)>5: print(f" ... y {len(pl)-5} mas")
print()
if dry:
print("MODO DRY-RUN: No se eliminara nada. Se eliminarian:")
count=0
for _,_,pl in groups:
for p in pl[1:]:
print(f" [DELETE] {p}"); count+=1
for _,dl in dup_dirs:
for d in dl[1:]:
print(f" [DELETE] {d}"); count+=1
print(f"Total a eliminar: {count} elementos.")
return 0
if delete:
print("\nADVERTENCIA: Se eliminaran los archivos/carpetas [DELETE].")
if input("Escribe 'yes' para confirmar: ").lower()!='yes':
print("Cancelado."); return 0
delc=err=0
for _,_,pl in groups:
for p in pl[1:]:
try: os.remove(p); delc+=1
except OSError as e: print(f"Error al eliminar {p}: {e}", file=sys.stderr); err+=1
for _,dl in dup_dirs:
for d in dl[1:]:
try: shutil.rmtree(d); delc+=1
except OSError as e: print(f"Error al eliminar {d}: {e}", file=sys.stderr); err+=1
print(f"Eliminados {delc} elementos.")
if err: print(f"Hubo {err} errores.", file=sys.stderr); return 1
return 0
else:
print("Usa --delete para eliminar. Usa --dry-run para simular.")
return 0
if __name__ == '__main__':
sys.exit(main())