Sistema de Venta para Pequeño Negocio
Local:
“Mini-market María Guaraca” .
Sales System for a Small Local Businesses:
“Mini-market María Guaraca” .
Fecha de recepción: 16 de mayo del 2025.
Resumen:
Este proyecto desarrolla un sistema de ventas e inventario en Java y MySQL para el Mini-
market María Guaraca, un pequeño negocio comunitario liderado por mujeres en Ambato,
Ecuador. El sistema busca automatizar procesos manuales, mejorar la eficiencia operativa y
generar reportes útiles para la toma de decisiones. Se implementaron cuatro módulos
principales:1. Registro de productos y categorías. 2. Interfaz gráfica para ventas y clientes
frecuentes. 3. Alertas de inventario bajo. 4. Generación de reportes de ventas. La metodología
combinó enfoques cuantitativos y cualitativos, utilizando herramientas como JavaFX, MySQL,
Workbench y Git. Los resultados mostraron una reducción del 40-50 % en tiempo de procesos
manuales, disminución de errores en inventario y un posible aumento de 15-20 % en ventas. El
impacto social incluyó mejor coordinación con proveedoras locales, reducción de desperdicios y
mantenimiento de empleos comunitarios. El proyecto demuestra cómo soluciones tecnológicas
accesibles pueden transformar pequeños negocios.
Palabras clave: SQL, Java, Git, proyecto Abstract:
This project develops a sales and inventory system in Java and MySQL for Mini-Market
María Guaraca, a small, women-led community business in Ambato, Ecuador. The system seeks
to automate manual processes, improve operational efficiency, and generate useful reports for
decision-making. Four main modules were implemented: 1. Product and category registration. 2.
Graphical interface for sales and frequent customers. 3. Low inventory alerts. 4. Sales report
generation. The methodology combined quantitative and qualitative approaches, using tools
such as JavaFX, MySQL, Workbench, and Git. The results showed a 40-50% reduction in manual
process time, a decrease in inventory errors, and a potential 15-20% increase in sales. The social
impact included better coordination with local suppliers, waste reduction, and maintenance of
community jobs. The project demonstrates how affordable technology solutions can transform
small businesses. Keywords: SQL, Java, Git, project
Introducción.
La ausencia de inteligencia de negocios, también conocida como Business Intelligence o
BI en inglés, incide en casi todos los procesos de crecimiento empresarial; en este contexto,
cualquier organización puede enfrentar dificultades para analizar los informes e identificar los
datos pertinentes (Al Kautsaf et al., 2023). Los resultados muestran que las pymes, en particular
aquellas que no contaban con sistemas digitales sólidos, encontraron difícil gestionar las ventas
y las relaciones con los clientes de manera eficaz (Panduwiyasa et al., 2022). Los entornos ERP
tradicionales contienen una gran cantidad de aplicaciones con integración e interoperabilidad
limitadas, donde, la alta personalización a lo largo del tiempo ha aumentado la complejidad y
ralentizado la velocidad de implementación (Muhammad et al., 2025). Los sistemas de bases de
datos relacionales, como los SQL, en sistemas ERP, no son necesariamente óptimos para ciertas
industrias que necesitan velocidad en tiempo real sobre la capacidad del sistema para el
mantenimiento de datos (Azevedo et al., 2012).
A menudo, las pymes organizan sus sistemas de información en hojas de cálculos (Al
Kautsaf et al., 2023). Donde, los procesos manuales generan errores, pérdida de tiempo y
dificultan el seguimiento de los productos del proveedor local, sin embargo, los sistemas ERP
permiten a las empresas controlar los costes del ciclo de vida del producto, optimizar la
asignación de recursos y mejorar la sostenibilidad económica (Muhammad et al., 2025). Los
sistemas de planificación de recursos empresariales (ERP) contribuyen a la reducción de los
costos operativos en un 30 %, optimizan la toma de decisiones mediante la utilización de datos
en tiempo real y automatizan tareas tales como la administración de inventario y la proyección
de la demanda (Chaichana et al., 2024). La selección de un sistema ERP requiere alinear las
capacidades del sistema con los objetivos de la organización, incluyendo la flexibilidad, la
facilidad de uso y el soporte del proveedor (Azevedo et al., 2012). Los sistemas de ventas debían
integrarse con los sistemas financieros para garantizar un seguimiento preciso de los ingresos
esenciales para la toma de decisiones en tiempos de crisis (Panduwiyasa et al., 2022).
Trabajo y unión con la comunidad.
En un barrio lleno de color en Ambato, donde las paredes guardan historias en cada trazo
de pintura, funciona el minimercado María Guaraca. No es solo un lugar para comprar, sino un
espacio que une a la comunidad, liderado por mujeres tenaces y perseverantes. María, su
fundadora, levantó el negocio con sus propias manos, ofreciendo desde alimentos hasta
artesanías hechas por vecinas. Pero como muchas emprendedoras de la región, su esfuerzo pasa
desapercibido frente a las grandes empresas. María obtiene sus productos de mujeres como
Doña Rosa, quien produce quesos tras haber levantado su negocio ganadero después de quedar
viuda, y de un grupo de artesanas locales. Sin un método claro para gestionar pedidos, a veces
los estantes se quedan vacíos o los productos frescos llegan tarde, lo que complica competir con
las cadenas comerciales.
El trabajo de estas productoras, igual que el de María, rara vez recibe el reconocimiento
que merece. El impacto de María en su comunidad tampoco se difunde. Da empleo a tres madres
solteras con salarios dignos y dona leche a la escuela del barrio, acciones que casi nadie conoce.
Su tienda es un pilar local, pero su influencia podría crecer si más personas supieran de su labor.
Surge entonces la idea de una tecnología creada por y para mujeres. Este enfoque no solo facilita
ventas, sino que desafía la invisibilidad. Cada mujer que usa estas herramientas podría a futuro
inspirar a otras a explorar la tecnología o a emprender. Las historias personales se vuelven
motores de cambio. María Guaraca es ejemplo de cómo el ingenio y la colaboración pueden
transformar realidades. Las mujeres de la región no piden rescate, sino oportunidades para
potenciar su liderazgo. Cuando una avanza, todas ganan. El progreso, al fin, se construye en
colectivo. Por lo que propongo los siguientes objetivos:
Objetivos.
Objetivo General:
Desarrollar un sistema en Java y MySQL que automatice las ventas, controle el inventario y
genere reportes para mejorar la eficiencia del negocio.
Objetivos Específicos:
1. Implementar un módulo de registro de productos y categorías.
2. Diseñar una interfaz gráfica para registrar ventas y clientes frecuentes.
3. Generar alertas de existencias bajas y reportes de ventas
diarias/semanales.
4. Integrar una base de datos para almacenar transacciones y datos de productos.
Materiales y métodos.
La clasificación propuesta corresponde a un proyecto de ingeniería de software
aplicado, con un enfoque cuantitativo y descriptivo, centrado en resolver un problema
específico en un contexto comunitario (ej.: el caso de María Guaraca). Es cuantitativo para
medir impactos concretos (ej.: eficiencia en pedidos, reducción de desperdicios), lo que facilita
la evaluación objetiva del sistema propuesto.
Tabla 1. Clasificación del estudio por categoria.
Enfoque de investigación
Tipo de investigación
Diseño metodológico No experimental (caso de estudio)
Participación comunitaria
Metodologías de desarrollo de proyectos de ingeniería de software.
● Modelo en Cascada (Waterfall): Aplicable si el proyecto tiene requisitos bien
definidos y etapas secuenciales como análisis, diseño, implementación y pruebas.
● SCRUM (Metodología Ágil): Ideal para iteraciones rápidas (sprints) que permitan
entregar funcionalidades incrementales, como desarrollar el módulo de inventario
en un sprint y el de ventas en otro.
● Prototipado Rápido: Útil para validar la interfaz gráfica con usuarios reales, como
dueñas de negocios, antes de la implementación final.
Herramientas técnicas para el desarrollo.
Desarrollo basado en (Vida Informatico - AS, 2020):
● Para el desarrollo en Java:
〇 Interfaces gráficas:
■ JavaFX o Swing para construir la interfaz visual del sistema,
permitiendo crear pantallas para registro de ventas y gestión de
clientes.
○ Conexión con base de datos:
■ JDBC como opción básica para conectar Java con MySQL.
■ Hibernate como alternativa más avanzada para el mapeo objeto-
relacional.
○ Generación de reportes:
■ JFreeChart para crear gráficos estadísticos de ventas. ■ JasperReports
para diseñar reportes detallados en formato PDF.
○ Entornos de desarrollo integrado:
■ Eclipse con plugins para Java EE y MySQL.
■ IntelliJ IDEA con herramientas integradas para desarrollo de bases de
datos.
○ Para la base de datos MySQL:
■ MySQL Workbench como herramienta principal para:
● Diseñar el modelo de base de datos.
○ Generar tablas como productos, ventas y clientes.
○ Desarrollar scripts SQL para triggers que alerten
sobre existencias bajas.
○ Implementar procedimientos almacenados para
operaciones recurrentes.
〇 Control de versiones:
■ Git como sistema de control de versiones ●
GitHub o GitLab como repositorios remotos para:
○ Almacenamiento seguro del código fuente
○ Colaboración en equipo
○ Gestión de diferentes versiones del proyecto
Métodos de implementación.
● Para el módulo de registro de productos:
○ Patrón MVC (Modelo-Vista-Controlador) con clases Java para el modelo,
JavaFX para la vista y controladores para la lógica.
○ Validación de datos con expresiones regulares para campos como precios y
códigos.
● Para la interfaz de ventas:
○ Eventos en JavaFX para funcionalidad del carrito de compras.
○ Patrón Observer para actualización automática de inventario.
● Para alertas y reportes:
○ Consultas SQL con JOINs para detectar existencias bajas.
○ Cron Jobs o TimerTask en Java para reportes automáticos.
● Pruebas y calidad:
○ Pruebas unitarias con JUnit para validar métodos críticos. ○ Pruebas
de integración para verificar la conexión Java-MySQL. ○ Pruebas de
usabilidad con usuarios reales.
● Documentación:
○ JavaDoc para documentación automática del código.
○ Manual de usuario con capturas de pantalla para usuarios no técnicos.
● Despliegue:
○ Creación de instalador con Launch4j o JPackage.
○ Implementación de backups automáticos de la base de datos.
● Últimos puntos finales:
○ Priorizar la simplicidad en la interfaz para usuarios como dueños de
pequeños negocios.
○ Utilizar los videos referenciados como guía para la estructura básica.
○ Obtener feedback real mediante prototipos con usuarios finales.
Resultados y discusión.
1. Sistema funcional desarrollado en Java y MySQL que integre:
○ Módulo completo de registro de productos y categorías
○ Interfaz gráfica intuitiva para gestión de ventas y clientes frecuentes
○ Mecanismos automatizados de alerta de inventario bajo
○ Generación de reportes diarios/semanales de ventas
2. Base de datos optimizada que:
○ Registre todas las transacciones de ventas ○ Mantenga un control
preciso del inventario
○ Almacene información de clientes y proveedores
Conclusiones.
Impactos operativos para el negocio:
1. Mejora en la eficiencia operativa:
○ Reducción del tiempo dedicado a procesos manuales en un 40-50 %.
○ Disminución de errores en inventario y facturación
○ Optimización del control de existencias (evitando faltantes o excesos).
2. Beneficios financieros:
○ Posible aumento de ventas entre 15-20 % por mejor servicio al cliente.
○ Reducción de pérdidas por productos vencidos o mal
gestionados. ○ Mejor flujo de caja al tener información
financiera actualizada.
3. Ventajas estratégicas:
○ Capacidad de tomar decisiones basadas en datos (reportes de ventas).
○ Mejor relación con proveedores al anticipar pedidos.
○ Posibilidad de identificar productos más rentables.
Impacto social comunitario:
1. Para María Guaraca y su comunidad:
○ Reducción de carga laboral para las empleadas. ○ Mayor reconocimiento del
negocio en la comunidad. ○ Posibilidad de expandir servicios con base en datos.
2. Para las proveedoras locales:
○ Mejor coordinación de pedidos con Doña Rosa y artesanas.
○ Reducción de desperdicios en productos
perecederos. ○ Oportunidad de crecer junto al
negocio principal.
3. Para la comunidad:
○ Mantenimiento de empleos locales.
○ Continuidad de donaciones a la escuela (ahora más
sostenibles). ○ Modelo inspirador para otros pequeños
negocios.
Resultados adicionales:
1. Documentación completa que permita:
○ Mantenimiento futuro del sistema.
○ Capacitación de nuevo personal.
○ Posible replicación en negocios similares.
2. Base tecnológica para futuras mejoras:
○ Posibilidad de añadir comercio electrónico.
○ Integración con sistemas de pago digital.
○ Conexión con apps de entrega a domicilio.
3. Validación del enfoque:
○ Demostración de qué soluciones tecnológicas accesibles pueden transformar
pequeños negocios.
○ Caso de éxito para emprendedoras con recursos limitados.
Limitaciones a considerar:
● Dependencia inicial de María y su equipo para aprender el sistema.
● Necesidad de mantenimiento básico (ej: respaldos de BD).
● Requerimiento de equipo computacional mínimo para operar.
Bibliografía.
Al Kautsaf, F. M., Bin Mohd Nizam, M. N., & Harun, K. S. (2023).
, 287-292. Scopus.
[Link]
Azevedo, P. S., Romão, M., & Rebelo, E. (2012). Advantages, Limitations and Solutions in the
Use of ERP Systems (Enterprise Resource Planning) – A Case Study in the
Hospitality
Industry. , , 264-272.
[Link]
Chaichana, T., Reeve, G., Jaisan, C., & Chakrabandhu, Y. (2024). Modelling and assessing new SME
digital business status for visualising virtual economics
and sustainability economic indicators: Empirical evidence from poultry
business. , (9), e30624.
[Link]
Muhammad, S. S., Dey, B. L., Kamal, M. M., Samuel, L., & Alzeiby, E. A. (2025). Digital
transformation or digital divide?Smes’ use of AI during global crisis.
, , 124184.
[Link]
Panduwiyasa, H., Fikri, H. C., Saputra, M., & Puspitasari, W. (2022).
. Scopus.
[Link] Vida Informatico - AS (Director). (2020, agosto 4).
[Video recording].
[Link]
Realizarunainvestigaciónyresumensobreeltema"Buenasprácticasdeprogramación
Buenas PrácticasdeProgramación
¿Quéson?
Las buenasprácticas deprogramaciónsonunconjuntoderecomendaciones,técnicas y normas
quelos desarrolladoressiguenparaescribircódigolimpio,eficiente,comprensibley mantenible.
Nosonobligatorias,peroayudanamejorarla calidaddelsoftwareyafacilitarel trabajoenequipo.
Principalesbuenasprácticas
1.Códigolimpioylegible
Usarnombresdescriptivosparavariablesyfunciones.
Escribircomentarioscuandoelcódigonoseaevidente.
Usarunaindentaciónconsistente.
[Link]
Dividirel códigoenfunciones omódulospequeños querealicentareas específicas.
[Link] repetición(DRY:Don’ tRepeatYourself)
Reutilizarfunciones enlugardecopiarypegarcódigo.
[Link]
UtilizarherramientascomoGitpararastrearcambios ycolaborarconotros.
[Link]
Usartry-catchomecanismossimilares paraprevenirfallosinesperados.
[Link]
Escribirpruebas unitariasparaasegurarsedequeelcódigofuncionacomoseespera.
[Link]ón
Mantenerdocumentaciónactualizadaqueexpliquecómousarelcódigo.
[Link]ándares
Usarguíasdeestilodel lenguaje(porejemplo,PEP8para Python,GoogleStyleGuidepara Java)
Importancia
Aplicarbuenas prácticas:
Facilitaelmantenimientoylalecturadelcódigo.
Reduceerrores yfacilitaladepuración.
Mejoralacolaboraciónenequipos
Aumentalacalidaddel software.
¿Tegustaría unejemploprácticodecódigoconbuenasymalas prácticas?
luegorealiceunatablacomparativaconlasapreciaciones(similitudes ydiferencias)de
acuerdoalosautoresIndiquencomopuedenaplicarlasrecomendaciones encontradasenla
creacióndemódulos& paquetes ycuálsería(asucriterio)lamáseficienteenaplicarse
Aplicaciónderecomendaciones enla creacióndemódulosypaquetes:
Las recomendacionesparalacreacióndemódulos ypaquetes enPythonbuscanmejorarla organización,
legibilidadyreutilizacióndelcódigo. Algunas formas deaplicarlas son:
[Link]ónlógicadelcódigo:Dividirelproyectoenmódulos segúnfuncionalidades específicas
(porejemplo, [Link],[Link],[Link])yagruparlosenpaquetes (carpeta/
con_init_.py)permitemantenerel códigolimpioyfácildemantener.
[Link]:Utilizarnombresdescriptivosparamódulosypaquetes facilitala
comprensióndel propó[Link],unmódulollamado
procesador_datos.pyesmá[Link].
[Link] deimportación:Diseñarlos módulosdeformaquenodependancircularmente
[Link] compartidas enmódulosutilitarios.
4.Usodelarchivo_init_.py:Estearchivopermiteinicializarpaquetesycontrolarloquese
exponecuandoseimportaelpaquete,facilitandounainterfazclaraparaotrosdesarrolladores.
[Link]ónycomentarios:Añadirdocstrings alos módulos,clases yfunciones ayudaa
queelcódigoseafácilmenteentendibleyreutilizable
INVESTIGACION:CONCEPTOS DELPARADIGMADE
OBJETOS
Elparadigmadeobjetos,oprogramaciónorientadaaobjetos (POO),es
unametodologíadedesarrollodesoftwarequesebasa
enlaideadequelosprogramasestáncompuestos porobjetos.
Conceptosdelparadigmadeobjetos
Objetos:Sonentidades quetienenunestado,comportamientoe identidad.
Atributos:Sonlaspropiedadesdeunobjeto,comosucolor,altura oespesor.
Métodos:Sonlas accionesqueunobjetopuederealizar,como comer,cantar,enviar,etc.
Encapsulación:Eslatécnicaqueocultala complejidaddela
implementacióndeunobjetodetrásdeunainterfazsimple.
Herencia:Eslacaracterísticaquepermitealosobjetos heredar propiedadesycomportamientos
deotrosobjetos.
Polimorfismo:Esla característicaquepermitequeunobjetose comportedediferentesmaneras
endiferentes contextos.
Abstracción:Es unodelos principiosbásicosdelaPOO.
VentajasdelaPOO
Permitecrearaplicacionesmásrobustas,flexiblesyfáciles de mantener.
Facilitalamodularidadyreutilizacióndecódigo.
Promueveunaorganizaciónmáslógica ycomprensibledel software.
Permitea losprogramadorescrearsistemasdemaneramás
intuitiva.
LaIAgenerativa es experimental.
Realizarunainvestigaciónparaampliarlos
conceptossobrelosprincipios deProgramación
Orientada aObjetos:
-Abstracción
-Herencia
-Encapsulación
-Polimorfismo
Todo
VisióngeneralcreadaporIA
Más información
Elparadigmadeobjetos,oprogramaciónorientadaaobjetos (POO),es
unametodologíadedesarrollodesoftwarequesebasa
enlaideadequelosprogramasestáncompuestos porobjetos.
Conceptosdelparadigmadeobjetos
Objetos:Sonentidades quetienenunestado,comportamientoe identidad.
Atributos:Sonlaspropiedadesdeunobjeto,comosucolor,altura oespesor.
Métodos:Sonlas accionesqueunobjetopuederealizar,como comer,cantar,enviar,etc.
Encapsulación:Eslatécnicaqueocultala complejidaddela
implementacióndeunobjetodetrásdeunainterfazsimple.
Herencia:Eslacaracterísticaquepermitealosobjetos heredar
propiedadesycomportamientos deotrosobjetos. Polimorfismo:Esla
característicaquepermitequeunobjetose comportedediferentesmaneras
endiferentes contextos.
Abstracción:Es unodelos principiosbásicosdelaPOO.
VentajasdelaPOO
Permitecrearaplicacionesmásrobustas,flexiblesyfáciles de mantener.
Facilitalamodularidadyreutilizacióndecódigo.
Promueveunaorganizaciónmáslógica ycomprensibledel software.
Permitea losprogramadorescrearsistemasdemaneramás
intuitiva
Busqueejemplosparaaplicardichos principiosenPython.
Debeagregaralfinallasreferenciasbibliográficas.
SingleResponsibilityPrinciple(SRP)
ElprimerprincipiodeSOLIDllamadoPrincipiodeResponsabilidad
Únicaindicaqueuna clasedeberíaserresponsabledeunaúnica
[Link],laclasesolodeberíateneruna
únicarazó[Link]
defineunaclaseDuckcon5diferentesmétodos. classDuck:
def__init__(self,name): [Link]=name
deffly(self):
print(f"{[Link]}isflyingnotveryhigh") defswim(self):
print(f"{[Link]}swimsinthelakeandquacks") defdo_sound(self)->str:
return"Quack" defgreet(self,
duck2:Duck):
print(f"{[Link]}:{self.do_sound()},hello{[Link]}")
[Link]
quecambiarestadefinición,secambiaráestaclase. Elproblema
yaceenelmétodogreet(),queseencargadepoderhablarcon otros
[Link]
conversaciónentrepatos,seestaríacambiandotambiénlaclase Duck, es decir,
habríaunarazónadicionalparacambiarla clase. Las consecuencias
denorespetaresteprincipiopuedenser
varias,comodificultarladepuracióndeerrores,yaquevarios erroresapuntanal
mismositioylasfuncionalidadesestánmás acopladas.
Pararesolveresteproblemaenelcasodel ejemplo,sedefineuna nueva
claseCommunicatorqueseencarga detodala funcionalidad
decomunicació[Link]
entablarunaconversaciónentredospatos,dondeestosse
[Link],sehacambiadoel funcionamientode la
comunicaciónsinquelaclaseDucksehaya vistoafectada. classDuck:
def__init__(self,name): [Link]=name
deffly(self):
print(f"{[Link]}isflyingnotveryhigh") defswim(self):
print(f"{[Link]}swimsinthelakeandquacks") defdo_sound(self)->str:
return"Quack" classCommunicator:
def__init__(self,channel): [Link] =channel
defcommunicate(self, duck1:Duck,duck2:Duck):
sentence1=f"{[Link]}:{duck1.do_sound()},hello
{[Link]}" sentence2=f"{[Link]}:{duck2.do_sound()},hello
{[Link]}"
conversation=[sentence1,sentence2]
print(*conversation,
f"(via{[Link]})", sep='\n')
Open-ClosedPrinciple(OCP)
ElPrincipiodeAbierto/Cerradoindicaquelasclases deberían
estarabiertasparasuextensión, perocerradasparasu modificación.
Enotrostérminos,elcódigodeberíaestarescritode tal
maneraque,alahoradeañadirnuevasfuncionalidades,no sedeba
modificarelcódigoescritopreviamente,quepuedaestar
siendoutilizadoporotros usuarios.
Enelejemploanterior,nosepuedeextenderla funcionalidadde
Communicatorparaañadirdiferentestiposdeconversacionessin
modificarelmétodocommunicate().Paracumplirconelsegundo
principio,secreaunaclaseAbstractConversationquese encargarádedefinirdiferentes
tiposdeconversaciones ensus subclasesconimplementacionesdedo_conversation().Deesta
manera,elmétodocommunicate() deCommunicatorsolose
regiráallevaracabolacomunicaciónatravés deunacanaly
nuncaserequerirádesumodificación(esunmétodofinal).
fromtypingimportfinal classAbstractConversation:
defdo_conversation(self)->list:
pass classSimpleConversation(AbstractConversation):
def__init__(self,duck1:Duck, duck2:Duck):
self.duck1=duck1 self.duck2=duck2
Def do_conversation(self)->list:
sentence1=f"{[Link]}:{self.duck1.do_sound()},
hello{[Link]}"
sentence2=f"{[Link]}:{self.duck2.do_sound()},
hello{[Link]}" return[sentence1,sentence2]
classCommunicator:
Def __init__(self,channel): [Link]
=channel
@final defcommunicate(self,
conversation:AbstractConversation):
print(*conversation.do_conversation(), f"(via{[Link]})",
Sep='\n')
LiskovSubstitutionPrinciple(LSP)
ElPrincipiodeSubstitucióndeLiskovestablecequelasclases deberíansersustituibles
porinstanciasdesus [Link] ilustraresteprincipio, seconsidera
laposibilidaddequese puedanañadirnuevasavesenunfuturo. Para ello,unabuena
prácticaconsisteenañadirclaseabstractaBirdyquelasaves comoDuckimplementensus
mé[Link]ítambién sepuededefinir,apartirdeBird,una
subclasedecuervoCrow.
fromabcimportABC,abstractmethod
classBird(ABC): Def __init__(self,name):
[Link]=name @abstractmethod
deffly(self):
Pass @abstractmethod
Def swim(self):
Pass
@abstractmethod
Def do_sound(self)->str:
Pass classCrow(Bird):
Def fly(self):
print(f"{[Link]}isflyinghighandfast!") defswim(self):
RaiseNotImplementedError("Crows don'tswim!") defdo_sound(self)->str:
return"Caw" classDuck(Bird):
deffly(self):
print(f"{[Link]}isflyingnotveryhigh") defswim(self):
print(f"{[Link]}swims inthelakeandquacks")
Def do_sound(self)->str:
return"Quack"
Estepequeñocambiohageneradounproblema:los métodos de
[Link]
clasenopodríaaceptar,porejemplo,instancias delaclaseCrow.
Portanto,hayquecambiarladependencia deDuck [Link]
haberhechoestecambio,sepuedesustituirBirdconcualquier instancia desus subclases
sinqueestoorigineningúnproblema, esdecir,seestá respetandoel tercerprincipio.
classSimpleConversation(AbstractConversation): def__init__(self,bird1:Bird,bird2:Bird):
self.bird1=bird1 self.bird2=bird2
defdo_conversation(self)->list:
sentence1=f"{[Link]}:{self.bird1.do_sound()}, hello
{[Link]}" sentence2=f"{[Link]}:{self.bird2.do_sound()},
hello
{[Link]}" return[sentence1,sentence2]
InterfaceSegregationPrinciple(ISP)
ElPrincipiodeSegregacióndeInterfazestablecequelos clientes
nodeberíanserforzados adependerdemétodosquenoutilizan
y,portanto,sugierelacreacióndeinterfacesoclasesespecíficas para
dichosclientes. Enelapartadoanterior,sehaañadidouna nueva
claseCrowquedescribeuncuervo. Peroenesadefinición
hayunproblema:el cuervonosabenadarylaclaseabstracta
Birdnosobligaadefinirswim().
[Link]
hacerlo, sedefinendosnuevasclasesabstractasparaaquellos pájaros
quesabennadar(SwimmingBird)yaquellosquesaben
volar(FlyingBird),yqueextenderá[Link]
estamanera,CrowimplementalafuncionalidaddeFlyingBirdy
Duckimplementala funcionalidaddeSwimmingBirdyFlyingBird.
Ahora,sisetuvieraqueimplementarelpingüino,quesabenadar peronovuela,tansolosedebería
extenderSwimmingBird.
Class Bird(ABC): Def
__init__(self,name):
[Link]=name
@abstractmethod
Def do_sound(self)->str: Pass
classFlyingBird(Bird):
@abstractmethod
Def fly(self):
Pass
Class SwimmingBird(Bird):
@abstractmethod
defswim(self):
pass classCrow(FlyingBird):
deffly(self):
print(f"{[Link]}isflyinghighandfast!") defdo_sound(self)->str:
return"Caw" classDuck(SwimmingBird,FlyingBird):
deffly(self):
print(f"{[Link]}isflyingnotveryhigh") defswim(self):
print(f"{[Link]}swimsinthelakeandquacks") defdo_sound(self)->str:
return"Quack"
DependencyInversionPrinciple(DIP)
ElúltimoprincipiollamadoPrincipiodeInversiónde
Dependenciassepuedesepararendos [Link],
indicaquelasabstracciones nodeberíandependerdelos
detalles,pueslos detallesdeberíandependerdelas
[Link], indicaquelasclasesdealtonivel no
deberíandependerdeclases debajonivel,dadoqueambas
deberí[Link], hayque
dependerdelasabstracciones.
Parailustraresteprincipio,sedecidequeel canal queahorase
defineenlaclasedecomunicadorvaa tenermás funcionalidades
[Link](SRP),seextraeesta nueva
responsabilidaddela claseCommunicatoryseleasignaa
unanuevaclaseabstractaAbstractChannel. Adicionalmente,se
hacequelaclasedecomunicadorahoraseaabstracta
(AbstractCommunicator)detalformaquedefineuncanal
[Link]ónyelmétodofinal
get_channel_message()enAbstractChannelnosayudana cumplirel
segundoprincipio(OCP)yaquecommunicate()no
necesitarásermodificadopara usardiferentescanales.
classAbstractChannel(ABC): defget_channel_message(self)->str:
pass
Class AbstractCommunicator(ABC):
defget_channel(self)->AbstractChannel:
pass @final defcommunicate(self,
conversation:AbstractConversation):
print(*conversation.do_conversation(), self.get_channel().get_channel_message(),
sep='\n')
Apartirdeaquí,sepuededefiniruncanalyuncomunicadorpara
quenuestrasinteligentesavespuedanenviarsemensajesSMS:
classSMSChannel(AbstractChannel): defget_channel_message(self)->str:
return"(viaSMS)" classSMSCommunicator(AbstractCommunicator):
def__init__(self):
self._channel =SMSChannel() defget_channel(self)->AbstractChannel:
returnself._channel
Desafortunadamente, estaimplementaciónnorespetael
PrincipiodeInversió[Link]
dentrodeSMSCommunicatorseestállamandoaSMSChannel,es
decir,queseestádependiendodedetallesynodeclases abstractas.
Pararesolveresteproblema,sedefineun comunicadorquedependa
directamentedelaabstracción.
classSimpleCommunicator(AbstractCommunicator):
def__init__(self,channel:AbstractChannel):
self._channel =channel defget_channel(self)->str:
returnself._channel
Copyright©2025-TemaparaWordPress deCreativeThemes
NOTA:UseGeminipara resumirlabúsqueday recuerdequelepuedepreguntara
laIAsobrelas referenciasbibliográficas.
Las referencias bibliográficassonunconjuntode datos
quepermitenidentificarlasfuentes de
informació[Link] presentaral
finaldeltextoenformadelista,yseles llama bibliografía.
Elementosdeunareferenciabibliográfica
Autor
Título
Piedeimprenta
Fechadepublicación
Editorial
Revista
Direcciónweb
Formatos dereferenciasbibliográficas APA,CHICAGO,MLA,HARVARD,UNE-ISO690:2024,
IEEE,VANCOUVER.
Cómoseordenan
Generalmenteseordenanporordenalfabéticodel primerelementodelareferencia.
Cuandolaentradadeunareferenciabibliográfica comienzaporunnúmero,
sealfabetizacomosiel númeroestuvieraescrito.
Dóndesecolocan
Sepuedencolocarcomonotaa piedepágina,al finaldelcapítulooal
finaldetodoeltexto.
Función
Permitenquelos lectorespuedanidentificary localizarlos
recursosquesehancitadoenunescrito
TRIGGERS(Disparadores)enMySQLenespañol,organizada segúnlos tres puntos
solicitados:
1.-¿QUÉSON?
LosTriggersoDisparadores enMySQLsonbloquesdecódigoSQLqueseejecutan
automáticamentecuandoocurreuneventoespecíficoenunatabla, comounainserción
(INSERT), actualización(UPDATE)oeliminación(DELETE).
Seasociandirectamentea unatablayseactivanantes odespuésdequeserealicela acción.
2.-¿PARAQUÉSIRVEN?
Lostriggers seusanpara:
• Validardatosantes dequeseinsertenoactualicen.
• Registrarcambiosenunatabladeauditoría.
• Actualizarautomáticamenteotrastablas relacionadas.
• Evitaraccionesindebidas (comoeliminarunregistrosinosecumple cierta condición).
• Mantenerlaintegridaddelos datossinnecesidaddeprogramación externa.
3.-EJEMPLODEAPLICACIÓN
Supongamosquetenemosunatablaempleadosyotralog_cambiosdondequeremos
guardarautomáticamentelos registros modificados.
-- Creartabla deauditoría
CREATETABLElog_cambios ( idINT
AUTO_INCREMENTPRIMARYKEY,
empleado_idINT,
fecha_cambioDATETIME,
antiguo_salarioDECIMAL(10,2),
nuevo_salarioDECIMAL(10,2)
);
-- Crearel trigger
DELIMITER//
CREATETRIGGERantes_actualizar_salario
BEFOREUPDATEONempleados
FOREACHROW
BEGIN
[Link]!=[Link]
INSERTINTOlog_cambios(empleado_id,fecha_cambio, antiguo_salario,nuevo_salario)
VALUES([Link],NOW(),[Link],[Link]);
ENDIF;
END;
//
DELIMITER;
🔹 Estetriggerguarda unregistroenlog_cambios cadavezqueseactualizaelsalario
deunempleado. AquítieneslainformaciónsobrelostriggersenMySQL:
TRIGGERS(DISPARADORES)ENMYSQL
Lostriggers (odisparadores)enMySQLsonobjetos delabasededatosqueseasocian
aunatablayseactivanautomáticamentecuandoocurreuneventoespecíficosobreesa
[Link]ón(INSERT),actualización
(UPDATE)oeliminación(DELETE)[Link],untriggeres unbloque
decódigoSQLqueseejecutadeforma predefinidaenrespuestaaunevento. Lostriggers
tienendiversas utilidades enlagestiónymantenimientodebases dedatos, entrelascuales
destacan:
*Auditoría:Permitenregistrarcambios enlos datosdeunatabla, comoquiénmodificó
unregistro,cuándolohizoycuáles eranlosvaloresantesydespuésdel cambio.
*Mantenimientodelaintegridaddelos datos:Puedenutilizarsepara aplicarreglasde
negociocomplejasquenopuedensermanejadas únicamenteconrestricciones
(constraints)declaveprimaria,claveforánea,[Link], asegurarqueciertos
valoressiempreesténdentrodeunrangoespecíficooqueserealicencálculos automáticos
alinsertaroactualizardatos.
*Automatizacióndetareas:Permitenautomatizarlaejecucióndeotras sentencias SQL
enrespuesta [Link], actualizarelstockdeunproductocuandose
realizaunaventa,oinsertarunregistroenunatabladehistorial.
*Replicacióndedatos:Aunqueexistensolucionesmásrobustas parareplicación,en casos
específicos,lostriggerspodríanusarseparamantenercopias dedatosen diferentestablasobases
dedatos.
*Prevenirerrores:Puedenusarseparavalidardatos antesdequeseaninsertadoso actualizados,
lanzandoerroressinocumplenconciertas condiciones.
3.-EjemplodeAplicación
Imaginemosquetenemosunabasededatos paraunatienda yqueremos mantenerun
[Link] unpedido(loqueimplicala
insercióndeunalíneadepedido),queremosqueelstockdel productocorrespondiente
seactualiceautomáticamente.
Estructuradelas tablas: CREATETABLEProductos(
id_productoINTPRIMARYKEYAUTO_INCREMENT,
nombre_productoVARCHAR(100), stockINT
);
CREATETABLEPedidos( id_pedidoINTPRIMARYKEYAUTO_INCREMENT,
fecha_pedidoDATETIME
);
CREATETABLELineas_Pedido( id_linea
INTPRIMARYKEYAUTO_INCREMENT,
id_pedidoINT, id_productoINT, cantidadINT,
FOREIGNKEY(id_pedido)REFERENCESPedidos(id_pedido),
FOREIGNKEY(id_producto)REFERENCESProductos(id_producto)
);
CreacióndelTrigger:
QueremosquecuandoseinserteunanuevalíneaenLineas_Pedido,el stock del
Productocorrespondientesereduzcaporlacantidaddelpedido.
DELIMITER$$
CREATETRIGGERtg_actualizar_stock_despues_de_insertar_linea
AFTERINSERTONLineas_Pedido
FOREACHROW
BEGIN
UPDATEProductos
SETstock=[Link]
WHEREid_producto=NEW.id_producto;
END$$
DELIMITER;
ExplicacióndelTrigger:
*DELIMITER$$yDELIMITER;:Seutilizanpara cambiartemporalmenteel
delimitadordesentenciasSQL,ya queelcuerpodeltriggercontienepuntoycoma.
*CREATETRIGGERtg_actualizar_stock_despues_de_insertar_linea:Defineun
triggerconunnombredescriptivo.
*AFTERINSERTONLineas_Pedido:Indicaqueestetriggerseactivará después de
cadaoperacióndeINSERTenlatablaLineas_Pedido.
*FOREACHROW:Significaqueelcuerpodel triggerseejecutaráuna vezporcada filaafectadaporla
operaciónINSERT.
*BEGIN...END:DefineelbloquedecódigoSQLqueseejecutará.
*UPDATEProductosSETstock=stock -[Link] WHEREid_producto=
NEW.id_producto;: Estaes lalógicaprincipaldeltrigger.
*[Link]:Hacereferenciaalvalordelacolumnacantidaddela filaqueacaba
deserinsertada.
*NEW.id_producto:Hacereferenciaalvalordelacolumnaid_productodelafilaque
acabadeserinsertada.
*LasentenciaUPDATErestalacantidaddelproductoinsertadoalstockactual del
productocorrespondiente.
Ejemplodeuso:
*Insertarunproducto:
INSERTINTOProductos (nombre_producto,stock)VALUES('Camiseta', 100);
*Crearunpedido:
INSERTINTOPedidos(fecha_pedido)VALUES (NOW()); Supongamosqueid_pedidogeneradoes
1.
*Insertaruna línea depedido(estodisparará el trigger):
INSERTINTOLineas_Pedido(id_pedido,id_producto,cantidad)VALUES(1,1,2);
Despuésdeestainserción,eltriggertg_actualizar_stock_despues_de_insertar_linea se
ejecutaráautomáticamente,yelstock dela'Camiseta'enlatablaProductos sereducirá de100a
98.
Esteessolounejemplobásico,peroilustracómolostriggers puedenautomatizartareas
yayudaramantenerlaconsistencia delosdatos enunabasededatosMySQL.
código de herencia
# Programa para evidenciar la herencia en POO
class Persona: # Clase padre
def __init__(self):
[Link] = input("Ingrese su nombre: ")
[Link] = self.ingresar_edad()
def ingresar_edad(self):
while True:
try:
edad = int(input("Ingrese su edad: "))
if edad <= 0:
print("La edad debe ser un número entero positivo.")
else:
return edad
except ValueError:
print("Por favor, ingrese una edad válida (número entero positivo).")
def mostrar(self):
print("Nombre: ", [Link])
print("Edad: ", [Link])
class Obrero(Persona): # Clase hijo
def __init__(self):
super().__init__() # Referenciar el constructor de la clase padre
[Link] = self.ingresar_sueldo()
def ingresar_sueldo(self):
while True:
try:
sueldo = float(input("Ingrese el sueldo: "))
if sueldo < 0:
print("El sueldo no puede ser negativo.")
else:
return sueldo
except ValueError:
print("Por favor, ingrese un valor numérico válido para el sueldo.")
def visualizar(self):
super().mostrar()
print("Sueldo: ", [Link])
def pago_IR(self):
if [Link] > 1500:
print("Debe pagar IR")
else:
print("No debe pagar IR")
# Clase jubilado
class Jubilado(Persona): # Hereda de Persona
def __init__(self):
super().__init__()
[Link] = self.ingresar_pension()
def ingresar_pension(self):
while True:
try:
pension = float(input("Ingrese el monto de su pensión: "))
if pension < 0:
print("La pensión no puede ser negativa.")
else:
return pension
except ValueError:
print("Por favor, ingrese un valor válido para la pensión.")
def visualizar(self):
super().mostrar()
print("Pensión: ", [Link])
def pago_IR(self):
if [Link] > 1000:
print("Debe pagar IR")
else:
print("No debe pagar IR")
# Ejecución de pruebas
print("\n--- DATOS DEL OBRERO ---")
trabajo = Obrero()
[Link]()
trabajo.pago_IR()
print("\n--- DATOS DEL JUBILADO ---")
persona2 = Jubilado()
[Link]()
persona2.pago_IR()
código del programa "Calculadora simple"
import math
class Calculadora:
def sumar(self, a, b):
return a + b
def restar(self, a, b):
return a - b
def multiplicar(self, a, b):
return a * b
def dividir(self, a, b):
if b == 0:
return "Error: No se puede dividir entre cero."
return a / b
def raiz_cuadrada(self, a):
if a < 0:
return "Error: No se puede sacar la raíz cuadrada de un número negativo."
return [Link](a)
def mostrar_menu():
print("\nCalculadora Simple")
print("1. Sumar")
print("2. Restar")
print("3. Multiplicar")
print("4. Dividir")
print("5. Raíz Cuadrada")
print("6. Salir")
def main():
calc = Calculadora()
while True:
mostrar_menu()
opcion = input("Elige una opción (1-6): ")
if opcion == '6':
print("¡Hasta luego!")
break
try:
if opcion in ['1', '2', '3', '4']:
num1 = float(input("Ingresa el primer número: "))
num2 = float(input("Ingresa el segundo número: "))
if opcion == '1':
print("Resultado:", [Link](num1, num2))
elif opcion == '2':
print("Resultado:", [Link](num1, num2))
elif opcion == '3':
print("Resultado:", [Link](num1, num2))
elif opcion == '4':
print("Resultado:", [Link](num1, num2))
elif opcion == '5':
num = float(input("Ingresa un número: "))
print("Resultado:", calc.raiz_cuadrada(num))
else:
print("Opción no válida. Intenta de nuevo.")
except ValueError:
print("Error: Ingresa un número válido.")
if __name__ == "__main__":
main()
código del programa "evitar ingreso de números decimales"
#almacenar clase persona y sus datos
class Persona:
def __init__(self):
while True:
edad_str = input("Ingrese una edad: ")
if '.' in edad_str:
print("Por favor, ingrese un número entero, no decimal.")
else:
try:
[Link] = abs(int(edad_str)) #valor absoluto
break
except ValueError:
print("Por favor, ingrese un número válido.")
def usuario(self):
pass