Códigos de programación

Python - Arte ASCII con redes neuronales

Publicado el 18/02/2023

# Códigos Python: Generar arte ASCII con una red neuronal
# Desarrollado por Leandro Barone
# Complejidad del código: ★☆☆☆☆
import ascii_magic  # pip install --upgrade ascii_magic

# Podemos obtener una API key de DALL•E en https://openai.com
dalle_api_key = 'sk-V8ujlDlk48gkfJyy2p2082p9iofWm'
# Creamos una pieza de arte ASCII con lo que se nos ocurra
mi_arte = ascii_magic.from_dalle('Una reina vaca', dalle_api_key)
# La exportamos a un archivo
mi_arte.to_html_file('reina_vaca.html', columns=200)

Python - Descargar música de YouTube

Publicado el 13/01/2021

# Códigos Python: Descargar música de YouTube
# Desarrollado por Leandro Barone
# Complejidad del código: ★★☆☆☆
import pytube # pip install pytube
import sys

# Tomamos la URL del primer argumento del script, por ejemplo:
# python descargar_musica.py https://youtube.com/watch?v=...
try:
	url = sys.argv[1]
except:
	url = 'https://www.youtube.com/watch?v=7nQ2oiVqKHw'
# Abrimos la URL con pytube
try:
	yt = pytube.YouTube(url)
except pytube.exceptions.RegexMatchError:
	print(f'La URL especificada no es válida: {url}')
	exit()
# Descargamos la pista de audio (mp4audio u Opus)
audio_stream = yt.streams.filter(only_audio=True).first()
if audio_stream is None:
	print('El video no tiene una pista de audio independiente')
print(f'Descargando: "{audio_stream.title}"...')
audio_stream.download()

Python - Descargar video de YouTube

Publicado el 12/01/2021

# Códigos Python: Descargar video de YouTube
# Desarrollado por Leandro Barone
# Complejidad del código: ★★☆☆☆
import pytube # pip install pytube
import sys

# Tomamos la URL del primer argumento del script, por ejemplo:
# python descargar_video.py https://youtube.com/watch?v=...
try:
	url = sys.argv[1]
except:
	url = 'https://youtube.com/watch?v=DPEvF8l9LDM'
# Abrimos la URL con pytube
try:
	yt = pytube.YouTube(url)
except pytube.exceptions.RegexMatchError:
	print(f'La URL especificada no es válida: {url}')
	exit()
# Descargamos la versión del video con mayor calidad
# Las versiones progresivas incluyen el audio y el video juntos
prog_stream_list = yt.streams.filter(progressive=True)
stream = prog_stream_list.order_by('resolution').first()
print(f'Descargando el video: "{stream.title}"...')
stream.download()

Python - Sincronizar directorio local con Amazon S3

Publicado el 30/11/2020

Con Python y boto3 se pueden subir archivos a Amazon S3 en segundos.

# Códigos Python: Sincronizar directorio local con Amazon S3
# Desarrollado por Leandro Barone
# Complejidad del código: ★★★☆☆
from boto3 import Session # pip install boto3 (¡configurar antes!)
from glob import glob
from ntpath import split

DIR_LOCAL = 'fotografias/'
AWS_REGION_NAME = 'sa-east-1'
AWS_BUCKET_NAME = 'web'
AWS_BUCKET_PREFIX = 'galeria/fotografias/'

# Listamos los archivos locales que vamos a subir
# Usamos ntpath.split() para mayor compatibilidad con OSs
locales = list(split(archivo)[1] for archivo in glob(DIR_LOCAL + '*'))
# Nos conectamos a S3 y listamos los objetos
aws_session = Session(region_name=AWS_REGION_NAME)
aws_s3 = aws_session.resource('s3')
aws_bucket = aws_s3.Bucket(AWS_BUCKET_NAME)
objetos = aws_bucket.objects.filter(Prefix=AWS_BUCKET_PREFIX)
remotos = list(o.key[len(AWS_BUCKET_PREFIX):] for o in objetos)
# Iteramos sobre los archivos locales y subimos los que falten
for local in locales:
	if not local in remotos:
		with open(DIR_LOCAL + local, 'rb') as binario:
			aws_bucket.Object(AWS_BUCKET_PREFIX + local).put(Body=binario)

Python - Arte ASCII con paisaje aleatorio

Publicado el 26/11/2020

Desde chico me fascina el arte ASCII. Desarrollé el módulo ascii_magic para generar arte a color compatible con las terminales de Windows y Linux.

Más información en el repositorio de GitHub.

# Códigos Python: Arte ASCII con paisaje aleatorio
# Desarrollado por Leandro Barone
# Complejidad del código: ★☆☆☆☆
import ascii_magic # pip install ascii_magic

URL_IMAGEN_ALEATORIA = 'https://source.unsplash.com/800x600?landscape'
# Creamos un arte ASCII a partir de una foto de Unsplash
arte_ascii = ascii_magic.from_url(URL_IMAGEN_ALEATORIA)
# La mostramos en pantalla
ascii_magic.to_terminal(arte_ascii) 

Python - Arte ASCII en HTML

Publicado el 26/11/2020

El módulo ascii_magic puede generar arte ASCII en HTML a todo color.

# Códigos Python: Arte ASCII en HTML
# Desarrollado por Leandro Barone
# Complejidad del código: ★☆☆☆☆
import ascii_magic # pip install ascii_magic

URL_IMAGEN_ALEATORIA = 'https://source.unsplash.com/800x600?animals'
# Creamos un arte ASCII en HTML a partir de una foto de Unsplash
codigo_html = ascii_magic.from_url(
  URL_IMAGEN_ALEATORIA,
  columns=200,
  mode=ascii_magic.Modes.HTML
)
# Generamos un archivo HTML y lo abrimos en el navegador
ascii_magic.to_html_file('arte.html', codigo_html, auto_open=True)

Python - Web scraping de cotizacion del Bitcoin

Publicado el 24/11/2020

El web scraping consiste en extraer datos a partir del HTML de un sitio web de manera programática. Con Python puede hacerse en 3 líneas.

# Códigos Python: Web scraping de cotización del Bitcoin
# Desarrollado por Leandro Barone
# Complejidad del código: ★☆☆☆☆
import bs4 # pip install bs4
import requests # pip install requests
import datetime

URL_COTIZACION = 'https://es.investing.com/crypto/bitcoin'
# Muchos sitios bloquean peticiones de user agents desconocidos
HEADERS = {'User-Agent': "Mozilla Firefox Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:53.0) Gecko/20100101 Firefox/53.0"}

# Descargamos el HTML de Investing
request = requests.get(URL_COTIZACION, headers=HEADERS)
# Lo procesamos con BeautifulSoup, un parser HTML
soup = bs4.BeautifulSoup(request.text, features='lxml')
# Buscamos el <div id='last_last'> con la cotización
cotizacion = soup.find(id='last_last').get_text()
fecha = datetime.datetime.now().strftime('%d/%m/%Y %H:%M')

print(f'1BTC = US${cotizacion} ({fecha} via investing.com)')
# => 1BTC = US$19.106 (24/11/2020 22:53 via investing.com)

Python - Sincronizar directorio local y remoto por FTP

Publicado el 24/11/2020

# Códigos Python: Sincronizar directorio local y remoto por FTP
# Desarrollado por Leandro Barone
# Complejidad del código: ★★★☆☆
from ftplib import FTP
from glob import glob
from ntpath import split

DIR_LOCAL = 'fotografias/'
DIR_REMOTO = 'public_html/galeria/fotografias/'
FTP_SERVIDOR = '127.0.0.1'
FTP_USUARIO = 'miusuario'
FTP_CLAVE = 'miclave'

# Listamos los archivos locales que vamos a subir
# Usamos ntpath.split() para mayor compatibilidad con OSs
locales = list(split(archivo)[1] for archivo in glob(DIR_LOCAL + '*'))
# Nos conectamos al servidor y listamos los archivos remotos
with FTP(FTP_SERVIDOR) as sesion_ftp:
	sesion_ftp.login(FTP_USUARIO, FTP_CLAVE)
	sesion_ftp.cwd(DIR_REMOTO)
	remotos = list(archivo[0] for archivo in sesion_ftp.mlsd())
	# Iteramos sobre los archivos locales y subimos los que falten
	for local in locales:
		if not local in remotos:
			with open(DIR_LOCAL + local, 'rb') as binario:
				sesion_ftp.storbinary('STOR ' + local, binario)

Python - Leer archivo CSV y mostrarlo como tabla

Publicado el 24/11/2020

Con las (no tan) nuevas f-strings de Python 3.6 se puede mostrar información tabulada en una sola línea y sin módulos adicionales.

# Códigos Python: Leer archivo CSV y mostrarlo como tabla
# Desarrollado por Leandro Barone
# Complejidad del código: ★★☆☆☆
import csv

# Abrimos el archivo como texto
with open('pedido.csv', 'r') as archivo:
  	# csv.reader() devuelve un objeto iterable
	productos = csv.reader(archivo, dialect=csv.excel)
	# El iterable devuelve una lista por cada fila del CSV
	for producto, codigo, precio in productos:
      	# Mostramos cada línea dándole formato con f-strings
		print(f'{producto:40}{codigo:8}${float(precio):>7.2f}')

"""
> pedido.csv:
Jabon en polvo 500g,A1234,199.99 
Suavizante para ropa 200ml,B5678,99.00 
"Perfume para ropa, frutilla",C9123,44.99

> output: 
Jabon en polvo 500g                     A1234    $ 199.99
Suavizante para ropa 200ml              B5678    $  99.00
Perfume para ropa, frutilla             C9123    $  44.99
"""

Python - Generador de nombres fantasy aleatorios

Publicado el 22/11/2020

# Códigos Python: Generador de nombres fantasy aleatorios
# Desarrollado por Leandro Barone
# Complejidad del código: ★☆☆☆☆
import random

# Iterables (cadenas y tuplas) con piezas para generar nombres
VOCALES = 'aeiou'
CONSONANTES = 'bcdfghjklmnprstvwxyz'
SUFIJOS = 'ckson', 'ngton', 'gwyn', 'ndolin', 'sson', 'rindae'
ELEMENTOS = 'blood', 'fire', 'flame', 'thunder', 'shadow', 'poison'
SUSTANTIVOS = 'sword', 'axe', 'spear', 'hammer', 'wing', 'cloak'
ADJETIVOS = 'noble', 'brave', 'strong', 'nimble', 'wise', 'bright'

def generar_nombre() -> str:
	# Creamos un alias de choice() sin "ensuciar" el contexto global
	r = random.choice
	# Generamos las partes del nombre
	nombre = (r(CONSONANTES) + r(VOCALES) + r(SUFIJOS)).capitalize()
	apellido = (r(ELEMENTOS) + r(SUSTANTIVOS)).capitalize()
	titulo = r(ADJETIVOS).capitalize()
	return f'{nombre} {apellido} the {titulo}'

for _ in range(10): print(generar_nombre())
# => Vugwyn Bloodsword the Wise, Tosson Thundercloak the Brave, ...

Python - Piedra, Papel, Tijera, Lagarto, Spock

Publicado el 21/11/2020

# Códigos Python: Piedra, Papel, Tijera, Lagarto, Spock
# Variante del juego popularizada por The Big Bang Theory
# Desarrollado por Leandro Barone
# Complejidad del código: ★★☆☆☆
import random

# Movimientos posibles y a qué movimientos derrotan
MOVIMIENTOS = {
	'Piedra': ('Tijera', 'Lagarto'),
	'Papel': ('Piedra', 'Spock'),
	'Tijera': ('Papel', 'Lagarto'),
	'Lagarto': ('Papel', 'Spock'),
	'Spock': ('Piedra', 'Tijera'),
}

# Mostramos las opciones disponibles, ej: 1 => Piedra
for i, k in enumerate(MOVIMIENTOS):
	print(f'{i + 1} => {k}')

# El usuario elige movimiento, o si no escribe nada, salimos
while True:
	num_mov = input('Elegí tu movimiento: ') or exit()
	try:
		mov_jugador = list(MOVIMIENTOS)[int(num_mov) - 1]
	except:
		print('Movimiento inválido, probá de nuevo')
	else:
		break

# Determinamos al azar el movimiento de la CPU
mov_cpu = random.choice(list(MOVIMIENTOS))

# Resolvemos la partida
print(f'Elegiste {mov_jugador}')
print(f'La CPU eligió {mov_cpu}')
if mov_jugador == mov_cpu:
	print('¡Empate!')
elif mov_cpu in MOVIMIENTOS[mov_jugador]:
	print(f'{mov_jugador} mata {mov_cpu}, ¡ganaste!')
else:
	print(f'{mov_cpu} mata {mov_jugador}, ¡perdiste!')