Subida inicial. Chequeada
This commit is contained in:
commit
ce8262cafb
61
README.md
Normal file
61
README.md
Normal file
@ -0,0 +1,61 @@
|
||||
# Codificador visual de Morse
|
||||
|
||||
Este programa está realizado en python.
|
||||
|
||||
## Dependencias e instalación
|
||||
|
||||
El programa unicamente tiene como dependencia `Pygame` y lo puedes instalar de la siguiente forma:
|
||||
|
||||
1. Sistemas basados en Debian
|
||||
|
||||
Si usas **Debian**, Ubuntu, Linux Mint o Raspberry Pi debes usar el gestor
|
||||
de paquetes para evitar conflictos:
|
||||
|
||||
```bash
|
||||
sudo apt update
|
||||
sudo apt -y install python3-pygame
|
||||
```
|
||||
|
||||
2. Otros Sistemas Operativos
|
||||
|
||||
Si usas Windows, macOS u otras distros tienes que instalar las dependencias
|
||||
mediante el comando `pip`
|
||||
|
||||
```
|
||||
pip install pygame
|
||||
```
|
||||
|
||||
O usar el fichero requeriments.txt para resolver dependencias:
|
||||
|
||||
```
|
||||
pip install -r requeriments.txt
|
||||
```
|
||||
|
||||
## Ejecutar el programa
|
||||
|
||||
```
|
||||
python morse.py
|
||||
```
|
||||
|
||||
Captura de programa tras *codificar* en morse "SoloConLinux":
|
||||
|
||||

|
||||
|
||||
|
||||
Al finalizar la ejecución se muestra el texto y el código morse:
|
||||
|
||||
```bash
|
||||
|
||||
$ python morse.py
|
||||
|
||||
========================================
|
||||
CODIFICADOR MORSE
|
||||
TEXTO: SOLOCONLINUX
|
||||
MORSE: ... --- ... --- ... --- ... ... --- .-.. --- -.-. --- -. .-.. .. -. ..- -..-
|
||||
========================================
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
201
morse.py
Executable file
201
morse.py
Executable file
@ -0,0 +1,201 @@
|
||||
#!/usr/bin/env python3
|
||||
import os
|
||||
import warnings
|
||||
|
||||
# Ignorar el aviso de AVX2 y otros avisos de ejecución
|
||||
warnings.filterwarnings("ignore", category=RuntimeWarning)
|
||||
# Silenciar el saludo de "Hello from the pygame community"
|
||||
os.environ['PYGAME_HIDE_SUPPORT_PROMPT'] = "hide"
|
||||
|
||||
import pygame
|
||||
import sys
|
||||
|
||||
# Inicialización
|
||||
pygame.init()
|
||||
|
||||
# Configuración de ventana
|
||||
ANCHO, ALTO = 1000, 850
|
||||
ventana = pygame.display.set_mode((ANCHO, ALTO))
|
||||
pygame.display.set_caption("Codificador Morse - SoloConLinux")
|
||||
|
||||
# Colores
|
||||
COLOR_FONDO = (245, 245, 245)
|
||||
COLOR_PUNTO = (70, 70, 160)
|
||||
COLOR_RAYA = (180, 50, 50)
|
||||
COLOR_LINEA = (210, 210, 210)
|
||||
COLOR_RESALTE = (0, 200, 0)
|
||||
COLOR_TEXTO = (20, 20, 20)
|
||||
COLOR_BARRA = (40, 40, 40)
|
||||
COLOR_LEYENDA = (220, 220, 220)
|
||||
COLOR_HISTORIAL = (50, 50, 100)
|
||||
|
||||
# Fuentes
|
||||
fuente_nodos = pygame.font.SysFont("Arial", 20, bold=True)
|
||||
fuente_leyenda = pygame.font.SysFont("Monospace", 16)
|
||||
fuente_preview = pygame.font.SysFont("Arial", 40, bold=True)
|
||||
fuente_mensaje = pygame.font.SysFont("Courier New", 36, bold=True)
|
||||
|
||||
class NodoMorse:
|
||||
def __init__(self, letra, x, y, es_raya=False):
|
||||
self.letra = letra
|
||||
self.x = x
|
||||
self.y = y
|
||||
self.es_raya = es_raya
|
||||
self.punto = None
|
||||
self.raya = None
|
||||
self.padre = None
|
||||
|
||||
def dibujar_lineas(self, superficie, nodo_actual):
|
||||
es_camino_activo = self.es_parte_del_camino(nodo_actual)
|
||||
color = COLOR_RESALTE if es_camino_activo else COLOR_LINEA
|
||||
ancho = 4 if es_camino_activo else 2
|
||||
|
||||
if self.punto:
|
||||
pygame.draw.line(superficie, color, (self.x, self.y), (self.punto.x, self.punto.y), ancho)
|
||||
self.punto.dibujar_lineas(superficie, nodo_actual)
|
||||
if self.raya:
|
||||
pygame.draw.line(superficie, color, (self.x, self.y), (self.raya.x, self.raya.y), ancho)
|
||||
self.raya.dibujar_lineas(superficie, nodo_actual)
|
||||
|
||||
def dibujar_nodo(self, superficie, nodo_actual):
|
||||
activo = (self == nodo_actual)
|
||||
color = COLOR_RESALTE if activo else (COLOR_RAYA if self.es_raya else COLOR_PUNTO)
|
||||
|
||||
if self.es_raya:
|
||||
pygame.draw.rect(superficie, color, (self.x - 22, self.y - 11, 44, 22))
|
||||
else:
|
||||
pygame.draw.circle(superficie, color, (self.x, self.y), 16)
|
||||
|
||||
if self.letra:
|
||||
color_letra = (255, 255, 255) if activo else COLOR_TEXTO
|
||||
# Ajustar texto si no tiene fuente Arial instalada
|
||||
# Generamos la superficie del texto
|
||||
texto_surf = fuente_nodos.render(self.letra, True, color_letra)
|
||||
|
||||
# Creamos un rectángulo con el tamaño del texto y lo centramos en (self.x, self.y)
|
||||
texto_rect = texto_surf.get_rect(center=(self.x, self.y))
|
||||
|
||||
# Dibujamos la superficie en las coordenadas del rectángulo calculado
|
||||
superficie.blit(texto_surf, texto_rect)
|
||||
|
||||
def es_parte_del_camino(self, destino):
|
||||
temp = destino
|
||||
while temp is not None:
|
||||
if temp == self: return True
|
||||
temp = temp.padre
|
||||
return False
|
||||
|
||||
# --- CONSTRUCCIÓN DEL ÁRBOL ---
|
||||
nodos_lista = []
|
||||
def crear_nodo(letra, x, y, es_raya=False):
|
||||
nuevo = NodoMorse(letra, x, y, es_raya)
|
||||
nodos_lista.append(nuevo)
|
||||
return nuevo
|
||||
|
||||
raiz = crear_nodo("", 500, 150) # Bajado un poco para dar espacio al texto arriba
|
||||
# Derecha (Puntos)
|
||||
e = crear_nodo("E", 700, 250); e.padre = raiz; raiz.punto = e
|
||||
i = crear_nodo("I", 800, 250); i.padre = e; e.punto = i
|
||||
s = crear_nodo("S", 900, 250); s.padre = i; i.punto = s
|
||||
h = crear_nodo("H", 970, 250); h.padre = s; s.punto = h
|
||||
v = crear_nodo("V", 900, 330, True); v.padre = s; s.raya = v
|
||||
u = crear_nodo("U", 800, 330, True); u.padre = i; i.raya = u
|
||||
f = crear_nodo("F", 800, 410); f.padre = u; u.punto = f
|
||||
a = crear_nodo("A", 700, 450, True); a.padre = e; e.raya = a
|
||||
r = crear_nodo("R", 800, 530); r.padre = a; a.punto = r
|
||||
l = crear_nodo("L", 900, 530); l.padre = r; r.punto = l
|
||||
w = crear_nodo("W", 700, 610, True); w.padre = a; a.raya = w
|
||||
p = crear_nodo("P", 800, 610); p.padre = w; w.punto = p
|
||||
j = crear_nodo("J", 700, 690, True); j.padre = w; w.raya = j
|
||||
# Izquierda (Rayas)
|
||||
t = crear_nodo("T", 300, 250, True); t.padre = raiz; raiz.raya = t
|
||||
m = crear_nodo("M", 200, 250, True); m.padre = t; t.raya = m
|
||||
o = crear_nodo("O", 100, 250, True); o.padre = m; m.raya = o
|
||||
g = crear_nodo("G", 200, 330); g.padre = m; m.punto = g
|
||||
q = crear_nodo("Q", 100, 410, True); q.padre = g; g.raya = q
|
||||
z = crear_nodo("Z", 200, 410); z.padre = g; g.punto = z
|
||||
n = crear_nodo("N", 300, 450); n.padre = t; t.punto = n
|
||||
k = crear_nodo("K", 200, 530, True); k.padre = n; n.raya = k
|
||||
y = crear_nodo("Y", 100, 530, True); y.padre = k; k.raya = y
|
||||
c = crear_nodo("C", 200, 610); c.padre = k; k.punto = c
|
||||
d = crear_nodo("D", 300, 610); d.padre = n; n.punto = d
|
||||
x = crear_nodo("X", 200, 690, True); x.padre = d; d.raya = x
|
||||
b = crear_nodo("B", 300, 690); b.padre = d; d.punto = b
|
||||
|
||||
# --- VARIABLES DE ESTADO ---
|
||||
nodo_actual = raiz
|
||||
mensaje_completo = "" # El mensaje final que se imprimirá
|
||||
codigo_morse_total = "" # El código final que se imprimirá
|
||||
morse_actual = "" # Lo que se va pulsando para la letra actual
|
||||
ejecutando = True
|
||||
reloj = pygame.time.Clock()
|
||||
|
||||
while ejecutando:
|
||||
ventana.fill(COLOR_FONDO)
|
||||
|
||||
# 1. Dibujar Cabecera (Mensaje generado)
|
||||
pygame.draw.rect(ventana, (230, 230, 230), (0, 0, ANCHO, 80))
|
||||
pygame.draw.line(ventana, COLOR_BARRA, (0, 80), (ANCHO, 80), 2)
|
||||
img_msg = fuente_mensaje.render(mensaje_completo + "_", True, COLOR_HISTORIAL)
|
||||
ventana.blit(img_msg, (20, 20))
|
||||
|
||||
# 2. Dibujar Árbol
|
||||
raiz.dibujar_lineas(ventana, nodo_actual)
|
||||
for n in nodos_lista:
|
||||
n.dibujar_nodo(ventana, nodo_actual)
|
||||
|
||||
# 3. Dibujar Barra de Leyenda
|
||||
pygame.draw.rect(ventana, COLOR_BARRA, (0, ALTO - 60, ANCHO, 60))
|
||||
texto_leyenda = ". (Punto) - (Raya) SPACE (Confirmar) BACKSPACE (Borrar) ESC (Salir)"
|
||||
img_leyenda = fuente_leyenda.render(texto_leyenda, True, COLOR_LEYENDA)
|
||||
ventana.blit(img_leyenda, (20, ALTO - 38))
|
||||
|
||||
# 4. Previsualización de letra actual
|
||||
if nodo_actual.letra:
|
||||
# Ajuste texto si no tiene fuente Arial
|
||||
pygame.draw.circle(ventana, COLOR_RESALTE, (ANCHO - 60, ALTO - 120), 35, 3)
|
||||
img_prev = fuente_preview.render(nodo_actual.letra, True, COLOR_TEXTO)
|
||||
# Centrado dinámico:
|
||||
rect_prev = img_prev.get_rect(center=(ANCHO - 60, ALTO - 120))
|
||||
ventana.blit(img_prev, rect_prev)
|
||||
|
||||
for evento in pygame.event.get():
|
||||
if evento.type == pygame.QUIT:
|
||||
ejecutando = False
|
||||
if evento.type == pygame.KEYDOWN:
|
||||
if evento.key == pygame.K_PERIOD:
|
||||
if nodo_actual.punto:
|
||||
nodo_actual = nodo_actual.punto
|
||||
morse_actual += "."
|
||||
elif evento.key in [pygame.K_MINUS, pygame.K_SLASH, pygame.K_KP_MINUS]:
|
||||
if nodo_actual.raya:
|
||||
nodo_actual = nodo_actual.raya
|
||||
morse_actual += "-"
|
||||
elif evento.key == pygame.K_SPACE:
|
||||
if nodo_actual.letra:
|
||||
mensaje_completo += nodo_actual.letra
|
||||
codigo_morse_total += morse_actual + " "
|
||||
else:
|
||||
mensaje_completo += " "
|
||||
codigo_morse_total += " "
|
||||
# resetarar para siguiente letra
|
||||
nodo_actual = raiz
|
||||
morse_actual = ""
|
||||
elif evento.key == pygame.K_BACKSPACE:
|
||||
mensaje_completo = mensaje_completo[:-1]
|
||||
morse_actual = ""
|
||||
elif evento.key == pygame.K_ESCAPE:
|
||||
ejecutando = False
|
||||
|
||||
pygame.display.flip()
|
||||
reloj.tick(30)
|
||||
|
||||
# -- Al Salir imprimimos todo el texto --
|
||||
print("\n" + "="*40)
|
||||
print("CODIFICADOR MORSE")
|
||||
print(f"TEXTO: {mensaje_completo}")
|
||||
print(f"MORSE: {codigo_morse_total.strip()}")
|
||||
print("="*40 + "\n")
|
||||
|
||||
pygame.quit()
|
||||
sys.exit()
|
||||
25
morse2text.py
Executable file
25
morse2text.py
Executable file
@ -0,0 +1,25 @@
|
||||
#!/usr/bin/env python3
|
||||
import sys
|
||||
|
||||
MORSE_MAP = {'A': '.-', 'B': '-...', 'C': '-.-.', 'D': '-..', 'E': '.', 'F': '..-.', 'G': '--.', 'H': '....', 'I': '..', 'J': '.---', 'K': '-.-', 'L': '.-..', 'M': '--', 'N': '-.', 'O': '---', 'P': '.--.', 'Q': '--.-', 'R': '.-.', 'S': '...', 'T': '-', 'U': '..-', 'V': '...-', 'W': '.--', 'X': '-..-', 'Y': '-.--', 'Z': '--..', '1': '.----', '2': '..---', '3': '...--', '4': '....-', '5': '.....', '6': '-....', '7': '--...', '8': '---..', '9': '----.', '0': '-----'}
|
||||
# Invertimos el diccionario: { '.-': 'A', ... }
|
||||
REVERSE_MAP = {v: k for k, v in MORSE_MAP.items()}
|
||||
|
||||
def decode():
|
||||
if len(sys.argv) < 2:
|
||||
print("Uso: python3 morse2text.py \".... --- .-.. .-\"")
|
||||
return
|
||||
|
||||
# El input es la cadena morse
|
||||
input_morse = sys.argv[1]
|
||||
palabras_morse = input_morse.split(" ") # Separamos por doble espacio
|
||||
frase_final = []
|
||||
|
||||
for palabra in palabras_morse:
|
||||
letras = [REVERSE_MAP.get(cod, "?") for cod in palabra.split(" ")]
|
||||
frase_final.append("".join(letras))
|
||||
|
||||
print(" ".join(frase_final))
|
||||
|
||||
if __name__ == "__main__":
|
||||
decode()
|
||||
1
requeriments.txt
Normal file
1
requeriments.txt
Normal file
@ -0,0 +1 @@
|
||||
pygame>=2.6.0
|
||||
22
text2morse.py
Executable file
22
text2morse.py
Executable file
@ -0,0 +1,22 @@
|
||||
#!/usr/bin/env python3
|
||||
import sys
|
||||
|
||||
MORSE_MAP = {'A': '.-', 'B': '-...', 'C': '-.-.', 'D': '-..', 'E': '.', 'F': '..-.', 'G': '--.', 'H': '....', 'I': '..', 'J': '.---', 'K': '-.-', 'L': '.-..', 'M': '--', 'N': '-.', 'O': '---', 'P': '.--.', 'Q': '--.-', 'R': '.-.', 'S': '...', 'T': '-', 'U': '..-', 'V': '...-', 'W': '.--', 'X': '-..-', 'Y': '-.--', 'Z': '--..', '1': '.----', '2': '..---', '3': '...--', '4': '....-', '5': '.....', '6': '-....', '7': '--...', '8': '---..', '9': '----.', '0': '-----'}
|
||||
|
||||
def encode():
|
||||
if len(sys.argv) < 2:
|
||||
print("Uso: python3 text2morse.py \"TEXTO A CONVERTIR\"")
|
||||
return
|
||||
|
||||
texto = " ".join(sys.argv[1:]).upper()
|
||||
resultado = []
|
||||
|
||||
for palabra in texto.split(" "):
|
||||
codificado = [MORSE_MAP.get(letra, "") for letra in palabra]
|
||||
resultado.append(" ".join(codificado))
|
||||
|
||||
# Unimos las palabras con 2 espacios
|
||||
print(" ".join(resultado))
|
||||
|
||||
if __name__ == "__main__":
|
||||
encode()
|
||||
Loading…
x
Reference in New Issue
Block a user